package config import ( "fmt" "os" "time" "github.com/caarlos0/env/v11" yaml "github.com/oasdiff/yaml3" ) type ClientsConfig struct { LogLevel string `json:"logLevel" yaml:"logLevel" env:"LOG_LEVEL" default:"warn"` LogFormat string `json:"logFormat" yaml:"logFormat" env:"LOG_FORMAT" default:"console"` Clients []ClientConfig `json:"clients" yaml:"clients" envPrefix:"CLIENT_"` } type ClientType string const ( TypeEdgeOS ClientType = "edgeos" TypeToughSwitch ClientType = "toughswitch" ) type ClientConfig struct { Type ClientType `json:"type" yaml:"type" env:"TYPE"` Name string `json:"name" yaml:"name" env:"NAME"` Host string `json:"host" yaml:"host" env:"HOST"` Scheme string `json:"scheme" yaml:"scheme" env:"SCHEME" default:"https"` User string `json:"user" yaml:"user" env:"USER"` Pass string `json:"pass" yaml:"pass" env:"PASS"` Insecure bool `json:"insecure" yaml:"insecure" env:"INSECURE" default:"false"` Timeout time.Duration `json:"timeout" yaml:"timeout" env:"TIMEOUT" default:"10s"` } // LoadConfig will load a file if given, layering env on-top of the config // if present. Environment variables take the form: // - LOG_LEVEL, LOG_FORMAT for top-level settings // - CLIENT_0_NAME, CLIENT_0_HOST, CLIENT_0_TYPE, etc. for client array func LoadConfig(configPath *string) (*ClientsConfig, error) { conf, err := env.ParseAs[ClientsConfig]() if err != nil { return nil, fmt.Errorf("could not parse env config: %w", err) } if configPath != nil && *configPath != "" { file, err := os.Open(*configPath) if err != nil { return nil, fmt.Errorf("could not open config file: %w", err) } defer file.Close() decoder := yaml.NewDecoder(file) if err := decoder.Decode(&conf); err != nil { return nil, fmt.Errorf("could not decode config file: %w", err) } } return &conf, nil } // GetClientByName returns a client config by its name, or nil if not found. func (c *ClientsConfig) GetClientByName(name string) *ClientConfig { for i := range c.Clients { if c.Clients[i].Name == name { return &c.Clients[i] } } return nil } // GetClientNames returns a list of all configured client names. func (c *ClientsConfig) GetClientNames() []string { names := make([]string, len(c.Clients)) for i, client := range c.Clients { names[i] = client.Name } return names }