package cloudinit import ( "fmt" "os" "gopkg.in/yaml.v3" ) // Parse reads a cloud-init YAML file and returns the parsed config. func Parse(path string) (*Config, error) { data, err := os.ReadFile(path) if err != nil { return nil, fmt.Errorf("reading cloud-init file %s: %w", path, err) } return ParseBytes(data) } // ParseBytes parses cloud-init YAML from a byte slice. func ParseBytes(data []byte) (*Config, error) { var cfg Config if err := yaml.Unmarshal(data, &cfg); err != nil { return nil, fmt.Errorf("parsing cloud-init YAML: %w", err) } if err := validate(&cfg); err != nil { return nil, fmt.Errorf("validating cloud-init config: %w", err) } // Apply defaults if cfg.Network.Mode == "" { cfg.Network.Mode = "dhcp" } return &cfg, nil } func validate(cfg *Config) error { switch cfg.Network.Mode { case "", "dhcp": // valid case "static": if cfg.Network.Address == "" { return fmt.Errorf("static network mode requires 'address' field") } if cfg.Network.Gateway == "" { return fmt.Errorf("static network mode requires 'gateway' field") } default: return fmt.Errorf("unknown network mode: %q (expected 'dhcp' or 'static')", cfg.Network.Mode) } return nil }