fixed printconfig bug

This commit is contained in:
jay brown
2025-03-18 15:52:58 -07:00
parent 31082c0ff5
commit 3fef82354a
5 changed files with 116 additions and 127 deletions
+20 -34
View File
@@ -2,46 +2,32 @@ package main
import ( import (
"fmt" "fmt"
"os" "log"
"sort"
"queryorchestration/internal/rbac" // Replace with your actual module name "queryorchestration/internal/rbac" // Replace with your actual module name
"queryorchestration/internal/serviceconfig"
) )
//type DummyServiceConfig struct { // for testing run like `LOG_LEVEL=INFO go run main.go`
// service.BaseConfig
//}
func PrintEnvironmentVariables() {
// Get all environment variables
envVars := os.Environ()
// Sort them for consistent output
sort.Strings(envVars)
// Print each variable in "key = value" format
for _, env := range envVars {
// Find the first equals sign to split the string
for i := 0; i < len(env); i++ {
if env[i] == '=' {
key := env[:i]
value := env[i+1:]
fmt.Printf("%s = %s\n", key, value)
break
}
}
}
}
func main() { func main() {
PrintEnvironmentVariables()
//cfg := &DummyServiceConfig{} cfg := &serviceconfig.BaseConfig{}
//errGettingConfig := serviceconfig.InitializeConfig(cfg) errGettingConfig := serviceconfig.InitializeConfig(cfg)
//if errGettingConfig != nil { if errGettingConfig != nil {
// log.Fatal(errGettingConfig) log.Fatal(errGettingConfig)
//} }
errorInitializingAuthProvider := cfg.InitializeAuthProvider()
if errorInitializingAuthProvider != nil {
log.Fatal(errorInitializingAuthProvider)
}
cfg.PrintConfig("secret")
// use the config here for the key provider parameters // use the config here for the key provider parameters
// Example with local key provider for testing // Example with local key provider for testing
if cfg.AuthProvider == nil {
log.Fatal("AuthProvider is nil")
}
localProvider := rbac.NewLocalKeyProvider("private_key.pem", "public_key.pem") localProvider := rbac.NewLocalKeyProvider("private_key.pem", "public_key.pem")
// Generate a mock JWT with multiple Cognito groups // Generate a mock JWT with multiple Cognito groups
+17
View File
@@ -19,6 +19,8 @@ import (
"log/slog" "log/slog"
"os" "os"
"queryorchestration/internal/serviceconfig"
queryservice "queryorchestration/api/queryService" queryservice "queryorchestration/api/queryService"
"queryorchestration/internal/client" "queryorchestration/internal/client"
"queryorchestration/internal/collector" "queryorchestration/internal/collector"
@@ -32,6 +34,7 @@ import (
service "queryorchestration/internal/server/service" service "queryorchestration/internal/server/service"
"queryorchestration/internal/serviceconfig/queue/clientsync" "queryorchestration/internal/serviceconfig/queue/clientsync"
"queryorchestration/internal/serviceconfig/queue/queryversionsync" "queryorchestration/internal/serviceconfig/queue/queryversionsync"
"queryorchestration/internal/serviceconfig/rbac"
"github.com/getkin/kin-openapi/openapi3" "github.com/getkin/kin-openapi/openapi3"
_ "github.com/lib/pq" _ "github.com/lib/pq"
@@ -92,6 +95,20 @@ func main() {
return swagger, nil return swagger, nil
} }
// this must be done before the rbac.InitializeAuthProvider
errInitializingConfig := serviceconfig.InitializeConfig(cfg)
if errInitializingConfig != nil {
slog.Error(errInitializingConfig.Error())
os.Exit(1)
}
// initialize the rbac config here since only the API service needs it
errorGettingAuthProvider := rbac.InitializeAuthProvider(&cfg.AuthConfig)
if errorGettingAuthProvider != nil {
slog.Error(errorGettingAuthProvider.Error())
os.Exit(1)
}
server, err := service.New(ctx, cfg) server, err := service.New(ctx, cfg)
if err != nil { if err != nil {
slog.Error(err.Error()) slog.Error(err.Error())
+69 -52
View File
@@ -28,18 +28,21 @@ import (
// BaseConfig provides common configuration fields and functionality // BaseConfig provides common configuration fields and functionality
// that can be embedded in service-specific configs. // that can be embedded in service-specific configs.
type BaseConfig struct { type BaseConfig struct {
rbac.AuthConfig // Always place non struct fields at the top of the struct
logger.LogConfig // this is a requirement for the PrintConfig function.
observability.ObsConfig
database.DBConfig
aws.AWSConfig
queue.QueueConfig
// miscellaneous fields uncategorized // miscellaneous fields uncategorized
// PWD will replace the BASE_PATH env var // PWD will replace the BASE_PATH env var
Pwd string `env:"PWD,required,notEmpty"` Pwd string `env:"PWD,required,notEmpty"`
// BASE_PATH will override the PWD env var if present // BASE_PATH will override the PWD env var if present
BasePath string `env:"BASE_PATH"` BasePath string `env:"BASE_PATH"`
rbac.AuthConfig
logger.LogConfig
observability.ObsConfig
database.DBConfig
aws.AWSConfig
queue.QueueConfig
} }
// Interfaces // Interfaces
@@ -110,7 +113,7 @@ func getBaseConfig(cfg ConfigProvider) *BaseConfig {
} }
var ( var (
initOnce sync.Once initOnce = sync.Once{}
initErr error initErr error
) )
@@ -185,25 +188,35 @@ func (b *BaseConfig) SetAWSConfig(cfg *aws.AWSConfig) {
} }
func (b *BaseConfig) PrintConfig(prefixSecret string) { func (b *BaseConfig) PrintConfig(prefixSecret string) {
b.printConfigRecursive(reflect.ValueOf(b), "", prefixSecret, make(map[uintptr]bool)) visited := make(map[uintptr]bool)
b.printConfigRecursive(reflect.ValueOf(b).Elem(), "", prefixSecret, visited)
} }
func (b *BaseConfig) printConfigRecursive(val reflect.Value, prefix string, prefixSecret string, visited map[uintptr]bool) { func (b *BaseConfig) printConfigRecursive(val reflect.Value, prefix string, prefixSecret string, visited map[uintptr]bool) {
// Handle pointer dereference // Skip non-structs and nil pointers
if val.Kind() == reflect.Ptr { if val.Kind() == reflect.Ptr {
if val.IsNil() {
return
}
val = val.Elem() val = val.Elem()
} }
// Prevent infinite recursion using the memory address if val.Kind() != reflect.Struct {
// Recommended way to get the uintptr
addr := uintptr(val.Addr().UnsafePointer())
if visited[addr] {
return return
} }
visited[addr] = true
// Check for cycles, but only for addressable values
if val.CanAddr() {
addr := uintptr(val.Addr().UnsafePointer())
if visited[addr] {
return
}
visited[addr] = true
}
typ := val.Type() typ := val.Type()
// Process all fields including embedded ones
for i := 0; i < val.NumField(); i++ { for i := 0; i < val.NumField(); i++ {
field := val.Field(i) field := val.Field(i)
fieldType := typ.Field(i) fieldType := typ.Field(i)
@@ -214,50 +227,54 @@ func (b *BaseConfig) printConfigRecursive(val reflect.Value, prefix string, pref
} }
fieldName := fieldType.Name fieldName := fieldType.Name
fullPath := prefix + fieldName // Handle anonymous (embedded) fields specially
if fieldType.Anonymous {
// Check for env tag // For embedded fields, recurse without adding to the path
envTag := fieldType.Tag.Get("env") // This is key - we want to process the embedded struct's fields directly
if envTag == "" { b.printConfigRecursive(field, prefix, prefixSecret, visited)
// If this is a struct, we still need to recurse into it
// as it might contain fields with env tags
if field.Kind() == reflect.Struct {
b.printConfigRecursive(field, fullPath+".", prefixSecret, visited)
}
continue continue
} }
// Handle different kinds of fields fullPath := prefix + fieldName
switch field.Kind() { envTag := fieldType.Tag.Get("env")
case reflect.Struct:
// If it's a struct AND has an env tag, print it and recurse
var valueStr string
if field.CanInterface() {
valueStr = fmt.Sprintf("%+v", field.Interface())
}
b.Logger.Info("Struct Config value", // Process fields with env tags
"key", fullPath, if envTag != "" {
"value", valueStr) if field.Kind() == reflect.Struct {
b.printConfigRecursive(field, fullPath+".", prefixSecret, visited) // For structs with env tags, log the struct and recurse
default: var valueStr string
var valueStr string if field.CanInterface() {
if field.Kind() == reflect.String { valueStr = fmt.Sprintf("%+v", field.Interface())
valueStr = field.String()
} else {
valueStr = fmt.Sprintf("%v", field.Interface())
}
// Mask sensitive values
if strings.Contains(strings.ToLower(fieldName), strings.ToLower(prefixSecret)) {
if len(valueStr) > 3 {
valueStr = valueStr[:3] + "..."
} }
}
b.Logger.Info("Config value", b.Logger.Info("Struct Config value",
"key", fullPath, "key", fullPath,
"value", valueStr) "value", valueStr)
} else {
// For non-struct fields with env tags
var valueStr string
if field.Kind() == reflect.String {
valueStr = field.String()
} else {
valueStr = fmt.Sprintf("%v", field.Interface())
}
// Mask sensitive values
if strings.Contains(strings.ToLower(fieldName), strings.ToLower(prefixSecret)) {
if len(valueStr) > 3 {
valueStr = valueStr[:3] + "..."
}
}
b.Logger.Info("Config value",
"key", fullPath,
"value", valueStr)
}
}
// Recurse into structs regardless of env tag
if field.Kind() == reflect.Struct {
b.printConfigRecursive(field, fullPath+".", prefixSecret, visited)
} }
} }
} }
+9 -40
View File
@@ -9,51 +9,16 @@ import (
// AuthConfig holds the RBAC configuration and KeyProvider // AuthConfig holds the RBAC configuration and KeyProvider
type AuthConfig struct { type AuthConfig struct {
AuthProvider rbac.KeyProvider AuthType string `env:"RBAC_PROVIDER" envDefault:"cognito"`
AuthType string `env:"RBAC_PROVIDER" envDefault:"cognito"`
// Cognito Config // Cognito Config
CognitoRegion string `env:"COGNITO_REGION" envDefault:"us-east-1"` CognitoRegion string `env:"COGNITO_REGION" envDefault:"us-east-1"`
CognitoUserPoolID string `env:"COGNITO_USER_POOL_ID"` CognitoUserPoolID string `env:"COGNITO_USER_POOL_ID"`
// Local Key Config // Local Key Config
PrivateKeyPath string `env:"RBAC_PRIVATE_KEY_PATH"` PrivateKeyPath string `env:"RBAC_PRIVATE_KEY_PATH"`
PublicKeyPath string `env:"RBAC_PUBLIC_KEY_PATH"` PublicKeyPath string `env:"RBAC_PUBLIC_KEY_PATH"`
}
//func IdentifyAuthProviderAndCreate(config rbac.AuthConfig) (KeyProvider, error) { // Actual provider - can be either local or cognito
// var keyProvider KeyProvider AuthProvider rbac.KeyProvider
// if config.AuthType == "local" {
// keyProvider = NewLocalKeyProvider(config.PrivateKeyPath, config.PublicKeyPath)
// } else if config.AuthType == "cognito" {
// keyProvider = NewCognitoKeyProvider(config.CognitoRegion, config.CognitoUserPoolID)
// }
// if keyProvider == nil {
// return nil, fmt.Errorf("invalid auth provider: %s", config.AuthProvider)
// }
// return keyProvider, nil
//}
// NewAuthConfig creates a new AuthConfig with the specified provider type
func NewAuthConfig(providerType string) (*AuthConfig, error) {
config := &AuthConfig{
AuthType: providerType,
}
if err := config.Initialize(); err != nil {
return nil, fmt.Errorf("failed to initialize auth config: %w", err)
}
return config, nil
}
// NewLocalAuthConfig creates a new AuthConfig configured for local key provider
func NewLocalAuthConfig(privateKeyPath, publicKeyPath string) (*AuthConfig, error) {
config := &AuthConfig{
AuthType: "local",
PrivateKeyPath: privateKeyPath,
PublicKeyPath: publicKeyPath,
}
if err := config.Initialize(); err != nil {
return nil, fmt.Errorf("failed to initialize local auth config: %w", err)
}
return config, nil
} }
// ConfigProvider interface defines the methods required for RBAC configuration // ConfigProvider interface defines the methods required for RBAC configuration
@@ -68,8 +33,12 @@ func (r *AuthConfig) GetKeyProvider() rbac.KeyProvider {
return r.AuthProvider return r.AuthProvider
} }
// Initialize initializes the appropriate KeyProvider based on configuration func InitializeAuthProvider(config *AuthConfig) error {
func (r *AuthConfig) Initialize() error { return config.InitializeAuthProvider()
}
// InitializeAuthProvider initializes the appropriate KeyProvider based on configuration
func (r *AuthConfig) InitializeAuthProvider() error {
switch r.AuthType { switch r.AuthType {
case "local": case "local":
if r.PrivateKeyPath == "" || r.PublicKeyPath == "" { if r.PrivateKeyPath == "" || r.PublicKeyPath == "" {
+1 -1
View File
@@ -13,7 +13,7 @@ func TestKeyProvider(t *testing.T, privateKeyPath, publicKeyPath string) rbac.Ke
PrivateKeyPath: privateKeyPath, PrivateKeyPath: privateKeyPath,
PublicKeyPath: publicKeyPath, PublicKeyPath: publicKeyPath,
} }
err := config.Initialize() err := config.InitializeAuthProvider()
if err != nil { if err != nil {
t.Fatalf("Failed to initialize auth config: %v", err) t.Fatalf("Failed to initialize auth config: %v", err)
} }