// pkg/config/config.go package config import ( "fmt" "os" "git.linuxforward.com/byom/byom-golang-lib/pkg/auth" "git.linuxforward.com/byom/byom-golang-lib/pkg/database" "git.linuxforward.com/byom/byom-golang-lib/pkg/errors" "git.linuxforward.com/byom/byom-golang-lib/pkg/logger" "git.linuxforward.com/byom/byom-golang-lib/pkg/server" "git.linuxforward.com/byom/byom-golang-lib/pkg/storage" "gopkg.in/yaml.v3" ) type Config struct { App *App `yaml:"app"` Auth *auth.Config `yaml:"auth"` Server *server.Config `yaml:"server"` Database *database.Config `yaml:"database"` Log *logger.Config `yaml:"log"` Storage *storage.Config `yaml:"storage"` CloudComputing *CloudComputing `yaml:"cloud_computing,omitempty"` SocialNetworks *SocialNetworks `yaml:"social_networks,omitempty"` } func (c *Config) UnmarshalYAML(unmarshal func(interface{}) error) error { type plain Config err := unmarshal((*plain)(c)) if err != nil { return err } if c.App == nil { return errors.NewConfigError("app", errors.ErrInvalidInput) } // Conditional validation based on app name switch c.App.Name { case "design": if c.CloudComputing == nil { return errors.NewConfigError("cloud_computing", errors.ErrInvalidInput) } case "trends": if c.SocialNetworks == nil { return errors.NewConfigError("social_networks", errors.ErrInvalidInput) } } return nil } type App struct { Name string `yaml:"name"` Environment string `yaml:"environment"` } func (c *App) UnmarshalYAML(unmarshal func(interface{}) error) error { type plain App err := unmarshal((*plain)(c)) if err != nil { return err } if c.Name == "" { return errors.NewConfigError("app.name", errors.ErrInvalidInput) } if c.Environment == "" { c.Environment = "development" } // Validate app name validNames := map[string]bool{"core": true, "design": true, "trends": true} if !validNames[c.Name] { return errors.NewConfigError("app.name", errors.ErrInvalidInput) } return nil } type CloudComputing struct { Provider string `yaml:"provider"` Region string `yaml:"region"` MaxCapacity int `yaml:"max_capacity"` } func (c *CloudComputing) UnmarshalYAML(unmarshal func(interface{}) error) error { type plain CloudComputing err := unmarshal((*plain)(c)) if err != nil { return err } if c.Provider == "" { return errors.NewConfigError("cloud_computing.provider", errors.ErrInvalidInput) } if c.Region == "" { return errors.NewConfigError("cloud_computing.region", errors.ErrInvalidInput) } if c.MaxCapacity <= 0 { return errors.NewConfigError("cloud_computing.max_capacity", errors.ErrInvalidInput) } return nil } type SocialNetworks struct { Networks []SocialNetwork `yaml:"networks"` } type SocialNetwork struct { Name string `yaml:"name"` APIKey string `yaml:"api_key"` APIToken string `yaml:"api_token"` } func (c *SocialNetworks) UnmarshalYAML(unmarshal func(interface{}) error) error { type plain SocialNetworks err := unmarshal((*plain)(c)) if err != nil { return err } if len(c.Networks) == 0 { return errors.NewConfigError("social_networks", errors.ErrInvalidInput) } for i, network := range c.Networks { section := fmt.Sprintf("social_networks.networks[%d]", i) if network.Name == "" { return errors.NewConfigError(section+".name", errors.ErrInvalidInput) } if network.APIKey == "" { return errors.NewConfigError(section+".api_key", errors.ErrInvalidInput) } if network.APIToken == "" { return errors.NewConfigError(section+".api_token", errors.ErrInvalidInput) } } return nil } func ReadConfig(configPath string) (*Config, error) { data, err := os.ReadFile(configPath) if err != nil { return nil, errors.NewConfigError("read", err) } config := &Config{} err = yaml.Unmarshal(data, config) if err != nil { return nil, errors.NewConfigError("parse", err) } // Validate all config sections that implement Validator interface validators := []Validator{} if config.Storage != nil { validators = append(validators, config.Storage) } if config.Database != nil { validators = append(validators, config.Database) } if config.Log != nil { validators = append(validators, config.Log) } if config.Server != nil { validators = append(validators, config.Server) } if config.Auth != nil { validators = append(validators, config.Auth) } if err := ValidateAll(validators...); err != nil { return nil, err } return config, nil }