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
+69 -52
View File
@@ -28,18 +28,21 @@ import (
// BaseConfig provides common configuration fields and functionality
// that can be embedded in service-specific configs.
type BaseConfig struct {
rbac.AuthConfig
logger.LogConfig
observability.ObsConfig
database.DBConfig
aws.AWSConfig
queue.QueueConfig
// Always place non struct fields at the top of the struct
// this is a requirement for the PrintConfig function.
// miscellaneous fields uncategorized
// PWD will replace the BASE_PATH env var
Pwd string `env:"PWD,required,notEmpty"`
// BASE_PATH will override the PWD env var if present
BasePath string `env:"BASE_PATH"`
rbac.AuthConfig
logger.LogConfig
observability.ObsConfig
database.DBConfig
aws.AWSConfig
queue.QueueConfig
}
// Interfaces
@@ -110,7 +113,7 @@ func getBaseConfig(cfg ConfigProvider) *BaseConfig {
}
var (
initOnce sync.Once
initOnce = sync.Once{}
initErr error
)
@@ -185,25 +188,35 @@ func (b *BaseConfig) SetAWSConfig(cfg *aws.AWSConfig) {
}
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) {
// Handle pointer dereference
// Skip non-structs and nil pointers
if val.Kind() == reflect.Ptr {
if val.IsNil() {
return
}
val = val.Elem()
}
// Prevent infinite recursion using the memory address
// Recommended way to get the uintptr
addr := uintptr(val.Addr().UnsafePointer())
if visited[addr] {
if val.Kind() != reflect.Struct {
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()
// Process all fields including embedded ones
for i := 0; i < val.NumField(); i++ {
field := val.Field(i)
fieldType := typ.Field(i)
@@ -214,50 +227,54 @@ func (b *BaseConfig) printConfigRecursive(val reflect.Value, prefix string, pref
}
fieldName := fieldType.Name
fullPath := prefix + fieldName
// Check for env tag
envTag := fieldType.Tag.Get("env")
if envTag == "" {
// 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)
}
// Handle anonymous (embedded) fields specially
if fieldType.Anonymous {
// For embedded fields, recurse without adding to the path
// This is key - we want to process the embedded struct's fields directly
b.printConfigRecursive(field, prefix, prefixSecret, visited)
continue
}
// Handle different kinds of fields
switch field.Kind() {
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())
}
fullPath := prefix + fieldName
envTag := fieldType.Tag.Get("env")
b.Logger.Info("Struct Config value",
"key", fullPath,
"value", valueStr)
b.printConfigRecursive(field, fullPath+".", prefixSecret, visited)
default:
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] + "..."
// Process fields with env tags
if envTag != "" {
if field.Kind() == reflect.Struct {
// For structs with env tags, log the struct and recurse
var valueStr string
if field.CanInterface() {
valueStr = fmt.Sprintf("%+v", field.Interface())
}
}
b.Logger.Info("Config value",
"key", fullPath,
"value", valueStr)
b.Logger.Info("Struct Config value",
"key", fullPath,
"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
type AuthConfig struct {
AuthProvider rbac.KeyProvider
AuthType string `env:"RBAC_PROVIDER" envDefault:"cognito"`
AuthType string `env:"RBAC_PROVIDER" envDefault:"cognito"`
// Cognito Config
CognitoRegion string `env:"COGNITO_REGION" envDefault:"us-east-1"`
CognitoUserPoolID string `env:"COGNITO_USER_POOL_ID"`
// Local Key Config
PrivateKeyPath string `env:"RBAC_PRIVATE_KEY_PATH"`
PublicKeyPath string `env:"RBAC_PUBLIC_KEY_PATH"`
}
//func IdentifyAuthProviderAndCreate(config rbac.AuthConfig) (KeyProvider, error) {
// var keyProvider 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
// Actual provider - can be either local or cognito
AuthProvider rbac.KeyProvider
}
// ConfigProvider interface defines the methods required for RBAC configuration
@@ -68,8 +33,12 @@ func (r *AuthConfig) GetKeyProvider() rbac.KeyProvider {
return r.AuthProvider
}
// Initialize initializes the appropriate KeyProvider based on configuration
func (r *AuthConfig) Initialize() error {
func InitializeAuthProvider(config *AuthConfig) error {
return config.InitializeAuthProvider()
}
// InitializeAuthProvider initializes the appropriate KeyProvider based on configuration
func (r *AuthConfig) InitializeAuthProvider() error {
switch r.AuthType {
case "local":
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,
PublicKeyPath: publicKeyPath,
}
err := config.Initialize()
err := config.InitializeAuthProvider()
if err != nil {
t.Fatalf("Failed to initialize auth config: %v", err)
}