package config import ( "fmt" "metis/pkg/inventory" ) // NodeConfig represents boot-time configuration to inject. type NodeConfig struct { Hostname string `json:"hostname"` IP string `json:"ip"` K3s K3sConfig `json:"k3s"` SSHUser string `json:"ssh_user,omitempty"` SSHKeys []string `json:"ssh_keys,omitempty"` Labels map[string]string `json:"labels,omitempty"` Taints []string `json:"taints,omitempty"` Fstab []FstabEntry `json:"fstab,omitempty"` Secrets map[string]string `json:"secrets,omitempty"` // optional key/values for local agent use } // K3sConfig includes role and token/url. type K3sConfig struct { Role string `json:"role"` Version string `json:"version,omitempty"` URL string `json:"url,omitempty"` Token string `json:"token,omitempty"` Args []string `json:"args,omitempty"` Labels map[string]string `json:"labels,omitempty"` Taints []string `json:"taints,omitempty"` } // FstabEntry for Longhorn or other mounts. type FstabEntry struct { UUID string `json:"uuid"` Mountpoint string `json:"mountpoint"` FS string `json:"fs"` Options string `json:"options"` } // Build creates a NodeConfig from inventory. func Build(inv *inventory.Inventory, nodeName string) (*NodeConfig, error) { n, cls, err := inv.FindNode(nodeName) if err != nil { return nil, err } labels := map[string]string{} for k, v := range cls.DefaultLabels { labels[k] = v } for k, v := range n.Labels { labels[k] = v } taints := append([]string{}, cls.DefaultTaints...) taints = append(taints, n.Taints...) k3sVersion := cls.K3sVersion if n.K3sVersion != "" { k3sVersion = n.K3sVersion } fstab := []FstabEntry{} for _, d := range n.LonghornDisks { fs := d.FS if fs == "" { fs = "ext4" } fstab = append(fstab, FstabEntry{ UUID: d.UUID, Mountpoint: d.Mountpoint, FS: fs, Options: "defaults,nofail", }) } cfg := &NodeConfig{ Hostname: n.Hostname, IP: n.IP, SSHUser: n.SSHUser, SSHKeys: n.SSHAuthorized, Labels: labels, Taints: taints, Fstab: fstab, K3s: K3sConfig{ Role: n.K3sRole, Version: k3sVersion, URL: n.K3sURL, Token: n.K3sToken, Labels: labels, Taints: taints, }, } if cfg.Hostname == "" || cfg.IP == "" { return nil, fmt.Errorf("hostname/ip required for node %s", nodeName) } return cfg, nil }