Updates to nodeStore
This commit is contained in:
219
internal/pkg/node/constructors.go
Normal file
219
internal/pkg/node/constructors.go
Normal file
@@ -0,0 +1,219 @@
|
||||
package node
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/hpcng/warewulf/internal/pkg/errors"
|
||||
"github.com/hpcng/warewulf/internal/pkg/wwlog"
|
||||
"gopkg.in/yaml.v2"
|
||||
"io/ioutil"
|
||||
"regexp"
|
||||
)
|
||||
|
||||
func New() (nodeYaml, error) {
|
||||
var ret nodeYaml
|
||||
|
||||
wwlog.Printf(wwlog.DEBUG, "Opening node configuration file: %s\n", ConfigFile)
|
||||
data, err := ioutil.ReadFile(ConfigFile)
|
||||
if err != nil {
|
||||
fmt.Printf("error reading node configuration file\n")
|
||||
return ret, err
|
||||
}
|
||||
|
||||
err = yaml.Unmarshal(data, &ret)
|
||||
if err != nil {
|
||||
return ret, err
|
||||
}
|
||||
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
func (self *nodeYaml) FindAllNodes() ([]NodeInfo, error) {
|
||||
var ret []NodeInfo
|
||||
|
||||
for groupname, group := range self.NodeGroups {
|
||||
for nodename, node := range group.Nodes {
|
||||
var n NodeInfo
|
||||
var allProfiles []string
|
||||
|
||||
if node.Disabled == true || group.Disabled == true {
|
||||
wwlog.Printf(wwlog.VERBOSE, "Skipping disabled node: %s/%s\n", groupname, nodename)
|
||||
continue
|
||||
}
|
||||
|
||||
n.Id = nodename
|
||||
n.Gid = groupname
|
||||
n.GroupName = groupname
|
||||
n.HostName = node.Hostname
|
||||
n.IpmiIpaddr.Set(node.IpmiIpaddr)
|
||||
|
||||
n.Profiles = node.Profiles
|
||||
|
||||
allProfiles = append(allProfiles, group.Profiles...)
|
||||
allProfiles = append(allProfiles, node.Profiles...)
|
||||
|
||||
for _, p := range allProfiles {
|
||||
if _, ok := self.NodeProfiles[p]; !ok {
|
||||
wwlog.Printf(wwlog.WARN, "Profile not found for node '%s': %s\n", nodename, p)
|
||||
continue
|
||||
}
|
||||
|
||||
n.Vnfs.profile = self.NodeProfiles[p].Vnfs
|
||||
n.KernelVersion.profile = self.NodeProfiles[p].KernelVersion
|
||||
n.KernelArgs.profile = self.NodeProfiles[p].KernelArgs
|
||||
n.Ipxe.profile = self.NodeProfiles[p].Ipxe
|
||||
n.IpmiUserName.profile = self.NodeProfiles[p].IpmiUserName
|
||||
n.IpmiPassword.profile = self.NodeProfiles[p].IpmiPassword
|
||||
n.DomainName.profile = self.NodeProfiles[p].DomainName
|
||||
n.SystemOverlay.profile = self.NodeProfiles[p].SystemOverlay
|
||||
n.RuntimeOverlay.profile = self.NodeProfiles[p].RuntimeOverlay
|
||||
}
|
||||
|
||||
n.DomainName.value = node.DomainName
|
||||
n.DomainName.group = group.DomainName
|
||||
n.Vnfs.value = node.Vnfs
|
||||
n.KernelVersion.value = node.KernelVersion
|
||||
n.KernelArgs.value = node.KernelArgs
|
||||
n.Ipxe.value = node.Ipxe
|
||||
n.IpmiUserName.value = node.IpmiUserName
|
||||
n.IpmiPassword.value = node.IpmiPassword
|
||||
|
||||
n.RuntimeOverlay.def = "default"
|
||||
n.SystemOverlay.def = "default"
|
||||
n.Ipxe.def = "default"
|
||||
n.KernelArgs.def = "crashkernel=no quiet"
|
||||
|
||||
// config := config.New()
|
||||
// n.VnfsRoot = config.VnfsChroot(vnfs.CleanName(n.Vnfs))
|
||||
|
||||
if n.DomainName.Defined() == true {
|
||||
n.Fqdn = n.HostName + "." + n.DomainName.Get()
|
||||
} else {
|
||||
n.Fqdn = node.Hostname
|
||||
}
|
||||
|
||||
n.NetDevs = node.NetDevs
|
||||
|
||||
ret = append(ret, n)
|
||||
}
|
||||
}
|
||||
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
func (self *nodeYaml) FindAllGroups() ([]GroupInfo, error) {
|
||||
var ret []GroupInfo
|
||||
|
||||
for groupname, group := range self.NodeGroups {
|
||||
var g GroupInfo
|
||||
|
||||
g.Id = groupname
|
||||
g.DomainName = group.DomainName
|
||||
g.Disabled = group.Disabled
|
||||
g.Comment = group.Comment
|
||||
|
||||
g.Profiles = group.Profiles
|
||||
|
||||
// TODO: Validate or die on all inputs
|
||||
|
||||
ret = append(ret, g)
|
||||
}
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
func (self *nodeYaml) FindAllProfiles() ([]ProfileInfo, error) {
|
||||
var ret []ProfileInfo
|
||||
|
||||
for name, profile := range self.NodeProfiles {
|
||||
var p ProfileInfo
|
||||
|
||||
p.Id = name
|
||||
p.Comment = profile.Comment
|
||||
p.Vnfs = profile.Vnfs
|
||||
p.Ipxe = profile.Ipxe
|
||||
p.KernelVersion = profile.KernelVersion
|
||||
p.KernelArgs = profile.KernelArgs
|
||||
p.IpmiUserName = profile.IpmiUserName
|
||||
p.IpmiPassword = profile.IpmiPassword
|
||||
p.DomainName = profile.DomainName
|
||||
p.RuntimeOverlay = profile.RuntimeOverlay
|
||||
p.SystemOverlay = profile.SystemOverlay
|
||||
|
||||
// TODO: Validate or die on all inputs
|
||||
|
||||
ret = append(ret, p)
|
||||
}
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
|
||||
|
||||
func (self *nodeYaml) FindByHwaddr(hwa string) (NodeInfo, error) {
|
||||
var ret NodeInfo
|
||||
|
||||
n, _ := self.FindAllNodes()
|
||||
|
||||
for _, node := range n {
|
||||
for _, dev := range node.NetDevs {
|
||||
if dev.Hwaddr == hwa {
|
||||
return node, nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ret, errors.New("No nodes found with HW Addr: " + hwa)
|
||||
}
|
||||
|
||||
func (self *nodeYaml) FindByIpaddr(ipaddr string) (NodeInfo, error) {
|
||||
var ret NodeInfo
|
||||
|
||||
n, _ := self.FindAllNodes()
|
||||
|
||||
for _, node := range n {
|
||||
for _, dev := range node.NetDevs {
|
||||
if dev.Ipaddr == ipaddr {
|
||||
return node, nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ret, errors.New("No nodes found with IP Addr: " + ipaddr)
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
func (nodes *nodeYaml) SearchByName(search string) ([]NodeInfo, error) {
|
||||
var ret []NodeInfo
|
||||
|
||||
n, _ := nodes.FindAllNodes()
|
||||
|
||||
for _, node := range n {
|
||||
b, _ := regexp.MatchString(search, node.Fqdn)
|
||||
if b == true {
|
||||
ret = append(ret, node)
|
||||
}
|
||||
}
|
||||
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
func (nodes *nodeYaml) SearchByNameList(searchList []string) ([]NodeInfo, error) {
|
||||
var ret []NodeInfo
|
||||
|
||||
n, _ := nodes.FindAllNodes()
|
||||
|
||||
for _, search := range searchList {
|
||||
for _, node := range n {
|
||||
b, _ := regexp.MatchString(search, node.Fqdn)
|
||||
if b == true {
|
||||
ret = append(ret, node)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ret, nil
|
||||
}
|
||||
123
internal/pkg/node/datastructure.go
Normal file
123
internal/pkg/node/datastructure.go
Normal file
@@ -0,0 +1,123 @@
|
||||
package node
|
||||
|
||||
import (
|
||||
"github.com/hpcng/warewulf/internal/pkg/util"
|
||||
"github.com/hpcng/warewulf/internal/pkg/wwlog"
|
||||
"os"
|
||||
)
|
||||
|
||||
type nodeYaml struct {
|
||||
NodeProfiles map[string]*ProfileConf
|
||||
NodeGroups map[string]*GroupConf
|
||||
}
|
||||
|
||||
type ProfileConf struct {
|
||||
Comment string `yaml:"comment"`
|
||||
Vnfs string `yaml:"vnfs,omitempty"`
|
||||
Ipxe string `yaml:"ipxe template,omitempty"`
|
||||
KernelVersion string `yaml:"kernel version,omitempty"`
|
||||
KernelArgs string `yaml:"kernel args,omitempty"`
|
||||
IpmiUserName string `yaml:"ipmi username,omitempty"`
|
||||
IpmiPassword string `yaml:"ipmi password,omitempty"`
|
||||
DomainName string `yaml:"domain name,omitempty"`
|
||||
RuntimeOverlay string `yaml:"runtime overlay files,omitempty"`
|
||||
SystemOverlay string `yaml:"system overlay files,omitempty"`
|
||||
}
|
||||
|
||||
type GroupConf struct {
|
||||
Comment string `yaml:"comment"`
|
||||
Disabled bool `yaml:"disabled,omitempty"`
|
||||
DomainName string `yaml:"domain name"`
|
||||
Profiles []string `yaml:"profiles,omitempty"`
|
||||
Nodes map[string]*NodeConf
|
||||
}
|
||||
|
||||
type NodeConf struct {
|
||||
Comment string `yaml:"comment,omitempty"`
|
||||
Disabled bool `yaml:"disabled,omitempty"`
|
||||
Hostname string `yaml:"hostname,omitempty"`
|
||||
Vnfs string `yaml:"vnfs,omitempty"`
|
||||
Ipxe string `yaml:"ipxe template,omitempty"`
|
||||
KernelVersion string `yaml:"kernel version,omitempty"`
|
||||
KernelArgs string `yaml:"kernel args,omitempty"`
|
||||
IpmiUserName string `yaml:"ipmi username,omitempty"`
|
||||
IpmiPassword string `yaml:"ipmi password,omitempty"`
|
||||
DomainName string `yaml:"domain name,omitempty"`
|
||||
IpmiIpaddr string `yaml:"ipmi ipaddr,omitempty"`
|
||||
RuntimeOverlay string `yaml:"runtime overlay files,omitempty"`
|
||||
SystemOverlay string `yaml:"system overlay files,omitempty"`
|
||||
Profiles []string `yaml:"profiles,omitempty"`
|
||||
NetDevs map[string]*NetDevs
|
||||
}
|
||||
|
||||
type NetDevs struct {
|
||||
Type string `yaml:"type,omitempty"`
|
||||
Hwaddr string
|
||||
Ipaddr string
|
||||
Netmask string
|
||||
Gateway string `yaml:"gateway,omitempty"`
|
||||
}
|
||||
|
||||
type NodeInfoEntry struct {
|
||||
value string
|
||||
profile string
|
||||
group string
|
||||
def string
|
||||
}
|
||||
|
||||
type NodeInfo struct {
|
||||
Id string
|
||||
Gid string
|
||||
Uid string
|
||||
Comment string
|
||||
GroupName string
|
||||
HostName string
|
||||
Fqdn string
|
||||
DomainName NodeInfoEntry
|
||||
Vnfs NodeInfoEntry
|
||||
VnfsRoot NodeInfoEntry
|
||||
Ipxe NodeInfoEntry
|
||||
KernelVersion NodeInfoEntry
|
||||
KernelArgs NodeInfoEntry
|
||||
IpmiIpaddr NodeInfoEntry
|
||||
IpmiUserName NodeInfoEntry
|
||||
IpmiPassword NodeInfoEntry
|
||||
RuntimeOverlay NodeInfoEntry
|
||||
SystemOverlay NodeInfoEntry
|
||||
Profiles []string
|
||||
NetDevs map[string]*NetDevs
|
||||
}
|
||||
|
||||
type GroupInfo struct {
|
||||
Id string
|
||||
Comment string
|
||||
Disabled bool
|
||||
DomainName string
|
||||
Profiles []string
|
||||
}
|
||||
|
||||
type ProfileInfo struct {
|
||||
Id string
|
||||
Comment string
|
||||
Vnfs string
|
||||
Ipxe string
|
||||
KernelVersion string
|
||||
KernelArgs string
|
||||
IpmiUserName string
|
||||
IpmiPassword string
|
||||
DomainName string
|
||||
RuntimeOverlay string
|
||||
SystemOverlay string
|
||||
}
|
||||
|
||||
|
||||
|
||||
const ConfigFile = "/etc/warewulf/nodes.conf"
|
||||
|
||||
func init() {
|
||||
//TODO: Check to make sure nodes.conf is found
|
||||
if util.IsFile(ConfigFile) == false {
|
||||
wwlog.Printf(wwlog.ERROR, "Configuration file not found: %s\n", ConfigFile)
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
55
internal/pkg/node/methods.go
Normal file
55
internal/pkg/node/methods.go
Normal file
@@ -0,0 +1,55 @@
|
||||
package node
|
||||
|
||||
func (self *NodeInfoEntry) String() string {
|
||||
if self.value != "" {
|
||||
return "node=" + self.value
|
||||
}
|
||||
if self.group != "" {
|
||||
return "group=" + self.group
|
||||
}
|
||||
if self.profile != "" {
|
||||
return "profile=" + self.profile
|
||||
}
|
||||
if self.def != "" {
|
||||
return "default=" + self.def
|
||||
}
|
||||
return "--"
|
||||
}
|
||||
|
||||
func (self *NodeInfoEntry) Get() string {
|
||||
if self.value != "" {
|
||||
return self.value
|
||||
}
|
||||
if self.group != "" {
|
||||
return self.group
|
||||
}
|
||||
if self.profile != "" {
|
||||
return self.profile
|
||||
}
|
||||
if self.def != "" {
|
||||
return self.def
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (self *NodeInfoEntry) Defined() bool {
|
||||
if self.Get() == "" {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func (self *NodeInfoEntry) Set(value string) {
|
||||
if value == "" {
|
||||
return
|
||||
}
|
||||
self.value = value
|
||||
}
|
||||
|
||||
func (self *NodeInfoEntry) Unset() {
|
||||
self.value = ""
|
||||
}
|
||||
|
||||
func (self *NodeInfoEntry) GetReal() string {
|
||||
return self.value
|
||||
}
|
||||
209
internal/pkg/node/modifiers.go
Normal file
209
internal/pkg/node/modifiers.go
Normal file
@@ -0,0 +1,209 @@
|
||||
package node
|
||||
|
||||
import (
|
||||
"github.com/hpcng/warewulf/internal/pkg/errors"
|
||||
"github.com/hpcng/warewulf/internal/pkg/wwlog"
|
||||
|
||||
"gopkg.in/yaml.v2"
|
||||
"os"
|
||||
)
|
||||
|
||||
/****
|
||||
*
|
||||
* NODE MODIFIERS
|
||||
*
|
||||
****/
|
||||
|
||||
func (self *nodeYaml) AddNode(groupID string, nodeID string) error {
|
||||
var node NodeConf
|
||||
|
||||
wwlog.Printf(wwlog.VERBOSE, "Adding new node: %s/%s\n", groupID, nodeID)
|
||||
|
||||
if _, ok := self.NodeGroups[groupID]; !ok {
|
||||
return errors.New("Group does not exist: " + groupID)
|
||||
}
|
||||
|
||||
if _, ok := self.NodeGroups[groupID].Nodes[groupID]; ok {
|
||||
return errors.New("Nodename already exists in group: " + nodeID)
|
||||
}
|
||||
|
||||
self.NodeGroups[groupID].Nodes[nodeID] = &node
|
||||
self.NodeGroups[groupID].Nodes[nodeID].Hostname = nodeID
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *nodeYaml) DelNode(groupID string, nodeID string) error {
|
||||
|
||||
if _, ok := self.NodeGroups[groupID]; !ok {
|
||||
return errors.New("Group '" + groupID + "' was not found")
|
||||
}
|
||||
if _, ok := self.NodeGroups[groupID].Nodes[nodeID]; !ok {
|
||||
return errors.New("Node '" + nodeID + "' was not found in group '" + groupID + "'")
|
||||
}
|
||||
|
||||
wwlog.Printf(wwlog.VERBOSE, "Deleting node network device: %s/%s\n", groupID, nodeID)
|
||||
delete(self.NodeGroups[groupID].Nodes, nodeID)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func(self *nodeYaml) NodeUpdate(node NodeInfo) error {
|
||||
groupID := node.Gid
|
||||
nodeID := node.Id
|
||||
|
||||
if _, ok := self.NodeGroups[groupID]; !ok {
|
||||
return errors.New("Group '" + groupID + "' was not found")
|
||||
}
|
||||
if _, ok := self.NodeGroups[groupID].Nodes[nodeID]; !ok {
|
||||
return errors.New("Node '" + nodeID + "' was not found in group '" + groupID + "'")
|
||||
}
|
||||
|
||||
self.NodeGroups[groupID].Nodes[nodeID].Hostname = node.HostName
|
||||
self.NodeGroups[groupID].Nodes[nodeID].Vnfs = node.Vnfs.GetReal()
|
||||
self.NodeGroups[groupID].Nodes[nodeID].DomainName = node.DomainName.GetReal()
|
||||
self.NodeGroups[groupID].Nodes[nodeID].Ipxe = node.Ipxe.GetReal()
|
||||
self.NodeGroups[groupID].Nodes[nodeID].KernelVersion = node.KernelVersion.GetReal()
|
||||
self.NodeGroups[groupID].Nodes[nodeID].KernelArgs = node.KernelArgs.GetReal()
|
||||
self.NodeGroups[groupID].Nodes[nodeID].IpmiIpaddr = node.IpmiIpaddr.GetReal()
|
||||
self.NodeGroups[groupID].Nodes[nodeID].IpmiUserName = node.IpmiUserName.GetReal()
|
||||
self.NodeGroups[groupID].Nodes[nodeID].IpmiPassword = node.IpmiPassword.GetReal()
|
||||
self.NodeGroups[groupID].Nodes[nodeID].RuntimeOverlay = node.RuntimeOverlay.GetReal()
|
||||
self.NodeGroups[groupID].Nodes[nodeID].SystemOverlay = node.SystemOverlay.GetReal()
|
||||
self.NodeGroups[groupID].Nodes[nodeID].Profiles = node.Profiles
|
||||
self.NodeGroups[groupID].Nodes[nodeID].NetDevs = node.NetDevs
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
|
||||
/****
|
||||
*
|
||||
* GROUP MODIFIERS
|
||||
*
|
||||
****/
|
||||
|
||||
func (self *nodeYaml) AddGroup(groupID string) error {
|
||||
var group GroupConf
|
||||
|
||||
wwlog.Printf(wwlog.VERBOSE, "Adding new group: %s/%s\n", groupID)
|
||||
|
||||
if _, ok := self.NodeGroups[groupID]; ok {
|
||||
return errors.New("Group name already exists: " + groupID)
|
||||
}
|
||||
|
||||
self.NodeGroups[groupID] = &group
|
||||
self.NodeGroups[groupID].DomainName = groupID
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *nodeYaml) DelGroup(groupID string) error {
|
||||
if _, ok := self.NodeGroups[groupID]; !ok {
|
||||
|
||||
return errors.New("Group '" + groupID + "' was not found")
|
||||
}
|
||||
|
||||
wwlog.Printf(wwlog.VERBOSE, "Deleting group: %s\n", groupID)
|
||||
delete(self.NodeGroups, groupID)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func(self *nodeYaml) GroupUpdate(group GroupInfo) error {
|
||||
groupID := group.Id
|
||||
|
||||
if _, ok := self.NodeGroups[groupID]; !ok {
|
||||
return errors.New("Group '" + groupID + "' was not found")
|
||||
}
|
||||
|
||||
self.NodeGroups[groupID].DomainName = group.DomainName
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/****
|
||||
*
|
||||
* PROFILE MODIFIERS
|
||||
*
|
||||
****/
|
||||
|
||||
func (self *nodeYaml) AddProfile(profileID string) error {
|
||||
var profile ProfileConf
|
||||
|
||||
wwlog.Printf(wwlog.VERBOSE, "Adding new profile: %s/%s\n", profileID)
|
||||
|
||||
if _, ok := self.NodeProfiles[profileID]; ok {
|
||||
return errors.New("Profile name already exists: " + profileID)
|
||||
}
|
||||
|
||||
self.NodeProfiles[profileID] = &profile
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *nodeYaml) DelProfile(profileID string) error {
|
||||
if _, ok := self.NodeProfiles[profileID]; ! ok {
|
||||
return errors.New("Group '" + profileID + "' was not found")
|
||||
}
|
||||
|
||||
wwlog.Printf(wwlog.VERBOSE, "Deleting profile: %s\n", profileID)
|
||||
delete(self.NodeProfiles, profileID)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func(self *nodeYaml) ProfileUpdate(profile ProfileInfo) error {
|
||||
profileID := profile.Id
|
||||
|
||||
if _, ok := self.NodeProfiles[profileID]; ! ok {
|
||||
return errors.New("Group '" + profileID + "' was not found")
|
||||
}
|
||||
|
||||
self.NodeProfiles[profileID].DomainName = profile.DomainName
|
||||
self.NodeProfiles[profileID].Vnfs = profile.Vnfs
|
||||
self.NodeProfiles[profileID].Ipxe = profile.Ipxe
|
||||
self.NodeProfiles[profileID].KernelVersion = profile.KernelVersion
|
||||
self.NodeProfiles[profileID].IpmiUserName = profile.IpmiUserName
|
||||
self.NodeProfiles[profileID].IpmiPassword = profile.IpmiPassword
|
||||
self.NodeProfiles[profileID].RuntimeOverlay = profile.RuntimeOverlay
|
||||
self.NodeProfiles[profileID].SystemOverlay = profile.SystemOverlay
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/****
|
||||
*
|
||||
* PERSISTENCE
|
||||
*
|
||||
****/
|
||||
|
||||
func (self *nodeYaml) Persist() error {
|
||||
|
||||
out, err := yaml.Marshal(self)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
file, err := os.OpenFile(ConfigFile, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0644)
|
||||
if err != nil {
|
||||
wwlog.Printf(wwlog.ERROR, "%s\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
defer file.Close()
|
||||
|
||||
_, err = file.WriteString(string(out))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -1,222 +0,0 @@
|
||||
package node
|
||||
|
||||
import (
|
||||
"github.com/hpcng/warewulf/internal/pkg/errors"
|
||||
"github.com/hpcng/warewulf/internal/pkg/util"
|
||||
"github.com/hpcng/warewulf/internal/pkg/wwlog"
|
||||
|
||||
"gopkg.in/yaml.v2"
|
||||
"os"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func (self *nodeYaml) AddGroup(groupID string) error {
|
||||
var group nodeGroup
|
||||
|
||||
if _, ok := self.NodeGroups[groupID]; ok {
|
||||
return errors.New("Group name already exists: " + groupID)
|
||||
}
|
||||
|
||||
self.NodeGroups[groupID] = &group
|
||||
self.NodeGroups[groupID].DomainSuffix = groupID
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *nodeYaml) AddNode(groupID string, nodeID string) error {
|
||||
var node nodeEntry
|
||||
|
||||
wwlog.Printf(wwlog.VERBOSE, "Adding new node: %s/%s\n", groupID, nodeID)
|
||||
|
||||
if _, ok := self.NodeGroups[groupID]; ok {
|
||||
if _, ok := self.NodeGroups[groupID].Nodes[nodeID]; ok {
|
||||
return errors.New("Nodename already exists in group: " + nodeID)
|
||||
}
|
||||
} else {
|
||||
return errors.New("Group does not exist: "+groupID)
|
||||
}
|
||||
|
||||
self.NodeGroups[groupID].Nodes[nodeID] = &node
|
||||
self.NodeGroups[groupID].Nodes[nodeID].Hostname = nodeID
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *nodeYaml) DelNode(groupID string, nodeID string) error {
|
||||
|
||||
if _, ok := self.NodeGroups[groupID]; ok {
|
||||
if _, ok := self.NodeGroups[groupID].Nodes[nodeID]; ok {
|
||||
delete(self.NodeGroups[groupID].Nodes, nodeID)
|
||||
wwlog.Printf(wwlog.VERBOSE, "Deleting node: %s/%s\n", groupID, nodeID)
|
||||
} else {
|
||||
return errors.New("Node '"+nodeID+"' was not found in group '"+groupID+"'")
|
||||
}
|
||||
} else {
|
||||
return errors.New("Group '"+groupID+"' was not found")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *nodeYaml) DelNodeNet(groupID string, nodeID string, netDev string) error {
|
||||
|
||||
if _, ok := self.NodeGroups[groupID]; ok {
|
||||
if _, ok := self.NodeGroups[groupID].Nodes[nodeID]; ok {
|
||||
if _, ok := self.NodeGroups[groupID].Nodes[nodeID].NetDevs[netDev]; ok {
|
||||
wwlog.Printf(wwlog.VERBOSE, "Deleting node network device: %s/%s:%s\n", groupID, nodeID, netDev)
|
||||
delete(self.NodeGroups[groupID].Nodes[nodeID].NetDevs, netDev)
|
||||
} else {
|
||||
return errors.New("Network device '"+netDev+"' was not found in node '"+groupID+"/"+nodeID+"'")
|
||||
}
|
||||
} else {
|
||||
return errors.New("Node '"+nodeID+"' was not found in group '"+groupID+"'")
|
||||
}
|
||||
} else {
|
||||
return errors.New("Group '"+groupID+"' was not found")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
func (self *nodeYaml) DelGroup(groupname string) error {
|
||||
if _, ok := self.NodeGroups[groupname]; ok {
|
||||
delete(self.NodeGroups, groupname)
|
||||
} else {
|
||||
return errors.New("Node group undefined: " + groupname)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *nodeYaml) SetGroupVal(groupID string, entry string, value string) error {
|
||||
if strings.ToUpper(value) == "UNDEF" || strings.ToUpper(value) == "NIL" || strings.ToUpper(value) == "DEL" {
|
||||
value = ""
|
||||
}
|
||||
|
||||
if _, ok := self.NodeGroups[groupID]; ok {
|
||||
wwlog.Printf(wwlog.VERBOSE, "Setting group %s to: %s = '%s'\n", groupID, entry, value )
|
||||
|
||||
switch strings.ToUpper(entry) {
|
||||
case "DOMAINSUFFIX":
|
||||
util.ValidateOrDie("Domain", entry, "^[a-zA-Z0-9-._]*$")
|
||||
self.NodeGroups[groupID].DomainSuffix = value
|
||||
}
|
||||
|
||||
} else {
|
||||
return errors.New("Group does not exist: " +groupID)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *nodeYaml) SetNodeVal(groupID string, nodeID string, entry string, value string) error {
|
||||
if strings.ToUpper(value) == "UNDEF" || strings.ToUpper(value) == "NIL" || strings.ToUpper(value) == "DEL" {
|
||||
value = ""
|
||||
}
|
||||
if _, ok := self.NodeGroups[groupID]; ok {
|
||||
if _, ok := self.NodeGroups[groupID].Nodes[nodeID]; ok {
|
||||
wwlog.Printf(wwlog.VERBOSE, "Setting node %s/%s to: %s = '%s'\n", groupID, nodeID, entry, value )
|
||||
|
||||
switch strings.ToUpper(entry) {
|
||||
case "VNFS":
|
||||
util.ValidateOrDie("VNFS", entry, "^[a-zA-Z0-9-._]*$")
|
||||
self.NodeGroups[groupID].Nodes[nodeID].Vnfs = value
|
||||
case "KERNEL":
|
||||
util.ValidateOrDie("Kernel Version", entry, "^[a-zA-Z0-9-._]*$")
|
||||
self.NodeGroups[groupID].Nodes[nodeID].KernelVersion = value
|
||||
case "DOMAINSUFFIX":
|
||||
util.ValidateOrDie("Domain", entry, "^[a-zA-Z0-9-._]*$")
|
||||
self.NodeGroups[groupID].Nodes[nodeID].DomainSuffix = value
|
||||
case "IPXE":
|
||||
util.ValidateOrDie("iPXE Template", entry, "^[a-zA-Z0-9-._]*$")
|
||||
self.NodeGroups[groupID].Nodes[nodeID].Ipxe = value
|
||||
case "HOSTNAME":
|
||||
util.ValidateOrDie("Hostname", entry, "^[a-zA-Z0-9-._]*$")
|
||||
self.NodeGroups[groupID].Nodes[nodeID].Hostname = value
|
||||
case "IPMIIPADDR":
|
||||
util.ValidateOrDie("IPMI IP Address", entry, "^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(\\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$")
|
||||
self.NodeGroups[groupID].Nodes[nodeID].IpmiIpaddr = value
|
||||
case "IPMIUSERNAME":
|
||||
util.ValidateOrDie("IPMI Username", entry, "^[a-zA-Z0-9-._]*$")
|
||||
self.NodeGroups[groupID].Nodes[nodeID].IpmiUserName = value
|
||||
case "IPMIPASSWORD":
|
||||
util.ValidateOrDie("IPMI Password", entry, "^[a-zA-Z0-9-._]*$")
|
||||
self.NodeGroups[groupID].Nodes[nodeID].IpmiPassword = value
|
||||
|
||||
}
|
||||
} else {
|
||||
return errors.New("Node does not exist: " +groupID+ "/" +nodeID)
|
||||
}
|
||||
} else {
|
||||
return errors.New("Group does not exist: " +groupID)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *nodeYaml) SetNodeNet(groupID string, nodeID string, netDev string, entry string, value string) error {
|
||||
if strings.ToUpper(value) == "UNDEF" || strings.ToUpper(value) == "NIL" || strings.ToUpper(value) == "DEL" {
|
||||
value = ""
|
||||
}
|
||||
|
||||
if _, ok := self.NodeGroups[groupID]; ok {
|
||||
if _, ok := self.NodeGroups[groupID].Nodes[nodeID]; ok {
|
||||
if _, ok := self.NodeGroups[groupID].Nodes[nodeID].NetDevs[netDev]; ok {
|
||||
wwlog.Printf(wwlog.VERBOSE, "Editing existing node NetDev entry for node: %s/%s\n", groupID, nodeID)
|
||||
} else {
|
||||
var nd NetDevs
|
||||
self.NodeGroups[groupID].Nodes[nodeID].NetDevs[netDev] = &nd
|
||||
}
|
||||
} else {
|
||||
return errors.New("Node does not exist: "+groupID+"/"+nodeID)
|
||||
}
|
||||
} else {
|
||||
return errors.New("Group does not exist: "+groupID)
|
||||
}
|
||||
|
||||
switch strings.ToUpper(entry) {
|
||||
case "IPADDR":
|
||||
util.ValidateOrDie("IP address", value, "^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(\\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$")
|
||||
self.NodeGroups[groupID].Nodes[nodeID].NetDevs[netDev].Ipaddr = value
|
||||
case "NETMASK":
|
||||
util.ValidateOrDie("Netmask", value, "^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(\\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$")
|
||||
self.NodeGroups[groupID].Nodes[nodeID].NetDevs[netDev].Netmask = value
|
||||
case "GATEWAY":
|
||||
util.ValidateOrDie("Gateway", value, "^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(\\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$")
|
||||
self.NodeGroups[groupID].Nodes[nodeID].NetDevs[netDev].Gateway = value
|
||||
case "TYPE":
|
||||
util.ValidateOrDie("Network device type", value, "^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(\\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$")
|
||||
self.NodeGroups[groupID].Nodes[nodeID].NetDevs[netDev].Type = value
|
||||
case "HWADDR":
|
||||
util.ValidateOrDie("HW address", value, "^([0-9A-Fa-f]{2}[:-]){5}([0-9A-Fa-f]{2})$")
|
||||
self.NodeGroups[groupID].Nodes[nodeID].NetDevs[netDev].Hwaddr = value
|
||||
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *nodeYaml) Persist() error {
|
||||
|
||||
out, err := yaml.Marshal(self)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
file, err := os.OpenFile(ConfigFile, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0644)
|
||||
if err != nil {
|
||||
wwlog.Printf(wwlog.ERROR, "%s\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
defer file.Close()
|
||||
|
||||
_, err = file.WriteString(string(out))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -1,377 +0,0 @@
|
||||
package node
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/hpcng/warewulf/internal/pkg/config"
|
||||
"github.com/hpcng/warewulf/internal/pkg/errors"
|
||||
"github.com/hpcng/warewulf/internal/pkg/vnfs"
|
||||
"github.com/hpcng/warewulf/internal/pkg/wwlog"
|
||||
"gopkg.in/yaml.v2"
|
||||
"io/ioutil"
|
||||
"regexp"
|
||||
)
|
||||
|
||||
const ConfigFile = "/etc/warewulf/nodes.conf"
|
||||
|
||||
func init() {
|
||||
//TODO: Check to make sure nodes.conf is found
|
||||
|
||||
}
|
||||
|
||||
type nodeYaml struct {
|
||||
Profiles map[string]*profileConfig
|
||||
NodeGroups map[string]*nodeGroup
|
||||
Hwaddrs map[string]NodeInfo
|
||||
}
|
||||
|
||||
type profileConfig struct {
|
||||
Vnfs string `yaml:"vnfs"`
|
||||
Ipxe string `yaml:"ipxe template,omitempty"`
|
||||
KernelVersion string `yaml:"kernel version"`
|
||||
KernelArgs string `yaml:"kernel args"`
|
||||
IpmiUserName string `yaml:"ipmi username,omitempty"`
|
||||
IpmiPassword string `yaml:"ipmi password,omitempty"`
|
||||
DomainSuffix string `yaml:"domain suffix,omitempty"`
|
||||
RuntimeOverlay []OverlayEntry `yaml:"runtime overlay files,omitempty"`
|
||||
SystemOverlay []OverlayEntry `yaml:"system overlay files,omitempty"`
|
||||
}
|
||||
|
||||
type OverlayEntry struct {
|
||||
Path string `yaml:"path,omitempty"`
|
||||
File bool `yaml:"file,omitempty"`
|
||||
Dir bool `yaml:"dir,omitempty"`
|
||||
Link bool `yaml:"link,omitempty"`
|
||||
Template bool `yaml:"template,omitempty"`
|
||||
Mode int32 `yaml:"mode,omitempty"`
|
||||
Owner string `yaml:"owner,omitempty"`
|
||||
Group string `yaml:"group,omitempty"`
|
||||
Source string `yaml:"source,omitempty"`
|
||||
Sources []string `yaml:"sources,omitempty"`
|
||||
}
|
||||
|
||||
type nodeGroup struct {
|
||||
Comment string
|
||||
DomainSuffix string `yaml:"domain suffix"`
|
||||
Profiles []string `yaml:"profiles"`
|
||||
Nodes map[string]*nodeEntry
|
||||
}
|
||||
|
||||
type nodeEntry struct {
|
||||
Hostname string `yaml:"hostname,omitempty"`
|
||||
Vnfs string `yaml:"vnfs"`
|
||||
Ipxe string `yaml:"ipxe template,omitempty"`
|
||||
KernelVersion string `yaml:"kernel version"`
|
||||
KernelArgs string `yaml:"kernel args"`
|
||||
IpmiUserName string `yaml:"ipmi username,omitempty"`
|
||||
IpmiPassword string `yaml:"ipmi password,omitempty"`
|
||||
DomainSuffix string `yaml:"domain suffix,omitempty"`
|
||||
IpmiIpaddr string `yaml:"ipmi ipaddr,omitempty"`
|
||||
Profiles []string `yaml:"profiles"`
|
||||
RuntimeOverlay []OverlayEntry `yaml:"system overlay files,omitempty"`
|
||||
SystemOverlay []OverlayEntry `yaml:"runtime overlay files,omitempty"`
|
||||
NetDevs map[string]*NetDevs
|
||||
}
|
||||
|
||||
type NetDevs struct {
|
||||
Type string `yaml:"type,omitempty"`
|
||||
Hwaddr string
|
||||
Ipaddr string
|
||||
Netmask string
|
||||
Gateway string `yaml:"gateway,omitempty"`
|
||||
}
|
||||
|
||||
type EntryInfo struct {
|
||||
Value string
|
||||
override string
|
||||
def string
|
||||
}
|
||||
|
||||
type NodeInfo struct {
|
||||
Id string
|
||||
Gid string
|
||||
Uid string
|
||||
GroupName string
|
||||
HostName string
|
||||
DomainName string
|
||||
Fqdn string
|
||||
Vnfs string
|
||||
VnfsRoot string
|
||||
Ipxe string
|
||||
KernelVersion string
|
||||
KernelArgs string
|
||||
IpmiIpaddr string
|
||||
IpmiUserName string
|
||||
IpmiPassword string
|
||||
Profiles []string
|
||||
RuntimeOverlay []OverlayEntry
|
||||
SystemOverlay []OverlayEntry
|
||||
NetDevs map[string]*NetDevs
|
||||
}
|
||||
|
||||
type GroupInfo struct {
|
||||
Id string
|
||||
GroupName string
|
||||
DomainName string
|
||||
Vnfs string
|
||||
Ipxe string
|
||||
SystemOverlay string
|
||||
RuntimeOverlay string
|
||||
KernelVersion string
|
||||
KernelArgs string
|
||||
IpmiUserName string
|
||||
IpmiPassword string
|
||||
}
|
||||
|
||||
|
||||
|
||||
func (i *EntryInfo) Default (value string) {
|
||||
if value == "" {
|
||||
return
|
||||
}
|
||||
i.def = value
|
||||
}
|
||||
|
||||
func (i *EntryInfo) Set (value string) {
|
||||
if value == "" {
|
||||
return
|
||||
}
|
||||
i.Value = value
|
||||
i.override = ""
|
||||
}
|
||||
|
||||
func (i *EntryInfo) Override (value string) {
|
||||
if value == "" {
|
||||
return
|
||||
}
|
||||
i.override = value
|
||||
}
|
||||
|
||||
func (i *EntryInfo) String () string {
|
||||
if i.override != "" {
|
||||
return i.override
|
||||
} else if i.Value != "" {
|
||||
return i.Value
|
||||
}
|
||||
return i.def
|
||||
}
|
||||
|
||||
func (i *EntryInfo) Defined () bool {
|
||||
if i.String() == "" {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func (i *EntryInfo) Fprint () string {
|
||||
if i.override != "" {
|
||||
return "["+ i.override +"]"
|
||||
} else if i.Value != "" {
|
||||
return i.Value
|
||||
} else if i.def != "" {
|
||||
return "("+ i.def +")"
|
||||
}
|
||||
return "--"
|
||||
}
|
||||
|
||||
func New() (nodeYaml, error) {
|
||||
var ret nodeYaml
|
||||
|
||||
wwlog.Printf(wwlog.DEBUG, "Opening node configuration file: %s\n", ConfigFile)
|
||||
data, err := ioutil.ReadFile(ConfigFile)
|
||||
if err != nil {
|
||||
fmt.Printf("error reading node configuration file\n")
|
||||
return ret, err
|
||||
}
|
||||
|
||||
err = yaml.Unmarshal(data, &ret)
|
||||
if err != nil {
|
||||
return ret, err
|
||||
}
|
||||
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
|
||||
func (self *nodeYaml) FindAllGroups() ([]GroupInfo, error) {
|
||||
var ret []GroupInfo
|
||||
|
||||
for groupname, group := range self.NodeGroups {
|
||||
var g GroupInfo
|
||||
|
||||
g.Id = groupname
|
||||
g.GroupName = groupname
|
||||
g.DomainName = group.DomainSuffix
|
||||
|
||||
// TODO: Validate or die on all inputs
|
||||
|
||||
ret = append(ret, g)
|
||||
}
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
|
||||
func (self *nodeYaml) FindAllNodes() ([]NodeInfo, error) {
|
||||
var ret []NodeInfo
|
||||
|
||||
for groupname, group := range self.NodeGroups {
|
||||
for nodename, node := range group.Nodes {
|
||||
var n NodeInfo
|
||||
|
||||
n.Id = nodename
|
||||
n.Gid = groupname
|
||||
n.GroupName = groupname
|
||||
n.HostName = node.Hostname
|
||||
n.Profiles = node.Profiles
|
||||
n.IpmiIpaddr = node.IpmiIpaddr
|
||||
|
||||
if len(n.Profiles) == 0 {
|
||||
n.Profiles = append(n.Profiles, "default")
|
||||
}
|
||||
|
||||
for _, p := range n.Profiles {
|
||||
if _, ok := self.Profiles[p]; ok {
|
||||
} else {
|
||||
continue
|
||||
}
|
||||
if self.Profiles[p].Vnfs != "" {
|
||||
n.Vnfs = self.Profiles[p].Vnfs
|
||||
}
|
||||
if self.Profiles[p].KernelVersion != "" {
|
||||
n.KernelVersion = self.Profiles[p].KernelVersion
|
||||
}
|
||||
if self.Profiles[p].KernelArgs != "" {
|
||||
n.KernelArgs = self.Profiles[p].KernelArgs
|
||||
}
|
||||
if self.Profiles[p].Ipxe != "" {
|
||||
n.Ipxe = self.Profiles[p].Ipxe
|
||||
}
|
||||
if self.Profiles[p].IpmiUserName != "" {
|
||||
n.IpmiUserName = self.Profiles[p].IpmiUserName
|
||||
}
|
||||
if self.Profiles[p].IpmiPassword != "" {
|
||||
n.IpmiPassword = self.Profiles[p].IpmiPassword
|
||||
}
|
||||
if self.Profiles[p].DomainSuffix != "" {
|
||||
n.DomainName = self.Profiles[p].DomainSuffix
|
||||
}
|
||||
|
||||
for _, ro := range self.Profiles[p].RuntimeOverlay {
|
||||
n.RuntimeOverlay = append(n.RuntimeOverlay, ro)
|
||||
}
|
||||
for _, so := range self.Profiles[p].SystemOverlay {
|
||||
n.SystemOverlay = append(n.SystemOverlay, so)
|
||||
}
|
||||
}
|
||||
|
||||
if node.DomainSuffix != "" {
|
||||
n.DomainName = node.DomainSuffix
|
||||
} else if group.DomainSuffix != "" {
|
||||
n.DomainName = group.DomainSuffix
|
||||
}
|
||||
if node.Vnfs != "" {
|
||||
n.Vnfs = node.Vnfs
|
||||
}
|
||||
if node.KernelVersion != "" {
|
||||
n.KernelVersion = node.KernelVersion
|
||||
}
|
||||
if node.KernelArgs != "" {
|
||||
n.KernelArgs = node.KernelArgs
|
||||
}
|
||||
if node.Ipxe != "" {
|
||||
n.Ipxe = node.Ipxe
|
||||
}
|
||||
if node.IpmiUserName != "" {
|
||||
n.IpmiUserName = node.IpmiUserName
|
||||
}
|
||||
if node.IpmiPassword != "" {
|
||||
n.IpmiPassword = node.IpmiPassword
|
||||
}
|
||||
|
||||
if n.Ipxe == "" {
|
||||
n.Ipxe = "default"
|
||||
}
|
||||
if n.KernelArgs == "" {
|
||||
n.KernelArgs = "crashkernel=no quiet"
|
||||
}
|
||||
|
||||
config := config.New()
|
||||
n.VnfsRoot = config.VnfsChroot(vnfs.CleanName(n.Vnfs))
|
||||
|
||||
if n.DomainName != "" {
|
||||
n.Fqdn = node.Hostname + "." + n.DomainName
|
||||
} else {
|
||||
n.Fqdn = node.Hostname
|
||||
}
|
||||
|
||||
n.NetDevs = node.NetDevs
|
||||
|
||||
ret = append(ret, n)
|
||||
}
|
||||
}
|
||||
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
func (self *nodeYaml) FindByHwaddr(hwa string) (NodeInfo, error) {
|
||||
var ret NodeInfo
|
||||
|
||||
n, _ := self.FindAllNodes()
|
||||
|
||||
for _, node := range n {
|
||||
for _, dev := range node.NetDevs {
|
||||
if dev.Hwaddr == hwa {
|
||||
return node, nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ret, errors.New("No nodes found with HW Addr: " + hwa)
|
||||
}
|
||||
|
||||
func (self *nodeYaml) FindByIpaddr(ipaddr string) (NodeInfo, error) {
|
||||
var ret NodeInfo
|
||||
|
||||
n, _ := self.FindAllNodes()
|
||||
|
||||
for _, node := range n {
|
||||
for _, dev := range node.NetDevs {
|
||||
if dev.Ipaddr == ipaddr {
|
||||
return node, nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ret, errors.New("No nodes found with IP Addr: " + ipaddr)
|
||||
}
|
||||
|
||||
func (nodes *nodeYaml) SearchByName(search string) ([]NodeInfo, error) {
|
||||
var ret []NodeInfo
|
||||
|
||||
n, _ := nodes.FindAllNodes()
|
||||
|
||||
for _, node := range n {
|
||||
b, _ := regexp.MatchString(search, node.Fqdn)
|
||||
if b == true {
|
||||
ret = append(ret, node)
|
||||
}
|
||||
}
|
||||
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
func (nodes *nodeYaml) SearchByNameList(searchList []string) ([]NodeInfo, error) {
|
||||
var ret []NodeInfo
|
||||
|
||||
n, _ := nodes.FindAllNodes()
|
||||
|
||||
for _, search := range searchList {
|
||||
for _, node := range n {
|
||||
b, _ := regexp.MatchString(search, node.Fqdn)
|
||||
if b == true {
|
||||
ret = append(ret, node)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ret, nil
|
||||
}
|
||||
Reference in New Issue
Block a user