diff --git a/internal/app/wwctl/node/list/main.go b/internal/app/wwctl/node/list/main.go index 713ab66c..16954318 100644 --- a/internal/app/wwctl/node/list/main.go +++ b/internal/app/wwctl/node/list/main.go @@ -58,6 +58,10 @@ func CobraRunE(cmd *cobra.Command, args []string) error { fmt.Printf("%-20s %-18s %-12s %s\n", node.Id.Get(), name+":TYPE", netdev.Type.Source(), netdev.Type.Print()) fmt.Printf("%-20s %-18s %-12s %t\n", node.Id.Get(), name+":DEFAULT", netdev.Default.Source(), netdev.Default.PrintB()) } + + for keyname, key := range node.Keys { + fmt.Printf("%-20s %-18s %-12s %s\n", node.Id.Get(), "Keys."+keyname, key.Source(), key.Print()) + } } } else if ShowNet { diff --git a/internal/app/wwctl/node/set/main.go b/internal/app/wwctl/node/set/main.go index e8db25f4..ff45500c 100644 --- a/internal/app/wwctl/node/set/main.go +++ b/internal/app/wwctl/node/set/main.go @@ -325,6 +325,35 @@ func CobraRunE(cmd *cobra.Command, args []string) error { n.NetDevs[SetNetDev].Default.SetB(true) } + if SetValue != "" { + if SetKey == "" { + wwlog.Printf(wwlog.ERROR, "You must include the '--key/-k' option\n") + os.Exit(1) + } + + if _, ok := n.Keys[SetKey]; !ok { + var nd node.Entry + n.Keys[SetKey] = &nd + } + wwlog.Printf(wwlog.VERBOSE, "Node: %s:%s, Setting Value %s\n", n.Id.Get(), SetKey, SetValue) + n.Keys[SetKey].Set(SetValue) + } + + if SetKeyDel == true { + if SetKey == "" { + wwlog.Printf(wwlog.ERROR, "You must include the '--key/-k' option\n") + os.Exit(1) + } + + if _, ok := n.Keys[SetKey]; !ok { + wwlog.Printf(wwlog.ERROR, "Custom parameter doesn't exist: %s\n", SetKey) + os.Exit(1) + } + + wwlog.Printf(wwlog.VERBOSE, "Node: %s, Deleting custom parameter: %s\n", n.Id.Get(), SetNetDev) + delete(n.Keys, SetKey) + } + err := nodeDB.NodeUpdate(n) if err != nil { wwlog.Printf(wwlog.ERROR, "%s\n", err) diff --git a/internal/app/wwctl/node/set/root.go b/internal/app/wwctl/node/set/root.go index 0a7747d2..48c1531d 100644 --- a/internal/app/wwctl/node/set/root.go +++ b/internal/app/wwctl/node/set/root.go @@ -41,6 +41,9 @@ var ( SetDiscoverable bool SetUndiscoverable bool SetRoot string + SetKey string + SetValue string + SetKeyDel bool ) func init() { @@ -74,6 +77,11 @@ func init() { baseCmd.PersistentFlags().BoolVar(&SetNetDevDel, "netdel", false, "Delete the node's network device") baseCmd.PersistentFlags().BoolVar(&SetNetDevDefault, "netdefault", false, "Set this network to be default") + baseCmd.PersistentFlags().StringVarP(&SetKey, "key", "k", "", "Define custom key") + baseCmd.PersistentFlags().BoolVar(&SetKeyDel, "keydel", false, "Delete custom key") + + baseCmd.PersistentFlags().StringVarP(&SetValue, "value", "", "", "Set value") + baseCmd.PersistentFlags().BoolVarP(&SetNodeAll, "all", "a", false, "Set all nodes") baseCmd.PersistentFlags().BoolVarP(&SetYes, "yes", "y", false, "Set 'yes' to all questions asked") diff --git a/internal/app/wwctl/profile/list/main.go b/internal/app/wwctl/profile/list/main.go index c84998b4..03b4c91a 100644 --- a/internal/app/wwctl/profile/list/main.go +++ b/internal/app/wwctl/profile/list/main.go @@ -54,6 +54,10 @@ func CobraRunE(cmd *cobra.Command, args []string) error { fmt.Printf("%-20s %-18s %s\n", profile.Id.Get(), name+":TYPE", netdev.Hwaddr.Print()) fmt.Printf("%-20s %-18s %t\n", profile.Id.Get(), name+":DEFAULT", netdev.Default.PrintB()) } + + for keyname, key := range profile.Keys { + fmt.Printf("%-20s %-18s %s\n", profile.Id.Get(), "Keys."+keyname, key.Print()) + } } } else { fmt.Printf("%-20s %s\n", "PROFILE NAME", "COMMENT/DESCRIPTION") diff --git a/internal/app/wwctl/profile/set/main.go b/internal/app/wwctl/profile/set/main.go index 696dfa4d..b7a2eda6 100644 --- a/internal/app/wwctl/profile/set/main.go +++ b/internal/app/wwctl/profile/set/main.go @@ -233,7 +233,7 @@ func CobraRunE(cmd *cobra.Command, args []string) error { p.NetDevs[SetNetDev] = &nd } - wwlog.Printf(wwlog.VERBOSE, "Node: %s:%s, Setting device as default\n", p.Id.Get(), SetNetDev) + wwlog.Printf(wwlog.VERBOSE, "Profile: %s:%s, Setting device as default\n", p.Id.Get(), SetNetDev) for _, dev := range p.NetDevs { // First clear all other devices that might be configured as default dev.Default.SetB(false) @@ -241,6 +241,35 @@ func CobraRunE(cmd *cobra.Command, args []string) error { p.NetDevs[SetNetDev].Default.SetB(true) } + if SetValue != "" { + if SetKey == "" { + wwlog.Printf(wwlog.ERROR, "You must include the '--key/-k' option\n") + os.Exit(1) + } + + if _, ok := p.Keys[SetKey]; !ok { + var nd node.Entry + p.Keys[SetKey] = &nd + } + wwlog.Printf(wwlog.VERBOSE, "Profile: %s:%s, Setting Value %s\n", p.Id.Get(), SetKey, SetValue) + p.Keys[SetKey].Set(SetValue) + } + + if SetKeyDel == true { + if SetKey == "" { + wwlog.Printf(wwlog.ERROR, "You must include the '--key/-k' option\n") + os.Exit(1) + } + + if _, ok := p.Keys[SetKey]; !ok { + wwlog.Printf(wwlog.ERROR, "Custom key doesn't exist: %s\n", SetKey) + os.Exit(1) + } + + wwlog.Printf(wwlog.VERBOSE, "Profile: %s, Deleting custom key: %s\n", p.Id.Get(), SetNetDev) + delete(p.Keys, SetKey) + } + err := nodeDB.ProfileUpdate(p) if err != nil { wwlog.Printf(wwlog.ERROR, "%s\n", err) diff --git a/internal/app/wwctl/profile/set/root.go b/internal/app/wwctl/profile/set/root.go index 6d81f861..2bc4b6e2 100644 --- a/internal/app/wwctl/profile/set/root.go +++ b/internal/app/wwctl/profile/set/root.go @@ -35,6 +35,9 @@ var ( SetNetDevDefault bool SetInit string SetRoot string + SetKey string + SetValue string + SetKeyDel bool ) func init() { @@ -63,6 +66,11 @@ func init() { baseCmd.PersistentFlags().BoolVar(&SetNetDevDel, "netdel", false, "Delete the node's network device") baseCmd.PersistentFlags().BoolVar(&SetNetDevDefault, "netdefault", false, "Set this network to be default") + baseCmd.PersistentFlags().StringVarP(&SetKey, "key", "k", "", "Define custom key") + baseCmd.PersistentFlags().BoolVar(&SetKeyDel, "keydel", false, "Delete custom key") + + baseCmd.PersistentFlags().StringVarP(&SetValue, "value", "", "", "Set value") + baseCmd.PersistentFlags().BoolVarP(&SetAll, "all", "a", false, "Set all profiles") baseCmd.PersistentFlags().BoolVarP(&SetForce, "force", "f", false, "Force configuration (even on error)") baseCmd.PersistentFlags().BoolVarP(&SetYes, "yes", "y", false, "Set 'yes' to all questions asked") diff --git a/internal/pkg/node/constructors.go b/internal/pkg/node/constructors.go index 6e15f2f3..7f90342c 100644 --- a/internal/pkg/node/constructors.go +++ b/internal/pkg/node/constructors.go @@ -43,6 +43,7 @@ func (config *nodeYaml) FindAllNodes() ([]NodeInfo, error) { wwlog.Printf(wwlog.DEBUG, "In node loop: %s\n", nodename) n.NetDevs = make(map[string]*NetDevEntry) + n.Keys = make(map[string]*Entry) n.SystemOverlay.SetDefault("default") n.RuntimeOverlay.SetDefault("default") n.Ipxe.SetDefault("default") @@ -94,6 +95,14 @@ func (config *nodeYaml) FindAllNodes() ([]NodeInfo, error) { n.NetDevs[devname].Default.SetB(netdev.Default) } + for keyname, key := range node.Keys { + if _, ok := n.Keys[keyname]; !ok { + var key Entry + n.Keys[keyname] = &key + } + n.Keys[keyname].Set(key) + } + for _, p := range n.Profiles { if _, ok := config.NodeProfiles[p]; !ok { wwlog.Printf(wwlog.WARN, "Profile not found for node '%s': %s\n", nodename, p) @@ -134,6 +143,14 @@ func (config *nodeYaml) FindAllNodes() ([]NodeInfo, error) { n.NetDevs[devname].Type.SetAlt(netdev.Type, p) n.NetDevs[devname].Default.SetAltB(netdev.Default, p) } + + for keyname, key := range config.NodeProfiles[p].Keys { + if _, ok := n.Keys[keyname]; !ok { + var key Entry + n.Keys[keyname] = &key + } + n.Keys[keyname].SetAlt(key, p) + } } ret = append(ret, n) @@ -160,6 +177,7 @@ func (config *nodeYaml) FindAllProfiles() ([]NodeInfo, error) { for name, profile := range config.NodeProfiles { var p NodeInfo p.NetDevs = make(map[string]*NetDevEntry) + p.Keys = make(map[string]*Entry) p.Id.Set(name) p.Comment.Set(profile.Comment) @@ -194,6 +212,14 @@ func (config *nodeYaml) FindAllProfiles() ([]NodeInfo, error) { p.NetDevs[devname].Default.SetB(netdev.Default) } + for keyname, key := range profile.Keys { + if _, ok := p.Keys[keyname]; !ok { + var key Entry + p.Keys[keyname] = &key + } + p.Keys[keyname].Set(key) + } + // TODO: Validate or die on all inputs ret = append(ret, p) diff --git a/internal/pkg/node/datastructure.go b/internal/pkg/node/datastructure.go index 67427052..406c656d 100644 --- a/internal/pkg/node/datastructure.go +++ b/internal/pkg/node/datastructure.go @@ -36,6 +36,7 @@ type NodeConf struct { Discoverable bool `yaml:"discoverable,omitempty"` Profiles []string `yaml:"profiles,omitempty"` NetDevs map[string]*NetDevs `yaml:"network devices,omitempty"` + Keys map[string]string `yaml:"keys,omitempty"` } type NetDevs struct { @@ -82,6 +83,7 @@ type NodeInfo struct { Profiles []string GroupProfiles []string NetDevs map[string]*NetDevEntry + Keys map[string]*Entry } type NetDevEntry struct { diff --git a/internal/pkg/node/modifiers.go b/internal/pkg/node/modifiers.go index 41a81b2d..ce22dea1 100644 --- a/internal/pkg/node/modifiers.go +++ b/internal/pkg/node/modifiers.go @@ -75,6 +75,8 @@ func (config *nodeYaml) NodeUpdate(node NodeInfo) error { config.Nodes[nodeID].Profiles = node.Profiles config.Nodes[nodeID].NetDevs = make(map[string]*NetDevs) + config.Nodes[nodeID].Keys = make(map[string]string) + for devname, netdev := range node.NetDevs { var newdev NetDevs config.Nodes[nodeID].NetDevs[devname] = &newdev @@ -87,6 +89,10 @@ func (config *nodeYaml) NodeUpdate(node NodeInfo) error { config.Nodes[nodeID].NetDevs[devname].Default = netdev.Default.GetRealB() } + for keyname, key := range node.Keys { + config.Nodes[nodeID].Keys[keyname] = key.GetReal() + } + return nil } @@ -151,6 +157,8 @@ func (config *nodeYaml) ProfileUpdate(profile NodeInfo) error { config.NodeProfiles[profileID].Profiles = profile.Profiles config.NodeProfiles[profileID].NetDevs = make(map[string]*NetDevs) + + config.NodeProfiles[profileID].Keys = make(map[string]string) for devname, netdev := range profile.NetDevs { var newdev NetDevs @@ -164,6 +172,10 @@ func (config *nodeYaml) ProfileUpdate(profile NodeInfo) error { config.NodeProfiles[profileID].NetDevs[devname].Default = netdev.Default.GetRealB() } + for keyname, key := range profile.Keys { + config.NodeProfiles[profileID].Keys[keyname] = key.GetReal() + } + return nil } diff --git a/internal/pkg/overlay/overlay.go b/internal/pkg/overlay/overlay.go index 2209fcfc..7936e534 100644 --- a/internal/pkg/overlay/overlay.go +++ b/internal/pkg/overlay/overlay.go @@ -31,6 +31,7 @@ type TemplateStruct struct { IpmiUserName string IpmiPassword string NetDevs map[string]*node.NetDevs + Keys map[string]string AllNodes []node.NodeInfo } @@ -149,6 +150,7 @@ func buildOverlay(nodeList []node.NodeInfo, overlayType string) error { t.IpmiUserName = n.IpmiUserName.Get() t.IpmiPassword = n.IpmiPassword.Get() t.NetDevs = make(map[string]*node.NetDevs) + t.Keys = make(map[string]string) for devname, netdev := range n.NetDevs { var nd node.NetDevs t.NetDevs[devname] = &nd @@ -159,6 +161,9 @@ func buildOverlay(nodeList []node.NodeInfo, overlayType string) error { t.NetDevs[devname].Type = netdev.Type.Get() t.NetDevs[devname].Default = netdev.Default.GetB() } + for keyname, key := range n.Keys { + t.Keys[keyname] = key.Get() + } t.AllNodes = allNodes if overlayType == "runtime" && n.RuntimeOverlay.Defined() == false {