// Copyright 2025, IPng Networks GmbH, Pim van Pelt package main import ( "fmt" "io/ioutil" "dario.cat/mergo" "gopkg.in/yaml.v3" ) // Config structures type Config struct { Types map[string]DeviceType `yaml:"types"` Devices map[string]Device `yaml:"devices"` } type DeviceType struct { Commands []string `yaml:"commands"` } type Device struct { User string `yaml:"user"` Type string `yaml:"type,omitempty"` Commands []string `yaml:"commands,omitempty"` Address string `yaml:"address,omitempty"` } func readYAMLFile(path string) (map[string]interface{}, error) { data, err := ioutil.ReadFile(path) if err != nil { return nil, err } var result map[string]interface{} if err := yaml.Unmarshal(data, &result); err != nil { return nil, err } return result, nil } // ConfigRead loads and merges multiple YAML files into a single config object func ConfigRead(yamlFiles []string) (*Config, error) { var finalConfig map[string]interface{} for _, file := range yamlFiles { current, err := readYAMLFile(file) if err != nil { return nil, fmt.Errorf("failed to parse %s: %v", file, err) } if finalConfig == nil { finalConfig = current } else { err := mergo.Merge(&finalConfig, current, mergo.WithOverride) if err != nil { return nil, fmt.Errorf("failed to merge %s: %v", file, err) } } } // Convert back to structured config out, err := yaml.Marshal(finalConfig) if err != nil { return nil, fmt.Errorf("failed to marshal merged config: %v", err) } var config Config if err := yaml.Unmarshal(out, &config); err != nil { return nil, fmt.Errorf("failed to unmarshal to Config struct: %v", err) } return &config, nil }