From ca7e4506c608310c51af1a0c9236eea8b16e089d Mon Sep 17 00:00:00 2001 From: Markus Vahlenkamp Date: Thu, 5 Dec 2024 15:20:39 +0100 Subject: [PATCH] Store information about NodeGeneration in registry. (#1347) * Store information about NodeGeneration in registry. So far generate.go contained two lists indenpendent from the nodes, that would describe nodes that (1) can be generated and (b) what the interface naming convention would be for the node kind. This will introduce seperate fields in the NodeRegistry for this information, such that the information for this sort of node generation can be defined as part of the node definition * use utils func to create topo file on generate * format * typo * added missing platforms * rename Credentials->GetCredentials * align node registration func * use native interface names * use getter --------- Co-authored-by: Roman Dodin --- clab/config/utils.go | 2 +- clab/inventory.go | 4 +- clab/sshconfig.go | 2 +- cmd/generate.go | 147 ++++-------------- cmd/tools_veth.go | 2 +- nodes/bridge/bridge.go | 12 +- nodes/c8000/c8000.go | 3 +- nodes/ceos/ceos.go | 7 +- .../checkpoint_cloudguard.go | 3 +- nodes/crpd/crpd.go | 13 +- nodes/dell_sonic/dell_sonic.go | 11 +- nodes/fortinet_fortigate/fortigate.go | 11 +- nodes/generic_vm/generic_vm.go | 9 +- nodes/huawei_vrp/huawei_vrp.go | 8 +- nodes/iol/iol.go | 12 +- nodes/ipinfusion_ocnos/ipinfusion_ocnos.go | 7 +- nodes/linux/linux.go | 10 +- nodes/node_registry.go | 88 ++++++++++- nodes/rare/rare.go | 14 +- nodes/sonic/sonic.go | 14 +- nodes/sonic_vm/sonic_vm.go | 12 +- nodes/srl/srl.go | 15 +- nodes/vr_aoscx/vr-aoscx.go | 7 +- nodes/vr_c8000v/vr-c8000v.go | 12 +- nodes/vr_cat9kv/vr-cat9kv.go | 12 +- nodes/vr_csr/vr-csr.go | 3 +- nodes/vr_freebsd/vr-freebsd.go | 12 +- nodes/vr_ftdv/vr-ftdv.go | 14 +- nodes/vr_ftosv/vr-ftosv.go | 3 +- nodes/vr_n9kv/vr-n9kv.go | 3 +- nodes/vr_openbsd/vr-openbsd.go | 12 +- nodes/vr_pan/vr-pan.go | 3 +- nodes/vr_ros/vr-ros.go | 3 +- nodes/vr_sros/vr-sros.go | 11 +- nodes/vr_veos/vr-veos.go | 12 +- nodes/vr_vjunosevolved/vr-vjunosevolved.go | 12 +- nodes/vr_vjunosswitch/vr-vjunosswitch.go | 12 +- nodes/vr_vmx/vr-vmx.go | 12 +- nodes/vr_vqfx/vr-vqfx.go | 11 +- nodes/vr_vsrx/vr-vsrx.go | 12 +- nodes/vr_xrv/vr-xrv.go | 3 +- nodes/vr_xrv9k/vr-xrv9k.go | 11 +- nodes/xrd/xrd.go | 12 +- 43 files changed, 379 insertions(+), 219 deletions(-) diff --git a/clab/config/utils.go b/clab/config/utils.go index 23421b9b1..3fe3d8463 100644 --- a/clab/config/utils.go +++ b/clab/config/utils.go @@ -64,7 +64,7 @@ func PrepareVars(c *clab.CLab) map[string]*NodeConfig { vars[vkRole] = nodeCfg.Kind } - creds := c.Reg.Kind(nodeCfg.Kind).Credentials().Slice() + creds := c.Reg.Kind(nodeCfg.Kind).GetCredentials().Slice() res[name] = &NodeConfig{ TargetNode: nodeCfg, diff --git a/clab/inventory.go b/clab/inventory.go index ec55db1c0..520c1d5c7 100644 --- a/clab/inventory.go +++ b/clab/inventory.go @@ -81,8 +81,8 @@ func (c *CLab) generateAnsibleInventory(w io.Writer) error { // assumption is that all nodes of the same kind have the same credentials nodeRegEntry := c.Reg.Kind(n.Config().Kind) if nodeRegEntry != nil { - kindProps.Username = nodeRegEntry.Credentials().GetUsername() - kindProps.Password = nodeRegEntry.Credentials().GetPassword() + kindProps.Username = nodeRegEntry.GetCredentials().GetUsername() + kindProps.Password = nodeRegEntry.GetCredentials().GetPassword() } // add network_os to the node diff --git a/clab/sshconfig.go b/clab/sshconfig.go index 763aa76a7..dad79232d 100644 --- a/clab/sshconfig.go +++ b/clab/sshconfig.go @@ -68,7 +68,7 @@ func (c *CLab) addSSHConfig() error { NodeRegistryEntry := c.Reg.Kind(n.Config().Kind) nodeData := SSHConfigNodeTmpl{ Name: n.Config().LongName, - Username: NodeRegistryEntry.Credentials().GetUsername(), + Username: NodeRegistryEntry.GetCredentials().GetUsername(), SSHConfig: n.GetSSHConfig(), } diff --git a/cmd/generate.go b/cmd/generate.go index d30e4a076..99821ff98 100644 --- a/cmd/generate.go +++ b/cmd/generate.go @@ -8,7 +8,6 @@ import ( "errors" "fmt" "net" - "os" "strconv" "strings" @@ -16,113 +15,13 @@ import ( "github.com/spf13/cobra" "github.com/srl-labs/containerlab/clab" "github.com/srl-labs/containerlab/links" - "github.com/srl-labs/containerlab/nodes/ceos" - "github.com/srl-labs/containerlab/nodes/crpd" - "github.com/srl-labs/containerlab/nodes/rare" - "github.com/srl-labs/containerlab/nodes/sonic" - "github.com/srl-labs/containerlab/nodes/srl" - "github.com/srl-labs/containerlab/nodes/vr_sros" - "github.com/srl-labs/containerlab/nodes/vr_veos" - "github.com/srl-labs/containerlab/nodes/vr_vjunosevolved" - "github.com/srl-labs/containerlab/nodes/vr_vjunosswitch" - "github.com/srl-labs/containerlab/nodes/vr_vmx" - "github.com/srl-labs/containerlab/nodes/vr_vqfx" - "github.com/srl-labs/containerlab/nodes/vr_vsrx" - "github.com/srl-labs/containerlab/nodes/vr_xrv9k" - "github.com/srl-labs/containerlab/nodes/xrd" + "github.com/srl-labs/containerlab/nodes" "github.com/srl-labs/containerlab/types" + "github.com/srl-labs/containerlab/utils" "gopkg.in/yaml.v2" ) -func buildInterfaceFormatMap() map[string]string { - m := make(map[string]string) - - // Add SR Linux kinds - for _, k := range srl.KindNames { - m[k] = "e1-%d" - } - - // Add Arista cEOS kinds - for _, k := range ceos.KindNames { - m[k] = "eth%d" - } - - // Add Arista vEOS kinds - for _, k := range vr_veos.KindNames { - m[k] = "Et1/%d" - } - - // Add Nokia SR OS kinds - for _, k := range vr_sros.KindNames { - m[k] = "1/1/%d" - } - - // Add Juniper cRPD - for _, k := range crpd.KindNames { - m[k] = "eth%d" - } - - // Add Juniper VMX kinds - for _, k := range vr_vmx.KindNames { - m[k] = "ge-0/0/%d" - } - - // Add Juniper vSRX kinds - for _, k := range vr_vsrx.KindNames { - m[k] = "ge-0/0/%d" - } - - // Add Juniper vQFX kinds - for _, k := range vr_vqfx.KindNames { - m[k] = "ge-0/0/%d" - } - - // Add Juniper vJunos-Switch/Router - for _, k := range vr_vjunosswitch.KindNames { - m[k] = "et-0/0/%d" - } - - // Add Juniper vJunos-Evolved - for _, k := range vr_vjunosevolved.KindNames { - m[k] = "et-0/0/%d" - } - - // Add Cisco XRv9k kinds - for _, k := range vr_xrv9k.KindNames { - m[k] = "Gi0/0/0/%d" - } - - // Add Cisco XRd - for _, k := range xrd.KindNames { - m[k] = "eth%d" - } - - // Add RARE FreeRtr - for _, k := range rare.KindNames { - m[k] = "eth%d" - } - - // Add SONiC VS - for _, k := range sonic.KindNames { - m[k] = "eth%d" - } - - m["linux"] = "eth%d" - m["bridge"] = "veth%d" - - return m -} - -var interfaceFormat = buildInterfaceFormatMap() - -var supportedKinds = []string{ - "srl", "ceos", "linux", "bridge", "sonic-vs", "crpd", "vr-sros", "vr-vmx", "vr-vsrx", - "vr-vqfx", "juniper_vjunosevolved", "juniper_vjunosrouter", "juniper_vjunosswitch", "vr-xrv9k", "vr-veos", - "xrd", "rare", "openbsd", "cisco_ftdv", "freebsd", -} - const ( - defaultSRLType = srl.SRLinuxDefaultType defaultNodePrefix = "node" defaultGroupPrefix = "tier" ) @@ -141,6 +40,7 @@ var ( groupPrefix string file string deploy bool + reg *nodes.NodeRegistry ) type nodesDef struct { @@ -183,7 +83,7 @@ var generateCmd = &cobra.Command{ } log.Debugf("generated topo: %s", string(b)) if file != "" { - err = saveTopoFile(file, b) + err = utils.CreateFile(file, string(b)) if err != nil { return err } @@ -192,7 +92,7 @@ var generateCmd = &cobra.Command{ reconfigure = true if file == "" { file = fmt.Sprintf("%s.clab.yml", name) - err = saveTopoFile(file, b) + err = utils.CreateFile(file, string(b)) if err != nil { return err } @@ -208,6 +108,22 @@ var generateCmd = &cobra.Command{ } func init() { + c := &clab.CLab{} + c.Reg = nodes.NewNodeRegistry() + c.RegisterNodes() + + reg = c.Reg + + generateNodesAttributes := reg.GetGenerateNodeAttributes() + supportedKinds := []string{} + + // prepare list of generateable node kinds + for k, v := range generateNodesAttributes { + if v.IsGenerateable() { + supportedKinds = append(supportedKinds, k) + } + } + rootCmd.AddCommand(generateCmd) generateCmd.Flags().StringVarP(&mgmtNetName, "network", "", "", "management network name") generateCmd.Flags().IPNetVarP(&mgmtIPv4Subnet, "ipv4-subnet", "4", net.IPNet{}, "management network IPv4 subnet range") @@ -271,6 +187,9 @@ func generateTopologyConfig(name, network, ipv4range, ipv6range string, } } } + + generateNodesAttributes := reg.GetGenerateNodeAttributes() + for i := 0; i < numStages-1; i++ { interfaceOffset := uint(0) if i > 0 { @@ -299,9 +218,9 @@ func generateTopologyConfig(name, network, ipv4range, ipv6range string, l := &links.LinkVEthRaw{ Endpoints: []*links.EndpointRaw{ links.NewEndpointRaw(node1, fmt.Sprintf( - interfaceFormat[nodes[i].kind], k+1+interfaceOffset), ""), + generateNodesAttributes[nodes[i].kind].GetInterfaceFormat(), k+1+interfaceOffset), ""), links.NewEndpointRaw(node2, fmt.Sprintf( - interfaceFormat[nodes[i+1].kind], j+1), ""), + generateNodesAttributes[nodes[i+1].kind].GetInterfaceFormat(), j+1), ""), }, } @@ -401,17 +320,3 @@ func parseNodesFlag(kind string, nodes ...string) ([]nodesDef, error) { } return result, nil } - -func saveTopoFile(path string, data []byte) error { - f, err := os.OpenFile(path, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, 0666) // skipcq: GSC-G302 - if err != nil { - return err - } - - _, err = f.Write(data) - if err != nil { - return err - } - - return f.Close() -} diff --git a/cmd/tools_veth.go b/cmd/tools_veth.go index 9086b5019..5576a6ff2 100644 --- a/cmd/tools_veth.go +++ b/cmd/tools_veth.go @@ -200,7 +200,7 @@ func parseVethEndpoint(s string) (parsedEndpoint, error) { case 3: if _, ok := utils.StringInSlice([]string{"ovs-bridge", "bridge"}, arr[0]); !ok { - return ep, fmt.Errorf("node type %s is not supported, supported nodes are %q", arr[0], supportedKinds) + return ep, fmt.Errorf("only bride and ovs-bridge can be used as a first block in the link definition. Got: %s", arr[0]) } switch arr[0] { diff --git a/nodes/bridge/bridge.go b/nodes/bridge/bridge.go index 5a057673b..5b9fbb1ee 100644 --- a/nodes/bridge/bridge.go +++ b/nodes/bridge/bridge.go @@ -23,18 +23,24 @@ import ( "github.com/vishvananda/netlink" ) -var kindnames = []string{"bridge"} +var kindNames = []string{"bridge"} const ( iptCheckCmd = "-vL FORWARD -w 5" iptAllowCmd = "-I FORWARD -i %s -j ACCEPT -w 5" + + generateable = true + generateIfFormat = "eth%d" ) // Register registers the node in the NodeRegistry. func Register(r *nodes.NodeRegistry) { - r.Register(kindnames, func() nodes.Node { + generateNodeAttributes := nodes.NewGenerateNodeAttributes(generateable, generateIfFormat) + nrea := nodes.NewNodeRegistryEntryAttributes(nil, generateNodeAttributes) + + r.Register(kindNames, func() nodes.Node { return new(bridge) - }, nil) + }, nrea) } type bridge struct { diff --git a/nodes/c8000/c8000.go b/nodes/c8000/c8000.go index 55adcbdf1..3f1874f4a 100644 --- a/nodes/c8000/c8000.go +++ b/nodes/c8000/c8000.go @@ -33,9 +33,10 @@ const ( // Register registers the node in the NodeRegistry. func Register(r *nodes.NodeRegistry) { + nrea := nodes.NewNodeRegistryEntryAttributes(defaultCredentials, nil) r.Register(kindnames, func() nodes.Node { return new(c8000) - }, defaultCredentials) + }, nrea) } type c8000 struct { diff --git a/nodes/ceos/ceos.go b/nodes/ceos/ceos.go index 760045b90..be91e3a03 100644 --- a/nodes/ceos/ceos.go +++ b/nodes/ceos/ceos.go @@ -26,6 +26,8 @@ import ( const ( ifWaitScriptContainerPath = "/mnt/flash/if-wait.sh" + generateable = true + generateIfFormat = "eth%d" ) var ( @@ -52,9 +54,12 @@ var ( // Register registers the node in the NodeRegistry. func Register(r *nodes.NodeRegistry) { + generateNodeAttributes := nodes.NewGenerateNodeAttributes(generateable, generateIfFormat) + nrea := nodes.NewNodeRegistryEntryAttributes(defaultCredentials, generateNodeAttributes) + r.Register(KindNames, func() nodes.Node { return new(ceos) - }, defaultCredentials) + }, nrea) } type ceos struct { diff --git a/nodes/checkpoint_cloudguard/checkpoint_cloudguard.go b/nodes/checkpoint_cloudguard/checkpoint_cloudguard.go index 89fe699af..4d0225d16 100644 --- a/nodes/checkpoint_cloudguard/checkpoint_cloudguard.go +++ b/nodes/checkpoint_cloudguard/checkpoint_cloudguard.go @@ -20,9 +20,10 @@ var ( // Register registers the node in the NodeRegistry. func Register(r *nodes.NodeRegistry) { + nrea := nodes.NewNodeRegistryEntryAttributes(defaultCredentials, nil) r.Register(kindnames, func() nodes.Node { return new(CheckpointCloudguard) - }, defaultCredentials) + }, nrea) } type CheckpointCloudguard struct { diff --git a/nodes/crpd/crpd.go b/nodes/crpd/crpd.go index daa692dfa..887d48823 100644 --- a/nodes/crpd/crpd.go +++ b/nodes/crpd/crpd.go @@ -20,13 +20,17 @@ import ( ) const ( + // licDir is the directory where Junos 22+ expects to find the license file. licDir = "/config/license" licFile = "license.lic" + + generateable = true + generateIfFormat = "eth%d" ) var ( - KindNames = []string{"crpd", "juniper_crpd"} + kindNames = []string{"crpd", "juniper_crpd"} //go:embed crpd.cfg defaultCfgTemplate string @@ -41,9 +45,12 @@ var ( // Register registers the node in the NodeRegistry. func Register(r *nodes.NodeRegistry) { - r.Register(KindNames, func() nodes.Node { + generateNodeAttributes := nodes.NewGenerateNodeAttributes(generateable, generateIfFormat) + nrea := nodes.NewNodeRegistryEntryAttributes(defaultCredentials, generateNodeAttributes) + + r.Register(kindNames, func() nodes.Node { return new(crpd) - }, defaultCredentials) + }, nrea) } type crpd struct { diff --git a/nodes/dell_sonic/dell_sonic.go b/nodes/dell_sonic/dell_sonic.go index 4b932f463..cd3a5f342 100644 --- a/nodes/dell_sonic/dell_sonic.go +++ b/nodes/dell_sonic/dell_sonic.go @@ -17,8 +17,10 @@ import ( ) var ( - kindnames = []string{"dell_sonic"} + kindNames = []string{"dell_sonic"} defaultCredentials = nodes.NewCredentials("admin", "admin") + generateable = true + generateIfFormat = "eth%d" ) const ( @@ -29,9 +31,12 @@ const ( // Register registers the node in the NodeRegistry. func Register(r *nodes.NodeRegistry) { - r.Register(kindnames, func() nodes.Node { + generateNodeAttributes := nodes.NewGenerateNodeAttributes(generateable, generateIfFormat) + nrea := nodes.NewNodeRegistryEntryAttributes(defaultCredentials, generateNodeAttributes) + + r.Register(kindNames, func() nodes.Node { return new(dell_sonic) - }, defaultCredentials) + }, nrea) } type dell_sonic struct { diff --git a/nodes/fortinet_fortigate/fortigate.go b/nodes/fortinet_fortigate/fortigate.go index fac8a613b..aa1d031ea 100644 --- a/nodes/fortinet_fortigate/fortigate.go +++ b/nodes/fortinet_fortigate/fortigate.go @@ -27,15 +27,20 @@ var ( const ( // scrapligo doesn't have a driver for fortigate, can be copied from scrapli community // scrapliPlatformName = "fortinet_fortigate". - configDirName = "config" - startupCfgFName = "startup-config.cfg" + configDirName = "config" + startupCfgFName = "startup-config.cfg" + generateable = true + generateIfFormat = "eth%d" ) // Register registers the node in the NodeRegistry. func Register(r *nodes.NodeRegistry) { + generateNodeAttributes := nodes.NewGenerateNodeAttributes(generateable, generateIfFormat) + nrea := nodes.NewNodeRegistryEntryAttributes(defaultCredentials, generateNodeAttributes) + r.Register(kindnames, func() nodes.Node { return new(fortigate) - }, defaultCredentials) + }, nrea) } type fortigate struct { diff --git a/nodes/generic_vm/generic_vm.go b/nodes/generic_vm/generic_vm.go index 75b17a7bd..e3d1663ea 100644 --- a/nodes/generic_vm/generic_vm.go +++ b/nodes/generic_vm/generic_vm.go @@ -20,14 +20,19 @@ var ( ) const ( - configDirName = "config" + configDirName = "config" + generateable = true + generateIfFormat = "eth%d" ) // Register registers the node in the NodeRegistry. func Register(r *nodes.NodeRegistry) { + generateNodeAttributes := nodes.NewGenerateNodeAttributes(generateable, generateIfFormat) + nrea := nodes.NewNodeRegistryEntryAttributes(defaultCredentials, generateNodeAttributes) + r.Register(kindnames, func() nodes.Node { return new(genericVM) - }, defaultCredentials) + }, nrea) } type genericVM struct { diff --git a/nodes/huawei_vrp/huawei_vrp.go b/nodes/huawei_vrp/huawei_vrp.go index 69741fc46..b88e43420 100644 --- a/nodes/huawei_vrp/huawei_vrp.go +++ b/nodes/huawei_vrp/huawei_vrp.go @@ -26,13 +26,19 @@ const ( configDirName = "config" startupCfgFName = "startup-config.cfg" + + generateable = true + generateIfFormat = "eth%d" ) // Register registers the node in the NodeRegistry. func Register(r *nodes.NodeRegistry) { + generateNodeAttributes := nodes.NewGenerateNodeAttributes(generateable, generateIfFormat) + nrea := nodes.NewNodeRegistryEntryAttributes(defaultCredentials, generateNodeAttributes) + r.Register(kindnames, func() nodes.Node { return new(huawei_vrp) - }, defaultCredentials) + }, nrea) } type huawei_vrp struct { diff --git a/nodes/iol/iol.go b/nodes/iol/iol.go index 4b38f4a64..84ac0f888 100644 --- a/nodes/iol/iol.go +++ b/nodes/iol/iol.go @@ -30,10 +30,13 @@ const ( typeL2 = "l2" iol_workdir = "/iol" + + generateable = true + generateIfFormat = "eth%d" ) var ( - kindnames = []string{"cisco_iol"} + kindNames = []string{"cisco_iol"} defaultCredentials = nodes.NewCredentials("admin", "admin") //go:embed iol.cfg.tmpl @@ -51,9 +54,12 @@ var ( // Register registers the node in the NodeRegistry. func Register(r *nodes.NodeRegistry) { - r.Register(kindnames, func() nodes.Node { + generateNodeAttributes := nodes.NewGenerateNodeAttributes(generateable, generateIfFormat) + nrea := nodes.NewNodeRegistryEntryAttributes(defaultCredentials, generateNodeAttributes) + + r.Register(kindNames, func() nodes.Node { return new(iol) - }, defaultCredentials) + }, nrea) } type iol struct { diff --git a/nodes/ipinfusion_ocnos/ipinfusion_ocnos.go b/nodes/ipinfusion_ocnos/ipinfusion_ocnos.go index b02a30fa8..ff83c3cf2 100644 --- a/nodes/ipinfusion_ocnos/ipinfusion_ocnos.go +++ b/nodes/ipinfusion_ocnos/ipinfusion_ocnos.go @@ -22,13 +22,18 @@ var ( const ( scrapliPlatformName = "ipinfusion_ocnos" + generateable = false + generateIfFormat = "" ) // Register registers the node in the NodeRegistry. func Register(r *nodes.NodeRegistry) { + generateNodeAttributes := nodes.NewGenerateNodeAttributes(generateable, generateIfFormat) + nrea := nodes.NewNodeRegistryEntryAttributes(defaultCredentials, generateNodeAttributes) + r.Register(kindnames, func() nodes.Node { return new(IPInfusionOcNOS) - }, defaultCredentials) + }, nrea) } type IPInfusionOcNOS struct { diff --git a/nodes/linux/linux.go b/nodes/linux/linux.go index 85009f783..d1f4336de 100644 --- a/nodes/linux/linux.go +++ b/nodes/linux/linux.go @@ -19,13 +19,21 @@ import ( "github.com/weaveworks/ignite/pkg/operations" ) +const ( + generateable = true + generateIfFormat = "eth%d" +) + var kindnames = []string{"linux"} // Register registers the node in the NodeRegistry. func Register(r *nodes.NodeRegistry) { + generateNodeAttributes := nodes.NewGenerateNodeAttributes(generateable, generateIfFormat) + nrea := nodes.NewNodeRegistryEntryAttributes(nil, generateNodeAttributes) + r.Register(kindnames, func() nodes.Node { return new(linux) - }, nil) + }, nrea) } type linux struct { diff --git a/nodes/node_registry.go b/nodes/node_registry.go index 0f2359028..f46ba1d43 100644 --- a/nodes/node_registry.go +++ b/nodes/node_registry.go @@ -21,8 +21,8 @@ func NewNodeRegistry() *NodeRegistry { } // Register registers the node' init function for all provided names. -func (r *NodeRegistry) Register(names []string, initf Initializer, credentials *Credentials) error { - newEntry := newRegistryEntry(names, initf, credentials) +func (r *NodeRegistry) Register(names []string, initf Initializer, attributes *NodeRegistryEntryAttributes) error { + newEntry := newRegistryEntry(names, initf, attributes) return r.addEntry(newEntry) } @@ -63,6 +63,14 @@ func (r *NodeRegistry) GetRegisteredNodeKindNames() []string { return result } +func (r *NodeRegistry) GetGenerateNodeAttributes() map[string]*GenerateNodeAttributes { + result := map[string]*GenerateNodeAttributes{} + for k, v := range r.nodeIndex { + result[k] = v.GetGenerateAttributes() + } + return result +} + func (r *NodeRegistry) Kind(kind string) *NodeRegistryEntry { return r.nodeIndex[kind] } @@ -70,11 +78,27 @@ func (r *NodeRegistry) Kind(kind string) *NodeRegistryEntry { type NodeRegistryEntry struct { nodeKindNames []string initFunction Initializer - credentials *Credentials + attributes *NodeRegistryEntryAttributes +} + +func (nre *NodeRegistryEntry) GetCredentials() *Credentials { + if nre.attributes == nil { + return nil + } + + return nre.attributes.GetCredentials() +} + +func (nre *NodeRegistryEntry) GetGenerateAttributes() *GenerateNodeAttributes { + if nre.attributes == nil { + return nil + } + return nre.attributes.generateAttributes } // Credentials returns entry's credentials. -func (e *NodeRegistryEntry) Credentials() *Credentials { +// might return nil if no default credentials present. +func (e *NodeRegistryEntryAttributes) Credentials() *Credentials { if e == nil { return nil } @@ -82,12 +106,64 @@ func (e *NodeRegistryEntry) Credentials() *Credentials { return e.credentials } -func newRegistryEntry(nodeKindNames []string, initFunction Initializer, credentials *Credentials) *NodeRegistryEntry { +func newRegistryEntry(nodeKindNames []string, initFunction Initializer, + attributes *NodeRegistryEntryAttributes, +) *NodeRegistryEntry { return &NodeRegistryEntry{ nodeKindNames: nodeKindNames, initFunction: initFunction, - credentials: credentials, + attributes: attributes, + } +} + +type NodeRegistryEntryAttributes struct { + credentials *Credentials + generateAttributes *GenerateNodeAttributes +} + +func NewNodeRegistryEntryAttributes(c *Credentials, ga *GenerateNodeAttributes) *NodeRegistryEntryAttributes { + // set default value for GenerateNodeAttributes + if ga == nil { + ga = NewGenerateNodeAttributes(false, "") + } + return &NodeRegistryEntryAttributes{ + credentials: c, + generateAttributes: ga, + } +} + +func (nrea *NodeRegistryEntryAttributes) GetCredentials() *Credentials { + return nrea.credentials +} + +func (nrea *NodeRegistryEntryAttributes) GetGenerateAttributes() *GenerateNodeAttributes { + return nrea.generateAttributes +} + +type GenerateNodeAttributes struct { + generateable bool + interfaceFormat string +} + +func NewGenerateNodeAttributes(generateable bool, ifFormat string) *GenerateNodeAttributes { + return &GenerateNodeAttributes{ + generateable: generateable, + interfaceFormat: ifFormat, + } +} + +func (ga *GenerateNodeAttributes) IsGenerateable() bool { + if ga == nil { + return false + } + return ga.generateable +} + +func (ga *GenerateNodeAttributes) GetInterfaceFormat() string { + if ga == nil { + return "" } + return ga.interfaceFormat } // Credentials defines NOS SSH credentials. diff --git a/nodes/rare/rare.go b/nodes/rare/rare.go index ba8a8cc30..bbf2b8d62 100644 --- a/nodes/rare/rare.go +++ b/nodes/rare/rare.go @@ -14,13 +14,21 @@ import ( "github.com/srl-labs/containerlab/utils" ) -var KindNames = []string{"rare"} +var kindNames = []string{"rare"} + +const ( + generateable = true + generateIfFormat = "eth%d" +) // Register registers the node in the NodeRegistry. func Register(r *nodes.NodeRegistry) { - r.Register(KindNames, func() nodes.Node { + generateNodeAttributes := nodes.NewGenerateNodeAttributes(generateable, generateIfFormat) + nrea := nodes.NewNodeRegistryEntryAttributes(nil, generateNodeAttributes) + + r.Register(kindNames, func() nodes.Node { return new(rare) - }, nil) + }, nrea) } type rare struct { diff --git a/nodes/sonic/sonic.go b/nodes/sonic/sonic.go index b0a4d75f3..799d1c110 100644 --- a/nodes/sonic/sonic.go +++ b/nodes/sonic/sonic.go @@ -15,13 +15,21 @@ import ( "github.com/srl-labs/containerlab/utils" ) -var KindNames = []string{"sonic-vs"} +const ( + generateable = true + generateIfFormat = "eth%d" +) + +var kindNames = []string{"sonic-vs"} // Register registers the node in the NodeRegistry. func Register(r *nodes.NodeRegistry) { - r.Register(KindNames, func() nodes.Node { + generateNodeAttributes := nodes.NewGenerateNodeAttributes(generateable, generateIfFormat) + nrea := nodes.NewNodeRegistryEntryAttributes(nil, generateNodeAttributes) + + r.Register(kindNames, func() nodes.Node { return new(sonic) - }, nil) + }, nrea) } type sonic struct { diff --git a/nodes/sonic_vm/sonic_vm.go b/nodes/sonic_vm/sonic_vm.go index 638b42fde..a320161b0 100644 --- a/nodes/sonic_vm/sonic_vm.go +++ b/nodes/sonic_vm/sonic_vm.go @@ -19,8 +19,11 @@ import ( ) var ( - kindnames = []string{"sonic-vm"} + kindNames = []string{"sonic-vm"} defaultCredentials = nodes.NewCredentials("admin", "admin") + + generateable = true + generateIfFormat = "eth%d" ) const ( @@ -31,9 +34,12 @@ const ( // Register registers the node in the NodeRegistry. func Register(r *nodes.NodeRegistry) { - r.Register(kindnames, func() nodes.Node { + generateNodeAttributes := nodes.NewGenerateNodeAttributes(generateable, generateIfFormat) + nrea := nodes.NewNodeRegistryEntryAttributes(defaultCredentials, generateNodeAttributes) + + r.Register(kindNames, func() nodes.Node { return new(sonic_vm) - }, defaultCredentials) + }, nrea) } type sonic_vm struct { diff --git a/nodes/srl/srl.go b/nodes/srl/srl.go index df84c90fd..96cf28f56 100644 --- a/nodes/srl/srl.go +++ b/nodes/srl/srl.go @@ -36,7 +36,11 @@ const ( SRLinuxDefaultType = "ixrd2l" // default srl node type readyTimeout = time.Minute * 5 // max wait time for node to boot - retryTimer = time.Second + + generateable = true + generateIfFormat = "e1-%d" + + retryTimer = time.Second // defaultCfgPath is a path to a file with default config that clab adds on top of the factory config. // Default config is a config that adds some basic configuration to the node, such as tls certs, gnmi/json-rpc, login-banner. @@ -52,7 +56,7 @@ var ( //go:embed srl_default_config.go.tpl srlConfigCmdsTpl string - KindNames = []string{"srl", "nokia_srlinux"} + kindNames = []string{"srl", "nokia_srlinux"} srlSysctl = map[string]string{ "net.ipv4.ip_forward": "0", "net.ipv6.conf.all.disable_ipv6": "0", @@ -111,9 +115,12 @@ var ( // Register registers the node in the NodeRegistry. func Register(r *nodes.NodeRegistry) { - r.Register(KindNames, func() nodes.Node { + generateNodeAttributes := nodes.NewGenerateNodeAttributes(generateable, generateIfFormat) + nrea := nodes.NewNodeRegistryEntryAttributes(defaultCredentials, generateNodeAttributes) + + r.Register(kindNames, func() nodes.Node { return new(srl) - }, defaultCredentials) + }, nrea) } type srl struct { diff --git a/nodes/vr_aoscx/vr-aoscx.go b/nodes/vr_aoscx/vr-aoscx.go index 2de14a74a..f97b6ce9e 100644 --- a/nodes/vr_aoscx/vr-aoscx.go +++ b/nodes/vr_aoscx/vr-aoscx.go @@ -12,7 +12,7 @@ import ( ) var ( - kindnames = []string{"aruba_aoscx", "vr-aoscx", "vr-aruba_aoscx"} + kindNames = []string{"aruba_aoscx", "vr-aoscx", "vr-aruba_aoscx"} defaultCredentials = nodes.NewCredentials("admin", "admin") InterfaceRegexp = regexp.MustCompile(`1/1/(?P\d+)`) @@ -27,9 +27,10 @@ const ( // Register registers the node in the NodeRegistry. func Register(r *nodes.NodeRegistry) { - r.Register(kindnames, func() nodes.Node { + nrea := nodes.NewNodeRegistryEntryAttributes(defaultCredentials, nil) + r.Register(kindNames, func() nodes.Node { return new(vrAosCX) - }, defaultCredentials) + }, nrea) } type vrAosCX struct { diff --git a/nodes/vr_c8000v/vr-c8000v.go b/nodes/vr_c8000v/vr-c8000v.go index f39f3b104..1bc516289 100644 --- a/nodes/vr_c8000v/vr-c8000v.go +++ b/nodes/vr_c8000v/vr-c8000v.go @@ -18,7 +18,7 @@ import ( ) var ( - kindnames = []string{"cisco_c8000v"} + kindNames = []string{"cisco_c8000v"} defaultCredentials = nodes.NewCredentials("admin", "admin") InterfaceRegexp = regexp.MustCompile(`(?:Gi|GigabitEthernet)\s?(?P\d+)$`) @@ -31,13 +31,19 @@ const ( configDirName = "config" startupCfgFName = "startup-config.cfg" + + generateable = true + generateIfFormat = "eth%d" ) // Register registers the node in the NodeRegistry. func Register(r *nodes.NodeRegistry) { - r.Register(kindnames, func() nodes.Node { + generateNodeAttributes := nodes.NewGenerateNodeAttributes(generateable, generateIfFormat) + nrea := nodes.NewNodeRegistryEntryAttributes(defaultCredentials, generateNodeAttributes) + + r.Register(kindNames, func() nodes.Node { return new(vrC8000v) - }, defaultCredentials) + }, nrea) } type vrC8000v struct { diff --git a/nodes/vr_cat9kv/vr-cat9kv.go b/nodes/vr_cat9kv/vr-cat9kv.go index 7d44ebb6f..c453bde81 100644 --- a/nodes/vr_cat9kv/vr-cat9kv.go +++ b/nodes/vr_cat9kv/vr-cat9kv.go @@ -18,7 +18,7 @@ import ( ) var ( - kindnames = []string{"cisco_cat9kv"} + kindNames = []string{"cisco_cat9kv"} defaultCredentials = nodes.NewCredentials("admin", "admin") InterfaceRegexp = regexp.MustCompile(`(?:Gi|GigabitEthernet)\s?1/0/(?P\d+)$`) @@ -31,13 +31,19 @@ const ( configDirName = "config" startupCfgFName = "startup-config.cfg" + + generateable = true + generateIfFormat = "eth%d" ) // Register registers the node in the NodeRegistry. func Register(r *nodes.NodeRegistry) { - r.Register(kindnames, func() nodes.Node { + generateNodeAttributes := nodes.NewGenerateNodeAttributes(generateable, generateIfFormat) + nrea := nodes.NewNodeRegistryEntryAttributes(defaultCredentials, generateNodeAttributes) + + r.Register(kindNames, func() nodes.Node { return new(vrCat9kv) - }, defaultCredentials) + }, nrea) } type vrCat9kv struct { diff --git a/nodes/vr_csr/vr-csr.go b/nodes/vr_csr/vr-csr.go index bffb2b5eb..e569413ff 100644 --- a/nodes/vr_csr/vr-csr.go +++ b/nodes/vr_csr/vr-csr.go @@ -35,9 +35,10 @@ const ( // Register registers the node in the NodeRegistry. func Register(r *nodes.NodeRegistry) { + nrea := nodes.NewNodeRegistryEntryAttributes(defaultCredentials, nil) r.Register(kindnames, func() nodes.Node { return new(vrCsr) - }, defaultCredentials) + }, nrea) } type vrCsr struct { diff --git a/nodes/vr_freebsd/vr-freebsd.go b/nodes/vr_freebsd/vr-freebsd.go index 0d5ab8e4b..4b6d5251a 100644 --- a/nodes/vr_freebsd/vr-freebsd.go +++ b/nodes/vr_freebsd/vr-freebsd.go @@ -18,7 +18,7 @@ import ( ) var ( - kindnames = []string{"freebsd"} + kindNames = []string{"freebsd"} defaultCredentials = nodes.NewCredentials("admin", "admin") saveCmd = "sh -c \"/backup.sh -u $USERNAME -p $PASSWORD backup\"" InterfaceRegexp = regexp.MustCompile(`vtnet(?P\d+)`) @@ -28,13 +28,19 @@ var ( const ( configDirName = "config" + + generateable = true + generateIfFormat = "eth%d" ) // Register registers the node in the NodeRegistry. func Register(r *nodes.NodeRegistry) { - r.Register(kindnames, func() nodes.Node { + generateNodeAttributes := nodes.NewGenerateNodeAttributes(generateable, generateIfFormat) + nrea := nodes.NewNodeRegistryEntryAttributes(defaultCredentials, generateNodeAttributes) + + r.Register(kindNames, func() nodes.Node { return new(vrFreeBSD) - }, defaultCredentials) + }, nrea) } type vrFreeBSD struct { diff --git a/nodes/vr_ftdv/vr-ftdv.go b/nodes/vr_ftdv/vr-ftdv.go index 2cf416c7e..23edc48ea 100644 --- a/nodes/vr_ftdv/vr-ftdv.go +++ b/nodes/vr_ftdv/vr-ftdv.go @@ -15,7 +15,7 @@ import ( ) var ( - kindnames = []string{"cisco_ftdv"} + kindNames = []string{"cisco_ftdv"} defaultCredentials = nodes.NewCredentials("admin", "Admin@123") InterfaceRegexp = regexp.MustCompile(`(?:GigabitEthernet|Gi)\s?0/(?P\d+)`) @@ -23,11 +23,19 @@ var ( InterfaceHelp = "GigabitEthernet0/X or Gi0/X (where X >= 0) or ethX (where X >= 1)" ) +const ( + generateable = true + generateIfFormat = "eth%d" +) + // Register registers the node in the NodeRegistry. func Register(r *nodes.NodeRegistry) { - r.Register(kindnames, func() nodes.Node { + generateNodeAttributes := nodes.NewGenerateNodeAttributes(generateable, generateIfFormat) + nrea := nodes.NewNodeRegistryEntryAttributes(defaultCredentials, generateNodeAttributes) + + r.Register(kindNames, func() nodes.Node { return new(vrFtdv) - }, defaultCredentials) + }, nrea) } type vrFtdv struct { diff --git a/nodes/vr_ftosv/vr-ftosv.go b/nodes/vr_ftosv/vr-ftosv.go index 21f586aeb..35ccc5408 100644 --- a/nodes/vr_ftosv/vr-ftosv.go +++ b/nodes/vr_ftosv/vr-ftosv.go @@ -26,9 +26,10 @@ const ( // Register registers the node in the NodeRegistry. func Register(r *nodes.NodeRegistry) { + nrea := nodes.NewNodeRegistryEntryAttributes(defaultCredentials, nil) r.Register(kindnames, func() nodes.Node { return new(vrFtosv) - }, defaultCredentials) + }, nrea) } type vrFtosv struct { diff --git a/nodes/vr_n9kv/vr-n9kv.go b/nodes/vr_n9kv/vr-n9kv.go index ac54aa307..5a76fd561 100644 --- a/nodes/vr_n9kv/vr-n9kv.go +++ b/nodes/vr_n9kv/vr-n9kv.go @@ -32,9 +32,10 @@ const ( // Register registers the node in the NodeRegistry. func Register(r *nodes.NodeRegistry) { + nrea := nodes.NewNodeRegistryEntryAttributes(defaultCredentials, nil) r.Register(kindnames, func() nodes.Node { return new(vrN9kv) - }, defaultCredentials) + }, nrea) } type vrN9kv struct { diff --git a/nodes/vr_openbsd/vr-openbsd.go b/nodes/vr_openbsd/vr-openbsd.go index 442c9c35c..b8f025d68 100644 --- a/nodes/vr_openbsd/vr-openbsd.go +++ b/nodes/vr_openbsd/vr-openbsd.go @@ -18,7 +18,7 @@ import ( ) var ( - kindnames = []string{"openbsd"} + kindNames = []string{"openbsd"} defaultCredentials = nodes.NewCredentials("admin", "admin") saveCmd = "sh -c \"/backup.sh -u $USERNAME -p $PASSWORD backup\"" @@ -29,13 +29,19 @@ var ( const ( configDirName = "config" + + generateable = true + generateIfFormat = "eth%d" ) // Register registers the node in the NodeRegistry. func Register(r *nodes.NodeRegistry) { - r.Register(kindnames, func() nodes.Node { + generateNodeAttributes := nodes.NewGenerateNodeAttributes(generateable, generateIfFormat) + nrea := nodes.NewNodeRegistryEntryAttributes(defaultCredentials, generateNodeAttributes) + + r.Register(kindNames, func() nodes.Node { return new(vrOpenBSD) - }, defaultCredentials) + }, nrea) } type vrOpenBSD struct { diff --git a/nodes/vr_pan/vr-pan.go b/nodes/vr_pan/vr-pan.go index 25b73f095..e25679835 100644 --- a/nodes/vr_pan/vr-pan.go +++ b/nodes/vr_pan/vr-pan.go @@ -31,9 +31,10 @@ const ( // Register registers the node in the NodeRegistry. func Register(r *nodes.NodeRegistry) { + nrea := nodes.NewNodeRegistryEntryAttributes(defaultCredentials, nil) r.Register(kindnames, func() nodes.Node { return new(vrPan) - }, defaultCredentials) + }, nrea) } type vrPan struct { diff --git a/nodes/vr_ros/vr-ros.go b/nodes/vr_ros/vr-ros.go index 6e0a07535..71ec7cedb 100644 --- a/nodes/vr_ros/vr-ros.go +++ b/nodes/vr_ros/vr-ros.go @@ -31,9 +31,10 @@ const ( // Register registers the node in the NodeRegistry. func Register(r *nodes.NodeRegistry) { + nrea := nodes.NewNodeRegistryEntryAttributes(defaultCredentials, nil) r.Register(kindnames, func() nodes.Node { return new(vrRos) - }, defaultCredentials) + }, nrea) } type vrRos struct { diff --git a/nodes/vr_sros/vr-sros.go b/nodes/vr_sros/vr-sros.go index 14c058678..255846150 100644 --- a/nodes/vr_sros/vr-sros.go +++ b/nodes/vr_sros/vr-sros.go @@ -32,7 +32,7 @@ import ( ) var ( - KindNames = []string{"nokia_sros", "vr-sros", "vr-nokia_sros"} + kindNames = []string{"nokia_sros", "vr-sros", "vr-nokia_sros"} defaultCredentials = nodes.NewCredentials("admin", "admin") InterfaceRegexp = regexp.MustCompile(`1/1/(?P\d+)`) @@ -41,6 +41,9 @@ var ( ) const ( + generateable = true + generateIfFormat = "1/1/%d" + vrsrosDefaultType = "sr-1" scrapliPlatformName = "nokia_sros" configDirName = "tftpboot" @@ -56,9 +59,11 @@ type SROSTemplateData struct { // Register registers the node in the NodeRegistry. func Register(r *nodes.NodeRegistry) { - r.Register(KindNames, func() nodes.Node { + generateNodeAttributes := nodes.NewGenerateNodeAttributes(generateable, generateIfFormat) + nrea := nodes.NewNodeRegistryEntryAttributes(defaultCredentials, generateNodeAttributes) + r.Register(kindNames, func() nodes.Node { return new(vrSROS) - }, defaultCredentials) + }, nrea) } type vrSROS struct { diff --git a/nodes/vr_veos/vr-veos.go b/nodes/vr_veos/vr-veos.go index b0c9b638f..bcb4354c0 100644 --- a/nodes/vr_veos/vr-veos.go +++ b/nodes/vr_veos/vr-veos.go @@ -18,7 +18,7 @@ import ( ) var ( - KindNames = []string{"arista_veos", "vr-veos", "vr-arista_veos"} + kindNames = []string{"arista_veos", "vr-veos", "vr-arista_veos"} defaultCredentials = nodes.NewCredentials("admin", "admin") InterfaceRegexp = regexp.MustCompile(`(?:Et|Ethernet)1/(?P\d+)`) @@ -27,6 +27,9 @@ var ( ) const ( + generateable = true + generateIfFormat = "Et1/%d" + scrapliPlatformName = "arista_eos" configDirName = "config" @@ -35,9 +38,12 @@ const ( // Register registers the node in the NodeRegistry. func Register(r *nodes.NodeRegistry) { - r.Register(KindNames, func() nodes.Node { + generateNodeAttributes := nodes.NewGenerateNodeAttributes(generateable, generateIfFormat) + nrea := nodes.NewNodeRegistryEntryAttributes(defaultCredentials, generateNodeAttributes) + + r.Register(kindNames, func() nodes.Node { return new(vrVEOS) - }, defaultCredentials) + }, nrea) } type vrVEOS struct { diff --git a/nodes/vr_vjunosevolved/vr-vjunosevolved.go b/nodes/vr_vjunosevolved/vr-vjunosevolved.go index 16a1a0487..63b729280 100644 --- a/nodes/vr_vjunosevolved/vr-vjunosevolved.go +++ b/nodes/vr_vjunosevolved/vr-vjunosevolved.go @@ -18,7 +18,7 @@ import ( ) var ( - KindNames = []string{"juniper_vjunosevolved"} + kindNames = []string{"juniper_vjunosevolved"} defaultCredentials = nodes.NewCredentials("admin", "admin@123") InterfaceRegexp = regexp.MustCompile(`(?:et|xe|ge)-0/0/(?P\d+)$`) @@ -31,13 +31,19 @@ const ( configDirName = "config" startupCfgFName = "startup-config.cfg" + + generateable = true + generateIfFormat = "et-0/0/%d" ) // Register registers the node in the NodeRegistry. func Register(r *nodes.NodeRegistry) { - r.Register(KindNames, func() nodes.Node { + generateNodeAttributes := nodes.NewGenerateNodeAttributes(generateable, generateIfFormat) + nrea := nodes.NewNodeRegistryEntryAttributes(defaultCredentials, generateNodeAttributes) + + r.Register(kindNames, func() nodes.Node { return new(vrVJUNOSEVOLVED) - }, defaultCredentials) + }, nrea) } type vrVJUNOSEVOLVED struct { diff --git a/nodes/vr_vjunosswitch/vr-vjunosswitch.go b/nodes/vr_vjunosswitch/vr-vjunosswitch.go index ee3ce843f..f28985473 100644 --- a/nodes/vr_vjunosswitch/vr-vjunosswitch.go +++ b/nodes/vr_vjunosswitch/vr-vjunosswitch.go @@ -18,7 +18,7 @@ import ( ) var ( - KindNames = []string{"juniper_vjunosrouter", "juniper_vjunosswitch"} + kindNames = []string{"juniper_vjunosrouter", "juniper_vjunosswitch"} defaultCredentials = nodes.NewCredentials("admin", "admin@123") InterfaceRegexp = regexp.MustCompile(`(?:et|xe|ge)-0/0/(?P\d+)$`) @@ -31,13 +31,19 @@ const ( configDirName = "config" startupCfgFName = "startup-config.cfg" + + generateable = true + generateIfFormat = "et-0/0/%d" ) // Register registers the node in the NodeRegistry. func Register(r *nodes.NodeRegistry) { - r.Register(KindNames, func() nodes.Node { + generateNodeAttributes := nodes.NewGenerateNodeAttributes(generateable, generateIfFormat) + nrea := nodes.NewNodeRegistryEntryAttributes(defaultCredentials, generateNodeAttributes) + + r.Register(kindNames, func() nodes.Node { return new(vrVJUNOSSWITCH) - }, defaultCredentials) + }, nrea) } type vrVJUNOSSWITCH struct { diff --git a/nodes/vr_vmx/vr-vmx.go b/nodes/vr_vmx/vr-vmx.go index dff7a16c3..19b7882dd 100644 --- a/nodes/vr_vmx/vr-vmx.go +++ b/nodes/vr_vmx/vr-vmx.go @@ -18,7 +18,7 @@ import ( ) var ( - KindNames = []string{"juniper_vmx", "vr-vmx", "vr-juniper_vmx"} + kindNames = []string{"juniper_vmx", "vr-vmx", "vr-juniper_vmx"} defaultCredentials = nodes.NewCredentials("admin", "admin@123") InterfaceRegexp = regexp.MustCompile(`(?:et|xe|ge)-0/0/(?P\d+)$`) @@ -27,6 +27,9 @@ var ( ) const ( + generateable = true + generateIfFormat = "ge-0/0/%d" + configDirName = "config" startupCfgFName = "startup-config.cfg" @@ -35,9 +38,12 @@ const ( // Register registers the node in the NodeRegistry. func Register(r *nodes.NodeRegistry) { - r.Register(KindNames, func() nodes.Node { + generateNodeAttributes := nodes.NewGenerateNodeAttributes(generateable, generateIfFormat) + nrea := nodes.NewNodeRegistryEntryAttributes(defaultCredentials, generateNodeAttributes) + + r.Register(kindNames, func() nodes.Node { return new(vrVMX) - }, defaultCredentials) + }, nrea) } type vrVMX struct { diff --git a/nodes/vr_vqfx/vr-vqfx.go b/nodes/vr_vqfx/vr-vqfx.go index 72b5f83d6..6f93952f5 100644 --- a/nodes/vr_vqfx/vr-vqfx.go +++ b/nodes/vr_vqfx/vr-vqfx.go @@ -18,7 +18,7 @@ import ( ) var ( - KindNames = []string{"juniper_vqfx", "vr-vqfx", "vr-juniper_vqfx"} + kindNames = []string{"juniper_vqfx", "vr-vqfx", "vr-juniper_vqfx"} defaultCredentials = nodes.NewCredentials("admin", "admin@123") InterfaceRegexp = regexp.MustCompile(`(?:et|xe|ge)-0/0/(?P\d+)$`) @@ -27,6 +27,9 @@ var ( ) const ( + generateable = true + generateIfFormat = "ge-0/0/%d" + scrapliPlatformName = "juniper_junos" configDirName = "config" @@ -35,9 +38,11 @@ const ( // Register registers the node in the NodeRegistry. func Register(r *nodes.NodeRegistry) { - r.Register(KindNames, func() nodes.Node { + generateNodeAttributes := nodes.NewGenerateNodeAttributes(generateable, generateIfFormat) + nrea := nodes.NewNodeRegistryEntryAttributes(defaultCredentials, generateNodeAttributes) + r.Register(kindNames, func() nodes.Node { return new(vrVQFX) - }, defaultCredentials) + }, nrea) } type vrVQFX struct { diff --git a/nodes/vr_vsrx/vr-vsrx.go b/nodes/vr_vsrx/vr-vsrx.go index 2db628acb..2cc450dd2 100644 --- a/nodes/vr_vsrx/vr-vsrx.go +++ b/nodes/vr_vsrx/vr-vsrx.go @@ -18,7 +18,7 @@ import ( ) var ( - KindNames = []string{"juniper_vsrx", "vr-vsrx", "vr-juniper_vsrx"} + kindNames = []string{"juniper_vsrx", "vr-vsrx", "vr-juniper_vsrx"} defaultCredentials = nodes.NewCredentials("admin", "admin@123") InterfaceRegexp = regexp.MustCompile(`(?:et|xe|ge)-0/0/(?P\d+)$`) @@ -27,6 +27,9 @@ var ( ) const ( + generateable = true + generateIfFormat = "ge-0/0/%d" + scrapliPlatformName = "juniper_junos" configDirName = "config" @@ -35,9 +38,12 @@ const ( // Register registers the node in the NodeRegistry. func Register(r *nodes.NodeRegistry) { - r.Register(KindNames, func() nodes.Node { + generateNodeAttributes := nodes.NewGenerateNodeAttributes(generateable, generateIfFormat) + nrea := nodes.NewNodeRegistryEntryAttributes(defaultCredentials, generateNodeAttributes) + + r.Register(kindNames, func() nodes.Node { return new(vrVSRX) - }, defaultCredentials) + }, nrea) } type vrVSRX struct { diff --git a/nodes/vr_xrv/vr-xrv.go b/nodes/vr_xrv/vr-xrv.go index 0ee948e69..3d5184ed7 100644 --- a/nodes/vr_xrv/vr-xrv.go +++ b/nodes/vr_xrv/vr-xrv.go @@ -34,9 +34,10 @@ const ( // Register registers the node in the NodeRegistry. func Register(r *nodes.NodeRegistry) { + nrea := nodes.NewNodeRegistryEntryAttributes(defaultCredentials, nil) r.Register(kindnames, func() nodes.Node { return new(vrXRV) - }, defaultCredentials) + }, nrea) } type vrXRV struct { diff --git a/nodes/vr_xrv9k/vr-xrv9k.go b/nodes/vr_xrv9k/vr-xrv9k.go index 12df76d77..d187dc458 100644 --- a/nodes/vr_xrv9k/vr-xrv9k.go +++ b/nodes/vr_xrv9k/vr-xrv9k.go @@ -18,7 +18,7 @@ import ( ) var ( - KindNames = []string{"cisco_xrv9k", "vr-xrv9k", "vr-cisco_xrv9k"} + kindNames = []string{"cisco_xrv9k", "vr-xrv9k", "vr-cisco_xrv9k"} defaultCredentials = nodes.NewCredentials("clab", "clab@123") InterfaceRegexp = regexp.MustCompile(`(?:Gi|GigabitEthernet|Te|TenGigE|TenGigabitEthernet)\s?0/0/0/(?P\d+)`) @@ -27,6 +27,9 @@ var ( ) const ( + generateable = true + generateIfFormat = "Gi0/0/0/%d" + scrapliPlatformName = "cisco_iosxr" configDirName = "config" @@ -35,9 +38,11 @@ const ( // Register registers the node in the NodeRegistry. func Register(r *nodes.NodeRegistry) { - r.Register(KindNames, func() nodes.Node { + generateNodeAttributes := nodes.NewGenerateNodeAttributes(generateable, generateIfFormat) + nrea := nodes.NewNodeRegistryEntryAttributes(defaultCredentials, generateNodeAttributes) + r.Register(kindNames, func() nodes.Node { return new(vrXRV9K) - }, defaultCredentials) + }, nrea) } type vrXRV9K struct { diff --git a/nodes/xrd/xrd.go b/nodes/xrd/xrd.go index caf9fdb30..3e92d326d 100644 --- a/nodes/xrd/xrd.go +++ b/nodes/xrd/xrd.go @@ -25,7 +25,7 @@ import ( ) var ( - KindNames = []string{"xrd", "cisco_xrd"} + kindNames = []string{"xrd", "cisco_xrd"} defaultCredentials = nodes.NewCredentials("clab", "clab@123") xrdEnv = map[string]string{ "XR_FIRST_BOOT_CONFIG": "/etc/xrd/first-boot.cfg", @@ -44,14 +44,20 @@ var ( ) const ( + generateable = true + generateIfFormat = "eth%d" + scrapliPlatformName = "cisco_iosxr" ) // Register registers the node in the NodeRegistry. func Register(r *nodes.NodeRegistry) { - r.Register(KindNames, func() nodes.Node { + generateNodeAttributes := nodes.NewGenerateNodeAttributes(generateable, generateIfFormat) + nrea := nodes.NewNodeRegistryEntryAttributes(defaultCredentials, generateNodeAttributes) + + r.Register(kindNames, func() nodes.Node { return new(xrd) - }, defaultCredentials) + }, nrea) } type xrd struct {