Skip to content

Commit

Permalink
cleanup, rework labels init and add basic tests
Browse files Browse the repository at this point in the history
  • Loading branch information
karimra committed Jun 18, 2021
1 parent a00ed40 commit 1588730
Show file tree
Hide file tree
Showing 15 changed files with 188 additions and 111 deletions.
3 changes: 0 additions & 3 deletions clab/ceos.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,9 +61,7 @@ func initCeosNode(c *CLab, nodeDef *types.NodeDefinition, nodeCfg *types.NodeCon
if err != nil {
return err
}
// nodeCfg.Image = c.imageInitialization(nodeDef, nodeCfg.Kind)
nodeCfg.Image = c.Config.Topology.GetNodeImage(nodeCfg.ShortName)
// nodeCfg.Position = c.positionInitialization(nodeDef, nodeCfg.Kind)
nodeCfg.Position = c.Config.Topology.GetNodePosition(nodeCfg.ShortName)

// initialize specific container information
Expand All @@ -90,7 +88,6 @@ func initCeosNode(c *CLab, nodeDef *types.NodeDefinition, nodeCfg *types.NodeCon
nodeCfg.Cmd = envSb.String()

nodeCfg.User = user
// nodeCfg.Group = c.groupInitialization(nodeDef, nodeCfg.Kind)
nodeCfg.Group = c.Config.Topology.GetNodeGroup(nodeCfg.ShortName)
nodeCfg.NodeType = nodeDef.Type

Expand Down
77 changes: 31 additions & 46 deletions clab/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,10 @@ import (
"context"
"fmt"
"os"
"path"
"path/filepath"
"runtime"
"sort"
"strings"
"syscall"

Expand Down Expand Up @@ -111,12 +113,15 @@ func (c *CLab) ParseTopology() error {
c.Links = make(map[int]*types.Link)

// initialize the Node information from the topology map
idx := 0
for nodeName, node := range c.Config.Topology.Nodes {
if err := c.NewNode(nodeName, node, idx); err != nil {
nodeNames := make([]string, 0, len(c.Config.Topology.Nodes))
for nodeName := range c.Config.Topology.Nodes {
nodeNames = append(nodeNames, nodeName)
}
sort.Strings(nodeNames)
for idx, nodeName := range nodeNames {
if err := c.NewNode(nodeName, c.Config.Topology.Nodes[nodeName], idx); err != nil {
return err
}
idx++
}
for i, l := range c.Config.Topology.Links {
// i represents the endpoint integer and l provide the link struct
Expand All @@ -125,69 +130,43 @@ func (c *CLab) ParseTopology() error {
return nil
}

// initialize container labels
func (c *CLab) labelsInit(nodeDef *types.NodeDefinition, kind string, node *types.NodeConfig) map[string]string {
defaultLabels := map[string]string{
"containerlab": c.Config.Name,
"clab-node-name": node.ShortName,
"clab-node-kind": kind,
"clab-node-type": node.NodeType,
"clab-node-group": node.Group,
"clab-node-lab-dir": node.LabDir,
"clab-topo-file": c.TopoFile.path,
}
// merge global labels into kind envs
m := utils.MergeStringMaps(c.Config.Topology.GetDefaults().GetLabels(), c.Config.Topology.GetKind(kind).GetLabels())
// merge result of previous merge into node envs
m2 := utils.MergeStringMaps(m, nodeDef.GetLabels())
// merge with default labels
return utils.MergeStringMaps(m2, defaultLabels)
}

// NewNode initializes a new node object
func (c *CLab) NewNode(nodeName string, nodeDef *types.NodeDefinition, idx int) error {
// initialize a new node
nodeCfg := new(types.NodeConfig)
nodeCfg.ShortName = nodeName
nodeCfg.LongName = prefix + "-" + c.Config.Name + "-" + nodeName
nodeCfg.Fqdn = nodeName + "." + c.Config.Name + ".io"
nodeCfg.LabDir = c.Dir.Lab + "/" + nodeName
nodeCfg.Index = idx
nodeCfg.Endpoints = []*types.Endpoint{}

nodeCfg.NetworkMode = strings.ToLower(nodeDef.NetworkMode)

nodeCfg.MgmtIPv4Address = nodeDef.MgmtIPv4
nodeCfg.MgmtIPv6Address = nodeDef.MgmtIPv6
// initialize a new node configuration
nodeCfg := &types.NodeConfig{
ShortName: nodeName,
LongName: strings.Join([]string{prefix, c.Config.Name, nodeName}, "-"),
Fqdn: strings.Join([]string{nodeName, c.Config.Name, ".io"}, "."),
LabDir: path.Join(c.Dir.Lab, nodeName),
Index: idx,
Endpoints: make([]*types.Endpoint, 0),
NetworkMode: strings.ToLower(nodeDef.GetNetworkMode()),
MgmtIPv4Address: nodeDef.GetMgmtIPv4(),
MgmtIPv6Address: nodeDef.GetMgmtIPv6(),
}

// initialize the node with global parameters
// Kind initialization is either coming from `topology.nodes` section or from `topology.defaults`
// normalize the data to lower case to compare
nodeCfg.Kind = strings.ToLower(c.Config.Topology.GetNodeKind(nodeName))

// initialize bind mounts
// binds := c.bindsInit(nodeDef)
binds := c.Config.Topology.GetNodeBinds(nodeName)
err := resolveBindPaths(binds, nodeCfg.LabDir)
if err != nil {
return err
}
nodeCfg.Binds = binds

//ps, pb, err := c.portsInit(nodeDef)
nodeCfg.PortSet, nodeCfg.PortBindings, err = c.Config.Topology.GetNodePorts(nodeName)
if err != nil {
return err
}

// initialize passed env variables which will be merged with kind specific ones
// envs := c.envInit(nodeDef, nodeCfg.Kind)
envs := c.Config.Topology.GetNodeEnv(nodeName)

// user := c.userInit(nodeDef, nodeCfg.Kind)
user := c.Config.Topology.GetNodeUser(nodeName)

// nodeCfg.Publish = c.publishInit(nodeDef, nodeCfg.Kind)
nodeCfg.Publish = c.Config.Topology.GetNodePublish(nodeName)
switch nodeCfg.Kind {
case "ceos":
Expand Down Expand Up @@ -253,18 +232,24 @@ func (c *CLab) NewNode(nodeName string, nodeDef *types.NodeDefinition, idx int)
}

case "bridge", "ovs-bridge":
// nodeCfg.Group = c.groupInitialization(nodeDef, nodeCfg.Kind)
nodeCfg.Group = c.Config.Topology.GetNodeGroup(nodeCfg.ShortName)
// nodeCfg.Position = c.positionInitialization(nodeDef, nodeCfg.Kind)
nodeCfg.Position = c.Config.Topology.GetNodePosition(nodeCfg.ShortName)

default:
return fmt.Errorf("node '%s' refers to a kind '%s' which is not supported. Supported kinds are %q", nodeName, nodeCfg.Kind, kinds)
}

// init labels after all node kinds are processed
nodeCfg.Labels = c.labelsInit(nodeDef, nodeCfg.Kind, nodeCfg)
// nodeCfg.Labels = c.Config.Topology.GetNodeLabels(nodeName)
nodeCfg.Labels = c.Config.Topology.GetNodeLabels(nodeName)
nodeCfg.Labels = utils.MergeStringMaps(nodeCfg.Labels, map[string]string{
"containerlab": c.Config.Name,
"clab-node-name": nodeCfg.ShortName,
"clab-node-kind": nodeCfg.Kind,
"clab-node-type": nodeCfg.NodeType,
"clab-node-group": nodeCfg.Group,
"clab-node-lab-dir": nodeCfg.LabDir,
"clab-topo-file": c.TopoFile.path,
})
c.Nodes[nodeName] = nodeCfg
return nil
}
Expand Down
28 changes: 11 additions & 17 deletions clab/crpd.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,26 +16,20 @@ import (
func initCrpdNode(c *CLab, nodeDef *types.NodeDefinition, nodeCfg *types.NodeConfig, user string, envs map[string]string) error {
var err error

// node.Config, err = c.configInit(nodeCfg, node.Kind)
c.Config.Topology.GetNodeConfig(nodeCfg.ShortName)
if err != nil {
return err
}
// nodeCfg.Image = c.imageInitialization(nodeDef, nodeCfg.Kind)
nodeCfg.Image = c.Config.Topology.GetNodeImage(nodeCfg.ShortName)
// nodeCfg.Group = c.groupInitialization(nodeDef, nodeCfg.Kind)
nodeCfg.Group = c.Config.Topology.GetNodeGroup(nodeCfg.ShortName)
// nodeCfg.Position = c.positionInitialization(nodeDef, nodeCfg.Kind)
nodeCfg.Position = c.Config.Topology.GetNodePosition(nodeCfg.ShortName)
nodeCfg.User = user

// initialize license file
// lp, err := c.licenseInit(nodeDef, nodeCfg)
lp, err := c.Config.Topology.GetNodeLicense(nodeCfg.ShortName)
nodeCfg.License, err = c.Config.Topology.GetNodeLicense(nodeCfg.ShortName)
if err != nil {
return err
}
nodeCfg.License = lp

// mount config and log dirs
nodeCfg.Binds = append(nodeCfg.Binds, fmt.Sprint(path.Join(nodeCfg.LabDir, "config"), ":/config"))
Expand All @@ -46,32 +40,32 @@ func initCrpdNode(c *CLab, nodeDef *types.NodeDefinition, nodeCfg *types.NodeCon
return err
}

func (c *CLab) createCRPDFiles(node *types.NodeConfig) error {
func (c *CLab) createCRPDFiles(nodeCfg *types.NodeConfig) error {
// create config and logs directory that will be bind mounted to crpd
utils.CreateDirectory(path.Join(node.LabDir, "config"), 0777)
utils.CreateDirectory(path.Join(node.LabDir, "log"), 0777)
utils.CreateDirectory(path.Join(nodeCfg.LabDir, "config"), 0777)
utils.CreateDirectory(path.Join(nodeCfg.LabDir, "log"), 0777)

// copy crpd config from default template or user-provided conf file
cfg := path.Join(node.LabDir, "/config/juniper.conf")
cfg := path.Join(nodeCfg.LabDir, "/config/juniper.conf")

err := node.GenerateConfig(cfg, defaultConfigTemplates[node.Kind])
err := nodeCfg.GenerateConfig(cfg, defaultConfigTemplates[nodeCfg.Kind])
if err != nil {
log.Errorf("node=%s, failed to generate config: %v", node.ShortName, err)
log.Errorf("node=%s, failed to generate config: %v", nodeCfg.ShortName, err)
}

// copy crpd sshd conf file to crpd node dir
src := "/etc/containerlab/templates/crpd/sshd_config"
dst := node.LabDir + "/config/sshd_config"
dst := nodeCfg.LabDir + "/config/sshd_config"
err = copyFile(src, dst)
if err != nil {
return fmt.Errorf("file copy [src %s -> dst %s] failed %v", src, dst, err)
}
log.Debugf("CopyFile src %s -> dst %s succeeded\n", src, dst)

if node.License != "" {
if nodeCfg.License != "" {
// copy license file to node specific lab directory
src = node.License
dst = path.Join(node.LabDir, "/config/license.conf")
src = nodeCfg.License
dst = path.Join(nodeCfg.LabDir, "/config/license.conf")
if err = copyFile(src, dst); err != nil {
return fmt.Errorf("file copy [src %s -> dst %s] failed %v", src, dst, err)
}
Expand Down
4 changes: 0 additions & 4 deletions clab/linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,9 @@ func initLinuxNode(c *CLab, nodeDef *types.NodeDefinition, nodeCfg *types.NodeCo
if err != nil {
return err
}
// nodeCfg.Image = c.imageInitialization(nodeDef, nodeCfg.Kind)
nodeCfg.Image = c.Config.Topology.GetNodeImage(nodeCfg.ShortName)
// nodeCfg.Group = c.groupInitialization(nodeDef, nodeCfg.Kind)
nodeCfg.Group = c.Config.Topology.GetNodeGroup(nodeCfg.ShortName)
// nodeCfg.Position = c.positionInitialization(nodeDef, nodeCfg.Kind)
nodeCfg.Position = c.Config.Topology.GetNodePosition(nodeCfg.ShortName)
// nodeCfg.Cmd = c.cmdInit(nodeDef, nodeCfg.Kind)
nodeCfg.Cmd = c.Config.Topology.GetNodeCmd(nodeCfg.ShortName)
nodeCfg.User = user

Expand Down
4 changes: 0 additions & 4 deletions clab/sonic.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,12 @@ import "github.com/srl-labs/containerlab/types"
func initSonicNode(c *CLab, nodeDef *types.NodeDefinition, nodeCfg *types.NodeConfig, user string, envs map[string]string) error {
var err error

// nodeCfg.Config, err = c.configInit(nodeDef, nodeCfg.Kind)
c.Config.Topology.GetNodeConfig(nodeCfg.ShortName)
if err != nil {
return err
}
// nodeCfg.Image = c.imageInitialization(nodeDef, nodeCfg.Kind)
nodeCfg.Image = c.Config.Topology.GetNodeImage(nodeCfg.ShortName)
// nodeCfg.Group = c.groupInitialization(nodeDef, nodeCfg.Kind)
nodeCfg.Group = c.Config.Topology.GetNodeGroup(nodeCfg.ShortName)
// nodeCfg.Position = c.positionInitialization(nodeDef, nodeCfg.Kind)
nodeCfg.Position = c.Config.Topology.GetNodePosition(nodeCfg.ShortName)
nodeCfg.User = user

Expand Down
13 changes: 3 additions & 10 deletions clab/srl.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,30 +63,23 @@ func initSRLNode(c *CLab, nodeDef *types.NodeDefinition, nodeCfg *types.NodeConf
return err
}

// lp, err := c.licenseInit(nodeDef, nodeCfg)
lp, err := c.Config.Topology.GetNodeLicense(nodeCfg.ShortName)
nodeCfg.License, err = c.Config.Topology.GetNodeLicense(nodeCfg.ShortName)
if err != nil {
return err
}
if lp == "" {
if nodeCfg.License == "" {
return fmt.Errorf("no license found for node '%s' of kind '%s'", nodeCfg.ShortName, nodeCfg.Kind)
}

nodeCfg.License = lp

// nodeCfg.Image = c.imageInitialization(nodeDef, nodeCfg.Kind)
nodeCfg.Image = c.Config.Topology.GetNodeImage(nodeCfg.ShortName)
// nodeCfg.Group = c.groupInitialization(nodeDef, nodeCfg.Kind)
nodeCfg.Group = c.Config.Topology.GetNodeGroup(nodeCfg.ShortName)
nodeCfg.NodeType = c.Config.Topology.GetNodeType(nodeCfg.ShortName)
if nodeCfg.NodeType == "" {
nodeCfg.NodeType = srlDefaultType
}
// nodeCfg.NodeType = c.typeInit(nodeDef, nodeCfg.Kind)
// nodeCfg.Position = c.positionInitialization(nodeDef, nodeCfg.Kind)
nodeCfg.Position = c.Config.Topology.GetNodePosition(nodeCfg.ShortName)
if filename, found := srlTypes[nodeCfg.NodeType]; found {
nodeCfg.Topology = baseConfigDir + filename
nodeCfg.Topology = path.Join(baseConfigDir, filename)
} else {
keys := make([]string, 0, len(srlTypes))
for key := range srlTypes {
Expand Down
3 changes: 0 additions & 3 deletions clab/vr-csr.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,8 @@ import (
func initVrCSRNode(c *CLab, nodeDef *types.NodeDefinition, nodeCfg *types.NodeConfig, user string, envs map[string]string) error {
var err error

// nodeCfg.Image = c.imageInitialization(nodeDef, nodeCfg.Kind)
nodeCfg.Image = c.Config.Topology.GetNodeImage(nodeCfg.ShortName)
// nodeCfg.Group = c.groupInitialization(nodeDef, nodeCfg.Kind)
nodeCfg.Group = c.Config.Topology.GetNodeGroup(nodeCfg.ShortName)
// nodeCfg.Position = c.positionInitialization(nodeDef, nodeCfg.Kind)
nodeCfg.Position = c.Config.Topology.GetNodePosition(nodeCfg.ShortName)
nodeCfg.User = user

Expand Down
3 changes: 0 additions & 3 deletions clab/vr-ros.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,8 @@ import (
func initVrROSNode(c *CLab, nodeDef *types.NodeDefinition, nodeCfg *types.NodeConfig, user string, envs map[string]string) error {
var err error

// nodeCfg.Image = c.imageInitialization(nodeDef, nodeCfg.Kind)
nodeCfg.Image = c.Config.Topology.GetNodeImage(nodeCfg.ShortName)
// nodeCfg.Group = c.groupInitialization(nodeDef, nodeCfg.Kind)
nodeCfg.Group = c.Config.Topology.GetNodeGroup(nodeCfg.ShortName)
// nodeCfg.Position = c.positionInitialization(nodeDef, nodeCfg.Kind)
nodeCfg.Position = c.Config.Topology.GetNodePosition(nodeCfg.ShortName)
nodeCfg.User = user

Expand Down
11 changes: 2 additions & 9 deletions clab/vr-sros.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,33 +15,26 @@ import (

func initSROSNode(c *CLab, nodeDef *types.NodeDefinition, nodeCfg *types.NodeConfig, user string, envs map[string]string) error {
var err error
// nodeCfg.Config, err = c.configInit(nodeDef, nodeCfg.Kind)

c.Config.Topology.GetNodeConfig(nodeCfg.ShortName)
if err != nil {
return err
}
// nodeCfg.Image = c.imageInitialization(nodeDef, nodeCfg.Kind)
nodeCfg.Image = c.Config.Topology.GetNodeImage(nodeCfg.ShortName)
// nodeCfg.Group = c.groupInitialization(nodeDef, nodeCfg.Kind)
nodeCfg.Group = c.Config.Topology.GetNodeGroup(nodeCfg.ShortName)
// nodeCfg.Position = c.positionInitialization(nodeDef, nodeCfg.Kind)
nodeCfg.Position = c.Config.Topology.GetNodePosition(nodeCfg.ShortName)
nodeCfg.User = user

// vr-sros type sets the vrnetlab/sros variant (https://github.com/hellt/vrnetlab/sros)
nodeCfg.NodeType = c.Config.Topology.GetNodeType(nodeCfg.ShortName)
//nodeCfg.NodeType = c.typeInit(nodeDef, nodeCfg.Kind)
if nodeCfg.NodeType == "" {
nodeCfg.NodeType = vrsrosDefaultType
}
// initialize license file
// lp, err := c.licenseInit(nodeDef, nodeCfg)
lp, err := c.Config.Topology.GetNodeLicense(nodeCfg.ShortName)
nodeCfg.License, err = c.Config.Topology.GetNodeLicense(nodeCfg.ShortName)
if err != nil {
return err
}
nodeCfg.License = lp

// env vars are used to set launch.py arguments in vrnetlab container
defEnv := map[string]string{
"CONNECTION_MODE": vrDefConnMode,
Expand Down
4 changes: 1 addition & 3 deletions clab/vr-veos.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,9 @@ import (

func initVrVeosNode(c *CLab, nodeDef *types.NodeDefinition, nodeCfg *types.NodeConfig, user string, envs map[string]string) error {
var err error
// nodeCfg.Image = c.imageInitialization(nodeDef, nodeCfg.Kind)

nodeCfg.Image = c.Config.Topology.GetNodeImage(nodeCfg.ShortName)
// nodeCfg.Group = c.groupInitialization(nodeDef, nodeCfg.Kind)
nodeCfg.Group = c.Config.Topology.GetNodeGroup(nodeCfg.ShortName)
// nodeCfg.Position = c.positionInitialization(nodeDef, nodeCfg.Kind)
nodeCfg.Position = c.Config.Topology.GetNodePosition(nodeCfg.ShortName)
nodeCfg.User = user

Expand Down
3 changes: 0 additions & 3 deletions clab/vr-vmx.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,8 @@ import (

func initVrVMXNode(c *CLab, nodeDef *types.NodeDefinition, nodeCfg *types.NodeConfig, user string, envs map[string]string) error {
var err error
// nodeCfg.Image = c.imageInitialization(nodeDef, nodeCfg.Kind)
nodeCfg.Image = c.Config.Topology.GetNodeImage(nodeCfg.ShortName)
// nodeCfg.Group = c.groupInitialization(nodeDef, nodeCfg.Kind)
nodeCfg.Group = c.Config.Topology.GetNodeGroup(nodeCfg.ShortName)
// nodeCfg.Position = c.positionInitialization(nodeDef, nodeCfg.Kind)
nodeCfg.Position = c.Config.Topology.GetNodePosition(nodeCfg.ShortName)
nodeCfg.User = user

Expand Down
3 changes: 0 additions & 3 deletions clab/vr-xrv.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,8 @@ import (
func initVrXRVNode(c *CLab, nodeDef *types.NodeDefinition, nodeCfg *types.NodeConfig, user string, envs map[string]string) error {
var err error

// nodeCfg.Image = c.imageInitialization(nodeDef, nodeCfg.Kind)
nodeCfg.Image = c.Config.Topology.GetNodeImage(nodeCfg.ShortName)
// nodeCfg.Group = c.groupInitialization(nodeDef, nodeCfg.Kind)
nodeCfg.Group = c.Config.Topology.GetNodeGroup(nodeCfg.ShortName)
// nodeCfg.Position = c.positionInitialization(nodeDef, nodeCfg.Kind)
nodeCfg.Position = c.Config.Topology.GetNodePosition(nodeCfg.ShortName)
nodeCfg.User = user

Expand Down
Loading

0 comments on commit 1588730

Please sign in to comment.