fixed printconfig bug
This commit is contained in:
@@ -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
|
||||||
|
|||||||
@@ -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())
|
||||||
|
|||||||
@@ -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
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check for cycles, but only for addressable values
|
||||||
|
if val.CanAddr() {
|
||||||
addr := uintptr(val.Addr().UnsafePointer())
|
addr := uintptr(val.Addr().UnsafePointer())
|
||||||
if visited[addr] {
|
if visited[addr] {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
visited[addr] = true
|
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,23 +227,21 @@ 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
|
// 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
|
var valueStr string
|
||||||
if field.CanInterface() {
|
if field.CanInterface() {
|
||||||
valueStr = fmt.Sprintf("%+v", field.Interface())
|
valueStr = fmt.Sprintf("%+v", field.Interface())
|
||||||
@@ -239,8 +250,8 @@ func (b *BaseConfig) printConfigRecursive(val reflect.Value, prefix string, pref
|
|||||||
b.Logger.Info("Struct Config value",
|
b.Logger.Info("Struct Config value",
|
||||||
"key", fullPath,
|
"key", fullPath,
|
||||||
"value", valueStr)
|
"value", valueStr)
|
||||||
b.printConfigRecursive(field, fullPath+".", prefixSecret, visited)
|
} else {
|
||||||
default:
|
// For non-struct fields with env tags
|
||||||
var valueStr string
|
var valueStr string
|
||||||
if field.Kind() == reflect.String {
|
if field.Kind() == reflect.String {
|
||||||
valueStr = field.String()
|
valueStr = field.String()
|
||||||
@@ -260,4 +271,10 @@ func (b *BaseConfig) printConfigRecursive(val reflect.Value, prefix string, pref
|
|||||||
"value", valueStr)
|
"value", valueStr)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Recurse into structs regardless of env tag
|
||||||
|
if field.Kind() == reflect.Struct {
|
||||||
|
b.printConfigRecursive(field, fullPath+".", prefixSecret, visited)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,7 +9,6 @@ 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"`
|
||||||
@@ -17,43 +16,9 @@ type AuthConfig struct {
|
|||||||
// 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 == "" {
|
||||||
|
|||||||
@@ -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)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user