From 026e4c00f776ba3776896ca2180ceff5b98475e7 Mon Sep 17 00:00:00 2001 From: Karim Radhouani Date: Fri, 18 Jun 2021 00:28:02 +0800 Subject: [PATCH] move topology struct and config items to types package --- clab/ceos.go | 34 +-- clab/cert.go | 2 +- clab/clab.go | 15 +- clab/config.go | 345 ++++++------------------------- clab/config_test.go | 27 ++- clab/crpd.go | 29 +-- clab/file.go | 2 +- clab/inventory.go | 4 +- clab/linux.go | 29 +-- clab/mysocketio.go | 2 +- clab/sonic.go | 18 +- clab/srl.go | 71 ++++--- clab/vr-csr.go | 22 +- clab/vr-ros.go | 22 +- clab/vr-sros.go | 44 ++-- clab/vr-veos.go | 23 ++- clab/vr-vmx.go | 22 +- clab/vr-xrv.go | 22 +- clab/vr-xrv9k.go | 22 +- cmd/deploy.go | 4 +- cmd/generate.go | 18 +- cmd/tools_veth.go | 4 +- go.mod | 2 +- go.sum | 120 +---------- runtime/containerd/containerd.go | 2 +- runtime/docker/docker.go | 2 +- runtime/runtime.go | 2 +- types/node_definition.go | 150 ++++++++++++++ types/topology.go | 288 ++++++++++++++++++++++++++ types/types.go | 8 +- utils/env.go | 21 ++ 31 files changed, 784 insertions(+), 592 deletions(-) create mode 100644 types/node_definition.go create mode 100644 types/topology.go diff --git a/clab/ceos.go b/clab/ceos.go index 9c7eafcd3..271df47d6 100644 --- a/clab/ceos.go +++ b/clab/ceos.go @@ -18,7 +18,7 @@ import ( "github.com/srl-labs/containerlab/utils" ) -func ceosPostDeploy(ctx context.Context, c *CLab, node *types.Node, lworkers uint) error { +func ceosPostDeploy(ctx context.Context, c *CLab, node *types.NodeConfig, lworkers uint) error { // regenerate ceos config since it is now known which IP address docker assigned to this container err := node.GenerateConfig(node.ResConfig, defaultConfigTemplates[node.Kind]) if err != nil { @@ -52,16 +52,19 @@ func ceosPostDeploy(ctx context.Context, c *CLab, node *types.Node, lworkers uin return err } -func initCeosNode(c *CLab, nodeCfg NodeConfig, node *types.Node, user string, envs map[string]string) error { +func initCeosNode(c *CLab, nodeDef *types.NodeDefinition, nodeCfg *types.NodeConfig, user string, envs map[string]string) error { var err error // initialize the global parameters with defaults, can be overwritten later - node.Config, err = c.configInit(&nodeCfg, node.Kind) + // node.Config, err = c.configInit(nodeCfg, node.Kind) + c.Config.Topology.GetNodeConfig(nodeCfg.ShortName) if err != nil { return err } - node.Image = c.imageInitialization(&nodeCfg, node.Kind) - node.Position = c.positionInitialization(&nodeCfg, node.Kind) + // 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 @@ -75,31 +78,32 @@ func initCeosNode(c *CLab, nodeCfg NodeConfig, node *types.Node, user string, en "INTFTYPE": "eth", "MAPETH0": "1", "MGMT_INTF": "eth0"} - node.Env = mergeStringMaps(kindEnv, envs) + nodeCfg.Env = utils.MergeStringMaps(kindEnv, envs) // the node.Cmd should be aligned with the environment. var envSb strings.Builder envSb.WriteString("/sbin/init ") - for k, v := range node.Env { + for k, v := range nodeCfg.Env { envSb.WriteString("systemd.setenv=" + k + "=" + v + " ") } - node.Cmd = envSb.String() + nodeCfg.Cmd = envSb.String() - node.User = user - node.Group = c.groupInitialization(&nodeCfg, node.Kind) - node.NodeType = nodeCfg.Type + nodeCfg.User = user + // nodeCfg.Group = c.groupInitialization(nodeDef, nodeCfg.Kind) + nodeCfg.Group = c.Config.Topology.GetNodeGroup(nodeCfg.ShortName) + nodeCfg.NodeType = nodeDef.Type - node.MacAddress = genMac("00:1c:73") + nodeCfg.MacAddress = genMac("00:1c:73") // mount config dir - cfgPath := filepath.Join(node.LabDir, "flash") - node.Binds = append(node.Binds, fmt.Sprint(cfgPath, ":/mnt/flash/")) + cfgPath := filepath.Join(nodeCfg.LabDir, "flash") + nodeCfg.Binds = append(nodeCfg.Binds, fmt.Sprint(cfgPath, ":/mnt/flash/")) return err } -func (c *CLab) createCEOSFiles(node *types.Node) error { +func (c *CLab) createCEOSFiles(node *types.NodeConfig) error { // generate config directory utils.CreateDirectory(path.Join(node.LabDir, "flash"), 0777) cfg := path.Join(node.LabDir, "flash", "startup-config") diff --git a/clab/cert.go b/clab/cert.go index 3e6e0a96b..f650c9872 100644 --- a/clab/cert.go +++ b/clab/cert.go @@ -202,7 +202,7 @@ func (c *CLab) GenerateCert(ca string, caKey string, csrJSONTpl *template.Templa // RetrieveNodeCertData reads the node private key and certificate by the well known paths // if either of those files doesn't exist, an error is returned -func (c *CLab) RetrieveNodeCertData(n *types.Node) (*Certificates, error) { +func (c *CLab) RetrieveNodeCertData(n *types.NodeConfig) (*Certificates, error) { var nodeCertFilesDir = path.Join(c.Dir.LabCA, n.ShortName) var nodeCertFile = path.Join(nodeCertFilesDir, n.ShortName+".pem") var nodeKeyFile = path.Join(nodeCertFilesDir, n.ShortName+"-key.pem") diff --git a/clab/clab.go b/clab/clab.go index ae3f0ab8d..ad1285ec5 100644 --- a/clab/clab.go +++ b/clab/clab.go @@ -26,7 +26,7 @@ type CLab struct { Config *Config TopoFile *TopoFile m *sync.RWMutex - Nodes map[string]*types.Node + Nodes map[string]*types.NodeConfig Links map[int]*types.Link Runtime runtime.ContainerRuntime Dir *Directory @@ -115,11 +115,12 @@ func WithGracefulShutdown(gracefulShutdown bool) ClabOption { func NewContainerLab(opts ...ClabOption) *CLab { c := &CLab{ Config: &Config{ - Mgmt: new(types.MgmtNet), + Mgmt: new(types.MgmtNet), + Topology: types.NewTopology(), }, TopoFile: new(TopoFile), m: new(sync.RWMutex), - Nodes: make(map[string]*types.Node), + Nodes: make(map[string]*types.NodeConfig), Links: make(map[int]*types.Link), } @@ -152,7 +153,7 @@ func (c *CLab) initMgmtNetwork() error { return nil } -func (c *CLab) CreateNode(ctx context.Context, node *types.Node, certs *Certificates) error { +func (c *CLab) CreateNode(ctx context.Context, node *types.NodeConfig, certs *Certificates) error { if certs != nil { c.m.Lock() node.TLSCert = string(certs.Cert) @@ -167,7 +168,7 @@ func (c *CLab) CreateNode(ctx context.Context, node *types.Node, certs *Certific } // ExecPostDeployTasks executes tasks that some nodes might require to boot properly after start -func (c *CLab) ExecPostDeployTasks(ctx context.Context, node *types.Node, lworkers uint) error { +func (c *CLab) ExecPostDeployTasks(ctx context.Context, node *types.NodeConfig, lworkers uint) error { switch node.Kind { case "ceos": log.Debugf("Running postdeploy actions for Arista cEOS '%s' node", node.ShortName) @@ -213,7 +214,7 @@ func (c *CLab) ExecPostDeployTasks(ctx context.Context, node *types.Node, lworke func (c *CLab) CreateNodes(ctx context.Context, workers uint) { wg := new(sync.WaitGroup) wg.Add(int(workers)) - nodesChan := make(chan *types.Node) + nodesChan := make(chan *types.NodeConfig) // start workers for i := uint(0); i < workers; i++ { go func(i uint) { @@ -372,7 +373,7 @@ func (c *CLab) DeleteNodes(ctx context.Context, workers uint, containers []types } -func disableTxOffload(n *types.Node) error { +func disableTxOffload(n *types.NodeConfig) error { // skip this if node runs in host mode if strings.ToLower(n.NetworkMode) == "host" { return nil diff --git a/clab/config.go b/clab/config.go index 86dac2ae6..5fdac5eaf 100644 --- a/clab/config.go +++ b/clab/config.go @@ -14,10 +14,10 @@ import ( "strings" "syscall" - "github.com/docker/go-connections/nat" "github.com/mitchellh/go-homedir" log "github.com/sirupsen/logrus" "github.com/srl-labs/containerlab/types" + "github.com/srl-labs/containerlab/utils" "github.com/vishvananda/netlink" ) @@ -85,53 +85,10 @@ var srlTypes = map[string]string{ // Config defines lab configuration as it is provided in the YAML file type Config struct { - Name string `json:"name,omitempty"` - Mgmt *types.MgmtNet `json:"mgmt,omitempty"` - Topology Topology `json:"topology,omitempty"` - ConfigPath string `yaml:"config_path,omitempty"` -} - -// Topology represents a lab topology -type Topology struct { - Defaults NodeConfig `yaml:"defaults,omitempty"` - Kinds map[string]NodeConfig `yaml:"kinds,omitempty"` - Nodes map[string]NodeConfig `yaml:"nodes,omitempty"` - Links []LinkConfig `yaml:"links,omitempty"` -} - -// NodeConfig represents a configuration a given node can have in the lab definition file -type NodeConfig struct { - Kind string `yaml:"kind,omitempty"` - Group string `yaml:"group,omitempty"` - Type string `yaml:"type,omitempty"` - Config string `yaml:"config,omitempty"` - Image string `yaml:"image,omitempty"` - License string `yaml:"license,omitempty"` - Position string `yaml:"position,omitempty"` - Cmd string `yaml:"cmd,omitempty"` - // list of bind mount compatible strings - Binds []string `yaml:"binds,omitempty"` - // list of port bindings - Ports []string `yaml:"ports,omitempty"` - // user-defined IPv4 address in the management network - MgmtIPv4 string `yaml:"mgmt_ipv4,omitempty"` - // user-defined IPv6 address in the management network - MgmtIPv6 string `yaml:"mgmt_ipv6,omitempty"` - // list of ports to publish with mysocketctl - Publish []string `yaml:"publish,omitempty"` - // environment variables - Env map[string]string `yaml:"env,omitempty"` - // linux user used in a container - User string `yaml:"user,omitempty"` - // container labels - Labels map[string]string `yaml:"labels,omitempty"` - // container networking mode. if set to `host` the host networking will be used for this node, else bridged network - NetworkMode string `yaml:"network-mode,omitempty"` -} - -type LinkConfig struct { - Endpoints []string - Labels map[string]string `yaml:"labels,omitempty"` + Name string `json:"name,omitempty"` + Mgmt *types.MgmtNet `json:"mgmt,omitempty"` + Topology *types.Topology `json:"topology,omitempty"` + ConfigPath string `yaml:"config_path,omitempty"` } // ParseTopology parses the lab topology @@ -150,7 +107,7 @@ func (c *CLab) ParseTopology() error { c.Dir.LabGraph = c.Dir.Lab + "/" + "graph" // initialize Nodes and Links variable - c.Nodes = make(map[string]*types.Node) + c.Nodes = make(map[string]*types.NodeConfig) c.Links = make(map[int]*types.Link) // initialize the Node information from the topology map @@ -168,131 +125,17 @@ func (c *CLab) ParseTopology() error { return nil } -func (c *CLab) kindInitialization(nodeCfg *NodeConfig) string { - if nodeCfg.Kind != "" { - return nodeCfg.Kind +func (c *CLab) kindInitialization(nodeDef *types.NodeDefinition) string { + if nodeDef.Kind != "" { + return nodeDef.Kind } return c.Config.Topology.Defaults.Kind } -func (c *CLab) bindsInit(nodeCfg *NodeConfig) []string { - switch { - case len(nodeCfg.Binds) != 0: - return nodeCfg.Binds - case len(c.Config.Topology.Kinds[nodeCfg.Kind].Binds) != 0: - return c.Config.Topology.Kinds[nodeCfg.Kind].Binds - case len(c.Config.Topology.Defaults.Binds) != 0: - return c.Config.Topology.Defaults.Binds - } - return nil -} - -// portsInit produces the nat.PortMap out of the slice of string representation of port bindings -func (c *CLab) portsInit(nodeCfg *NodeConfig) (nat.PortSet, nat.PortMap, error) { - if len(nodeCfg.Ports) != 0 { - ps, pb, err := nat.ParsePortSpecs(nodeCfg.Ports) - if err != nil { - return nil, nil, err - } - return ps, pb, nil - } - return nil, nil, nil -} - -func (c *CLab) groupInitialization(nodeCfg *NodeConfig, kind string) string { - if nodeCfg.Group != "" { - return nodeCfg.Group - } else if c.Config.Topology.Kinds[kind].Group != "" { - return c.Config.Topology.Kinds[kind].Group - } - return c.Config.Topology.Defaults.Group -} - -// initialize SRL HW type -func (c *CLab) typeInit(nodeCfg *NodeConfig, kind string) string { - switch { - case nodeCfg.Type != "": - return nodeCfg.Type - case c.Config.Topology.Kinds[kind].Type != "": - return c.Config.Topology.Kinds[kind].Type - case c.Config.Topology.Defaults.Type != "": - return c.Config.Topology.Defaults.Type - } - // default type if not defined - switch kind { - case "srl": - return srlDefaultType - - case "vr-sros": - return vrsrosDefaultType - } - return "" -} - -// configInit processes the path to a config file that can be provided on -// multiple configuration levels -// returns an error if the reference path doesn't exist -func (c *CLab) configInit(nodeCfg *NodeConfig, kind string) (string, error) { - var cfg string - var err error +func (c *CLab) cmdInit(nodeDef *types.NodeDefinition, kind string) string { switch { - case nodeCfg.Config != "": - cfg = nodeCfg.Config - case c.Config.Topology.Kinds[kind].Config != "": - cfg = c.Config.Topology.Kinds[kind].Config - case c.Config.Topology.Defaults.Config != "": - cfg = c.Config.Topology.Defaults.Config - default: - cfg = defaultConfigTemplates[kind] - } - if cfg != "" { - cfg, err = resolvePath(cfg) - if err != nil { - return "", err - } - _, err = os.Stat(cfg) - } - return cfg, err -} - -func (c *CLab) imageInitialization(nodeCfg *NodeConfig, kind string) string { - if nodeCfg.Image != "" { - return nodeCfg.Image - } - if c.Config.Topology.Kinds[kind].Image != "" { - return c.Config.Topology.Kinds[kind].Image - } - return c.Config.Topology.Defaults.Image -} - -func (c *CLab) licenseInit(nodeCfg *NodeConfig, node *types.Node) (string, error) { - // path to license file - var lic string - var err error - switch { - case nodeCfg.License != "": - lic = nodeCfg.License - case c.Config.Topology.Kinds[node.Kind].License != "": - lic = c.Config.Topology.Kinds[node.Kind].License - case c.Config.Topology.Defaults.License != "": - lic = c.Config.Topology.Defaults.License - default: - lic = "" - } - if lic != "" { - lic, err = resolvePath(lic) - if err != nil { - return "", err - } - _, err = os.Stat(lic) - } - return lic, err -} - -func (c *CLab) cmdInit(nodeCfg *NodeConfig, kind string) string { - switch { - case nodeCfg.Cmd != "": - return nodeCfg.Cmd + case nodeDef.Cmd != "": + return nodeDef.Cmd case c.Config.Topology.Kinds[kind].Cmd != "": return c.Config.Topology.Kinds[kind].Cmd @@ -303,51 +146,8 @@ func (c *CLab) cmdInit(nodeCfg *NodeConfig, kind string) string { return "" } -// initialize environment variables -func (c *CLab) envInit(nodeCfg *NodeConfig, kind string) map[string]string { - // merge global envs into kind envs - m := mergeStringMaps(c.Config.Topology.Defaults.Env, c.Config.Topology.Kinds[kind].Env) - // merge result of previous merge into node envs - return mergeStringMaps(m, nodeCfg.Env) -} - -func (c *CLab) positionInitialization(nodeCfg *NodeConfig, kind string) string { - if nodeCfg.Position != "" { - return nodeCfg.Position - } else if c.Config.Topology.Kinds[kind].Position != "" { - return c.Config.Topology.Kinds[kind].Position - } - return c.Config.Topology.Defaults.Position -} - -func (c *CLab) userInit(nodeCfg *NodeConfig, kind string) string { - switch { - case nodeCfg.User != "": - return nodeCfg.User - - case c.Config.Topology.Kinds[kind].User != "": - return c.Config.Topology.Kinds[kind].User - - case c.Config.Topology.Defaults.User != "": - return c.Config.Topology.Defaults.User - } - return "" -} - -func (c *CLab) publishInit(nodeCfg *NodeConfig, kind string) []string { - switch { - case len(nodeCfg.Publish) != 0: - return nodeCfg.Publish - case len(c.Config.Topology.Kinds[kind].Publish) != 0: - return c.Config.Topology.Kinds[kind].Publish - case len(c.Config.Topology.Defaults.Publish) != 0: - return c.Config.Topology.Defaults.Publish - } - return nil -} - // initialize container labels -func (c *CLab) labelsInit(nodeCfg *NodeConfig, kind string, node *types.Node) map[string]string { +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, @@ -358,136 +158,140 @@ func (c *CLab) labelsInit(nodeCfg *NodeConfig, kind string, node *types.Node) ma "clab-topo-file": c.TopoFile.path, } // merge global labels into kind envs - m := mergeStringMaps(c.Config.Topology.Defaults.Labels, c.Config.Topology.Kinds[kind].Labels) + m := utils.MergeStringMaps(c.Config.Topology.GetDefaults().GetLabels(), c.Config.Topology.GetKind(kind).GetLabels()) // merge result of previous merge into node envs - m2 := mergeStringMaps(m, nodeCfg.Labels) + m2 := utils.MergeStringMaps(m, nodeDef.GetLabels()) // merge with default labels - return mergeStringMaps(m2, defaultLabels) + return utils.MergeStringMaps(m2, defaultLabels) } // NewNode initializes a new node object -func (c *CLab) NewNode(nodeName string, nodeCfg NodeConfig, idx int) error { +func (c *CLab) NewNode(nodeName string, nodeDef *types.NodeDefinition, idx int) error { // initialize a new node - node := new(types.Node) - node.ShortName = nodeName - node.LongName = prefix + "-" + c.Config.Name + "-" + nodeName - node.Fqdn = nodeName + "." + c.Config.Name + ".io" - node.LabDir = c.Dir.Lab + "/" + nodeName - node.Index = idx - node.Endpoints = []*types.Endpoint{} + 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{} - node.NetworkMode = strings.ToLower(nodeCfg.NetworkMode) + nodeCfg.NetworkMode = strings.ToLower(nodeDef.NetworkMode) - node.MgmtIPv4Address = nodeCfg.MgmtIPv4 - node.MgmtIPv6Address = nodeCfg.MgmtIPv6 + nodeCfg.MgmtIPv4Address = nodeDef.MgmtIPv4 + nodeCfg.MgmtIPv6Address = nodeDef.MgmtIPv6 // 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 - node.Kind = strings.ToLower(c.kindInitialization(&nodeCfg)) + nodeCfg.Kind = strings.ToLower(c.kindInitialization(nodeDef)) // initialize bind mounts - binds := c.bindsInit(&nodeCfg) - err := resolveBindPaths(binds, node.LabDir) + // binds := c.bindsInit(nodeDef) + binds := c.Config.Topology.GetNodeBinds(nodeName) + err := resolveBindPaths(binds, nodeCfg.LabDir) if err != nil { return err } - node.Binds = binds + nodeCfg.Binds = binds - ps, pb, err := c.portsInit(&nodeCfg) + //ps, pb, err := c.portsInit(nodeDef) + nodeCfg.PortSet, nodeCfg.PortBindings, err = c.Config.Topology.GetNodePorts(nodeName) if err != nil { return err } - node.PortBindings = pb - node.PortSet = ps // initialize passed env variables which will be merged with kind specific ones - envs := c.envInit(&nodeCfg, node.Kind) - - user := c.userInit(&nodeCfg, node.Kind) + // envs := c.envInit(nodeDef, nodeCfg.Kind) + envs := c.Config.Topology.GetNodeEnv(nodeName) - node.Publish = c.publishInit(&nodeCfg, node.Kind) + // user := c.userInit(nodeDef, nodeCfg.Kind) + user := c.Config.Topology.GetNodeUser(nodeName) - switch node.Kind { + // nodeCfg.Publish = c.publishInit(nodeDef, nodeCfg.Kind) + nodeCfg.Publish = c.Config.Topology.GetNodePublish(nodeName) + switch nodeCfg.Kind { case "ceos": - err = initCeosNode(c, nodeCfg, node, user, envs) + err = initCeosNode(c, nodeDef, nodeCfg, user, envs) if err != nil { return err } case "srl": - err = initSRLNode(c, nodeCfg, node, user, envs) + err = initSRLNode(c, nodeDef, nodeCfg, user, envs) if err != nil { return err } case "crpd": - err = initCrpdNode(c, nodeCfg, node, user, envs) + err = initCrpdNode(c, nodeDef, nodeCfg, user, envs) if err != nil { return err } case "sonic-vs": - err = initSonicNode(c, nodeCfg, node, user, envs) + err = initSonicNode(c, nodeDef, nodeCfg, user, envs) if err != nil { return err } case "vr-sros": - err = initSROSNode(c, nodeCfg, node, user, envs) + err = initSROSNode(c, nodeDef, nodeCfg, user, envs) if err != nil { return err } case "vr-vmx": - err = initVrVMXNode(c, nodeCfg, node, user, envs) + err = initVrVMXNode(c, nodeDef, nodeCfg, user, envs) if err != nil { return err } case "vr-xrv": - err = initVrXRVNode(c, nodeCfg, node, user, envs) + err = initVrXRVNode(c, nodeDef, nodeCfg, user, envs) if err != nil { return err } case "vr-xrv9k": - err = initVrXRV9kNode(c, nodeCfg, node, user, envs) + err = initVrXRV9kNode(c, nodeDef, nodeCfg, user, envs) if err != nil { return err } case "vr-veos": - err = initVrVeosNode(c, nodeCfg, node, user, envs) + err = initVrVeosNode(c, nodeDef, nodeCfg, user, envs) if err != nil { return err } case "vr-csr": - err = initVrCSRNode(c, nodeCfg, node, user, envs) + err = initVrCSRNode(c, nodeDef, nodeCfg, user, envs) if err != nil { return err } case "vr-ros": - err = initVrROSNode(c, nodeCfg, node, user, envs) + err = initVrROSNode(c, nodeDef, nodeCfg, user, envs) if err != nil { return err } case "alpine", "linux", "mysocketio": - err = initLinuxNode(c, nodeCfg, node, user, envs) + err = initLinuxNode(c, nodeDef, nodeCfg, user, envs) if err != nil { return err } case "bridge", "ovs-bridge": - node.Group = c.groupInitialization(&nodeCfg, node.Kind) - node.Position = c.positionInitialization(&nodeCfg, node.Kind) + // 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, node.Kind, kinds) + 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 - node.Labels = c.labelsInit(&nodeCfg, node.Kind, node) - - c.Nodes[nodeName] = node + nodeCfg.Labels = c.labelsInit(nodeDef, nodeCfg.Kind, nodeCfg) + // nodeCfg.Labels = c.Config.Topology.GetNodeLabels(nodeName) + c.Nodes[nodeName] = nodeCfg return nil } // NewLink initializes a new link object -func (c *CLab) NewLink(l LinkConfig) *types.Link { +func (c *CLab) NewLink(l *types.LinkConfig) *types.Link { // initialize a new link link := new(types.Link) link.Labels = l.Labels @@ -529,7 +333,7 @@ func (c *CLab) NewEndpoint(e string) *types.Endpoint { // "host" is a special reference to host namespace // for which we create an special Node with kind "host" case "host": - endpoint.Node = &types.Node{ + endpoint.Node = &types.NodeConfig{ Kind: "host", ShortName: "host", NSPath: hostNSPath, @@ -537,7 +341,7 @@ func (c *CLab) NewEndpoint(e string) *types.Endpoint { // mgmt-net is a special reference to a bridge of the docker network // that is used as the management network case "mgmt-net": - endpoint.Node = &types.Node{ + endpoint.Node = &types.NodeConfig{ Kind: "bridge", ShortName: "mgmt-net", } @@ -833,27 +637,6 @@ func resolveBindPaths(binds []string, nodedir string) error { return nil } -// mergeStringMaps merges map m1 into m2 and return a resulting map as a new map -// maps that are passed for merging will not be changed -func mergeStringMaps(m1, m2 map[string]string) map[string]string { - if m1 == nil { - return m2 - } - if m2 == nil { - return m1 - } - // make a copy of a map - m := make(map[string]string) - for k, v := range m1 { - m[k] = v - } - - for k, v := range m2 { - m[k] = v - } - return m -} - // CheckResources runs container host resources check func (c *CLab) CheckResources() error { vcpu := runtime.NumCPU() diff --git a/clab/config_test.go b/clab/config_test.go index 2ad654ab6..a4caefb13 100644 --- a/clab/config_test.go +++ b/clab/config_test.go @@ -48,7 +48,9 @@ func TestLicenseInit(t *testing.T) { if err := c.ParseTopology(); err != nil { t.Fatal(err) } - + // fmt.Println(c.Config.Topology.Defaults) + // fmt.Println(c.Config.Topology.Kinds) + // fmt.Println(c.Config.Topology.Nodes) if filepath.Base(c.Nodes["node1"].License) != tc.want { t.Fatalf("wanted '%s' got '%s'", tc.want, c.Nodes["node1"].License) } @@ -94,10 +96,11 @@ func TestBindsInit(t *testing.T) { } nodeCfg := c.Config.Topology.Nodes["node1"] - node := types.Node{} - node.Kind = strings.ToLower(c.kindInitialization(&nodeCfg)) + node := types.NodeConfig{} + node.Kind = strings.ToLower(c.kindInitialization(nodeCfg)) - binds := c.bindsInit(&nodeCfg) + // binds := c.bindsInit(nodeCfg) + binds := c.Config.Topology.GetNodeBinds("node1") // resolve wanted paths as the binds paths are resolved as part of the c.ParseTopology err := resolveBindPaths(tc.want, node.LabDir) if err != nil { @@ -247,9 +250,10 @@ func TestEnvInit(t *testing.T) { t.Fatal(err) } - nodeCfg := c.Config.Topology.Nodes[tc.node] - kind := strings.ToLower(c.kindInitialization(&nodeCfg)) - env := c.envInit(&nodeCfg, kind) + // nodeCfg := c.Config.Topology.Nodes[tc.node] + // kind := strings.ToLower(c.kindInitialization(nodeCfg)) + env := c.Config.Topology.GetNodeEnv(tc.node) + //env := c.envInit(nodeCfg, kind) if !reflect.DeepEqual(env, tc.want) { t.Fatalf("wanted %q got %q", tc.want, env) } @@ -295,9 +299,10 @@ func TestUserInit(t *testing.T) { t.Fatal(err) } - nodeCfg := c.Config.Topology.Nodes[tc.node] - kind := strings.ToLower(c.kindInitialization(&nodeCfg)) - user := c.userInit(&nodeCfg, kind) + // nodeCfg := c.Config.Topology.Nodes[tc.node] + // kind := strings.ToLower(c.kindInitialization(nodeCfg)) + user := c.Config.Topology.GetNodeUser(tc.node) + //user := c.userInit(nodeCfg, kind) if user != tc.want { t.Fatalf("wanted %q got %q", tc.want, user) } @@ -339,7 +344,7 @@ func TestVerifyLinks(t *testing.T) { } -func TestLablesInit(t *testing.T) { +func TestLabelsInit(t *testing.T) { tests := map[string]struct { got string node string diff --git a/clab/crpd.go b/clab/crpd.go index e06943ae8..fb6f788b5 100644 --- a/clab/crpd.go +++ b/clab/crpd.go @@ -13,35 +13,40 @@ import ( "github.com/srl-labs/containerlab/utils" ) -func initCrpdNode(c *CLab, nodeCfg NodeConfig, node *types.Node, user string, envs map[string]string) error { +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) + // node.Config, err = c.configInit(nodeCfg, node.Kind) + c.Config.Topology.GetNodeConfig(nodeCfg.ShortName) if err != nil { return err } - node.Image = c.imageInitialization(&nodeCfg, node.Kind) - node.Group = c.groupInitialization(&nodeCfg, node.Kind) - node.Position = c.positionInitialization(&nodeCfg, node.Kind) - node.User = user + // 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(&nodeCfg, node) + // lp, err := c.licenseInit(nodeDef, nodeCfg) + lp, err := c.Config.Topology.GetNodeLicense(nodeCfg.ShortName) if err != nil { return err } - node.License = lp + nodeCfg.License = lp // mount config and log dirs - node.Binds = append(node.Binds, fmt.Sprint(path.Join(node.LabDir, "config"), ":/config")) - node.Binds = append(node.Binds, fmt.Sprint(path.Join(node.LabDir, "log"), ":/var/log")) + nodeCfg.Binds = append(nodeCfg.Binds, fmt.Sprint(path.Join(nodeCfg.LabDir, "config"), ":/config")) + nodeCfg.Binds = append(nodeCfg.Binds, fmt.Sprint(path.Join(nodeCfg.LabDir, "log"), ":/var/log")) // mount sshd_config - node.Binds = append(node.Binds, fmt.Sprint(path.Join(node.LabDir, "config/sshd_config"), ":/etc/ssh/sshd_config")) + nodeCfg.Binds = append(nodeCfg.Binds, fmt.Sprint(path.Join(nodeCfg.LabDir, "config/sshd_config"), ":/etc/ssh/sshd_config")) return err } -func (c *CLab) createCRPDFiles(node *types.Node) error { +func (c *CLab) createCRPDFiles(node *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) diff --git a/clab/file.go b/clab/file.go index 5362f1ada..7de7548d4 100644 --- a/clab/file.go +++ b/clab/file.go @@ -124,7 +124,7 @@ func createFile(file, content string) { } // CreateNodeDirStructure create the directory structure and files for the lab nodes -func (c *CLab) CreateNodeDirStructure(node *types.Node) (err error) { +func (c *CLab) CreateNodeDirStructure(node *types.NodeConfig) (err error) { c.m.RLock() defer c.m.RUnlock() diff --git a/clab/inventory.go b/clab/inventory.go index 56e9ebee5..ae14ac0a9 100644 --- a/clab/inventory.go +++ b/clab/inventory.go @@ -45,12 +45,12 @@ func (c *CLab) generateAnsibleInventory(w io.Writer) error { type inv struct { // clab nodes aggregated by their kind - Nodes map[string][]*types.Node + Nodes map[string][]*types.NodeConfig Meta map[string]string } i := inv{ - Nodes: make(map[string][]*types.Node), + Nodes: make(map[string][]*types.NodeConfig), } for _, n := range c.Nodes { diff --git a/clab/linux.go b/clab/linux.go index 6bb3a6340..e17e91ff2 100644 --- a/clab/linux.go +++ b/clab/linux.go @@ -10,25 +10,30 @@ import ( "github.com/srl-labs/containerlab/types" ) -func initLinuxNode(c *CLab, nodeCfg NodeConfig, node *types.Node, user string, envs map[string]string) error { +func initLinuxNode(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) + // nodeCfg.Config, err = c.configInit(nodeDef, nodeCfg.Kind) + c.Config.Topology.GetNodeConfig(nodeCfg.ShortName) if err != nil { return err } - node.Image = c.imageInitialization(&nodeCfg, node.Kind) - node.Group = c.groupInitialization(&nodeCfg, node.Kind) - node.Position = c.positionInitialization(&nodeCfg, node.Kind) - node.Cmd = c.cmdInit(&nodeCfg, node.Kind) - node.User = user - - node.Sysctls = make(map[string]string) - if strings.ToLower(node.NetworkMode) != "host" { - node.Sysctls["net.ipv6.conf.all.disable_ipv6"] = "0" + // 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 + + nodeCfg.Sysctls = make(map[string]string) + if strings.ToLower(nodeCfg.NetworkMode) != "host" { + nodeCfg.Sysctls["net.ipv6.conf.all.disable_ipv6"] = "0" } - node.Env = envs + nodeCfg.Env = envs return err } diff --git a/clab/mysocketio.go b/clab/mysocketio.go index 3e11259de..b69ef9bf9 100644 --- a/clab/mysocketio.go +++ b/clab/mysocketio.go @@ -87,7 +87,7 @@ func checkSockPort(p int) error { } // createMysocketTunnels creates internet reachable personal tunnels using mysocket.io -func createMysocketTunnels(ctx context.Context, c *CLab, node *types.Node) error { +func createMysocketTunnels(ctx context.Context, c *CLab, node *types.NodeConfig) error { // remove the existing sockets cmd := []string{"/bin/sh", "-c", "mysocketctl socket ls | awk '/clab/ {print $2}' | xargs -n1 mysocketctl socket delete -s"} log.Debugf("Running postdeploy mysocketio command %q", cmd) diff --git a/clab/sonic.go b/clab/sonic.go index 529817354..99731afec 100644 --- a/clab/sonic.go +++ b/clab/sonic.go @@ -6,20 +6,24 @@ package clab import "github.com/srl-labs/containerlab/types" -func initSonicNode(c *CLab, nodeCfg NodeConfig, node *types.Node, user string, envs map[string]string) error { +func initSonicNode(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) + // nodeCfg.Config, err = c.configInit(nodeDef, nodeCfg.Kind) + c.Config.Topology.GetNodeConfig(nodeCfg.ShortName) if err != nil { return err } - node.Image = c.imageInitialization(&nodeCfg, node.Kind) - node.Group = c.groupInitialization(&nodeCfg, node.Kind) - node.Position = c.positionInitialization(&nodeCfg, node.Kind) - node.User = user + // 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 // rewrite entrypoint so sonic won't start supervisord before we attach veth interfaces - node.Entrypoint = "/bin/bash" + nodeCfg.Entrypoint = "/bin/bash" return err } diff --git a/clab/srl.go b/clab/srl.go index c4c0d3fc1..5621760c4 100644 --- a/clab/srl.go +++ b/clab/srl.go @@ -54,80 +54,87 @@ func generateSRLTopologyFile(src, labDir string, index int) error { return nil } -func initSRLNode(c *CLab, nodeCfg NodeConfig, node *types.Node, user string, envs map[string]string) error { +func initSRLNode(c *CLab, nodeDef *types.NodeDefinition, nodeCfg *types.NodeConfig, user string, envs map[string]string) error { var err error // initialize the global parameters with defaults, can be overwritten later - node.Config, err = c.configInit(&nodeCfg, node.Kind) + // nodeCfg.Config, err = c.configInit(nodeDef, nodeCfg.Kind) + c.Config.Topology.GetNodeConfig(nodeCfg.ShortName) if err != nil { return err } - lp, err := c.licenseInit(&nodeCfg, node) + // lp, err := c.licenseInit(nodeDef, nodeCfg) + lp, err := c.Config.Topology.GetNodeLicense(nodeCfg.ShortName) if err != nil { return err } - if lp == "" { - return fmt.Errorf("no license found for node '%s' of kind '%s'", node.ShortName, node.Kind) + return fmt.Errorf("no license found for node '%s' of kind '%s'", nodeCfg.ShortName, nodeCfg.Kind) } - node.License = lp - - node.Image = c.imageInitialization(&nodeCfg, node.Kind) - node.Group = c.groupInitialization(&nodeCfg, node.Kind) - node.NodeType = c.typeInit(&nodeCfg, node.Kind) - node.Position = c.positionInitialization(&nodeCfg, node.Kind) + nodeCfg.License = lp - if filename, found := srlTypes[node.NodeType]; found { - node.Topology = baseConfigDir + filename + // 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 } else { keys := make([]string, 0, len(srlTypes)) for key := range srlTypes { keys = append(keys, key) } - log.Fatalf("wrong node type. '%s' doesn't exist. should be any of %s", node.NodeType, strings.Join(keys, ", ")) + log.Fatalf("wrong node type. '%s' doesn't exist. should be any of %s", nodeCfg.NodeType, strings.Join(keys, ", ")) } // the addition touch is needed to support non docker runtimes - node.Cmd = "sudo bash -c 'touch /.dockerenv && /opt/srlinux/bin/sr_linux'" + nodeCfg.Cmd = "sudo bash -c 'touch /.dockerenv && /opt/srlinux/bin/sr_linux'" kindEnv := map[string]string{"SRLINUX": "1"} - node.Env = mergeStringMaps(kindEnv, envs) + nodeCfg.Env = utils.MergeStringMaps(kindEnv, envs) // if user was not initialized to a value, use root if user == "" { user = "0:0" } - node.User = user + nodeCfg.User = user - node.Sysctls = make(map[string]string) - node.Sysctls["net.ipv4.ip_forward"] = "0" - node.Sysctls["net.ipv6.conf.all.disable_ipv6"] = "0" - node.Sysctls["net.ipv6.conf.all.accept_dad"] = "0" - node.Sysctls["net.ipv6.conf.default.accept_dad"] = "0" - node.Sysctls["net.ipv6.conf.all.autoconf"] = "0" - node.Sysctls["net.ipv6.conf.default.autoconf"] = "0" + nodeCfg.Sysctls = make(map[string]string) + nodeCfg.Sysctls["net.ipv4.ip_forward"] = "0" + nodeCfg.Sysctls["net.ipv6.conf.all.disable_ipv6"] = "0" + nodeCfg.Sysctls["net.ipv6.conf.all.accept_dad"] = "0" + nodeCfg.Sysctls["net.ipv6.conf.default.accept_dad"] = "0" + nodeCfg.Sysctls["net.ipv6.conf.all.autoconf"] = "0" + nodeCfg.Sysctls["net.ipv6.conf.default.autoconf"] = "0" // we mount a fixed path node.Labdir/license.key as the license referenced in topo file will be copied to that path // in (c *cLab) CreateNodeDirStructure - node.Binds = append(node.Binds, fmt.Sprint(filepath.Join(node.LabDir, "license.key"), ":/opt/srlinux/etc/license.key:ro")) + nodeCfg.Binds = append(nodeCfg.Binds, fmt.Sprint(filepath.Join(nodeCfg.LabDir, "license.key"), ":/opt/srlinux/etc/license.key:ro")) // mount config directory - cfgPath := filepath.Join(node.LabDir, "config") - node.Binds = append(node.Binds, fmt.Sprint(cfgPath, ":/etc/opt/srlinux/:rw")) + cfgPath := filepath.Join(nodeCfg.LabDir, "config") + nodeCfg.Binds = append(nodeCfg.Binds, fmt.Sprint(cfgPath, ":/etc/opt/srlinux/:rw")) // mount srlinux.conf - srlconfPath := filepath.Join(node.LabDir, "srlinux.conf") - node.Binds = append(node.Binds, fmt.Sprint(srlconfPath, ":/home/admin/.srlinux.conf:rw")) + srlconfPath := filepath.Join(nodeCfg.LabDir, "srlinux.conf") + nodeCfg.Binds = append(nodeCfg.Binds, fmt.Sprint(srlconfPath, ":/home/admin/.srlinux.conf:rw")) // mount srlinux topology - topoPath := filepath.Join(node.LabDir, "topology.yml") - node.Binds = append(node.Binds, fmt.Sprint(topoPath, ":/tmp/topology.yml:ro")) + topoPath := filepath.Join(nodeCfg.LabDir, "topology.yml") + nodeCfg.Binds = append(nodeCfg.Binds, fmt.Sprint(topoPath, ":/tmp/topology.yml:ro")) return err } -func (c *CLab) createSRLFiles(node *types.Node) error { +func (c *CLab) createSRLFiles(node *types.NodeConfig) error { log.Debugf("Creating directory structure for SRL container: %s", node.ShortName) var src string var dst string diff --git a/clab/vr-csr.go b/clab/vr-csr.go index 8d86257e6..fae299cab 100644 --- a/clab/vr-csr.go +++ b/clab/vr-csr.go @@ -8,15 +8,19 @@ import ( "fmt" "github.com/srl-labs/containerlab/types" + "github.com/srl-labs/containerlab/utils" ) -func initVrCSRNode(c *CLab, nodeCfg NodeConfig, node *types.Node, user string, envs map[string]string) error { +func initVrCSRNode(c *CLab, nodeDef *types.NodeDefinition, nodeCfg *types.NodeConfig, user string, envs map[string]string) error { var err error - node.Image = c.imageInitialization(&nodeCfg, node.Kind) - node.Group = c.groupInitialization(&nodeCfg, node.Kind) - node.Position = c.positionInitialization(&nodeCfg, node.Kind) - node.User = user + // 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 // env vars are used to set launch.py arguments in vrnetlab container defEnv := map[string]string{ @@ -26,14 +30,14 @@ func initVrCSRNode(c *CLab, nodeCfg NodeConfig, node *types.Node, user string, e "DOCKER_NET_V4_ADDR": c.Config.Mgmt.IPv4Subnet, "DOCKER_NET_V6_ADDR": c.Config.Mgmt.IPv6Subnet, } - node.Env = mergeStringMaps(defEnv, envs) + nodeCfg.Env = utils.MergeStringMaps(defEnv, envs) - if node.Env["CONNECTION_MODE"] == "macvtap" { + if nodeCfg.Env["CONNECTION_MODE"] == "macvtap" { // mount dev dir to enable macvtap - node.Binds = append(node.Binds, "/dev:/dev") + nodeCfg.Binds = append(nodeCfg.Binds, "/dev:/dev") } - node.Cmd = fmt.Sprintf("--username %s --password %s --hostname %s --connection-mode %s --trace", node.Env["USERNAME"], node.Env["PASSWORD"], node.ShortName, node.Env["CONNECTION_MODE"]) + nodeCfg.Cmd = fmt.Sprintf("--username %s --password %s --hostname %s --connection-mode %s --trace", nodeCfg.Env["USERNAME"], nodeCfg.Env["PASSWORD"], nodeCfg.ShortName, nodeCfg.Env["CONNECTION_MODE"]) return err } diff --git a/clab/vr-ros.go b/clab/vr-ros.go index ffa570c1c..dca4455f7 100644 --- a/clab/vr-ros.go +++ b/clab/vr-ros.go @@ -8,15 +8,19 @@ import ( "fmt" "github.com/srl-labs/containerlab/types" + "github.com/srl-labs/containerlab/utils" ) -func initVrROSNode(c *CLab, nodeCfg NodeConfig, node *types.Node, user string, envs map[string]string) error { +func initVrROSNode(c *CLab, nodeDef *types.NodeDefinition, nodeCfg *types.NodeConfig, user string, envs map[string]string) error { var err error - node.Image = c.imageInitialization(&nodeCfg, node.Kind) - node.Group = c.groupInitialization(&nodeCfg, node.Kind) - node.Position = c.positionInitialization(&nodeCfg, node.Kind) - node.User = user + // 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 // env vars are used to set launch.py arguments in vrnetlab container defEnv := map[string]string{ @@ -26,14 +30,14 @@ func initVrROSNode(c *CLab, nodeCfg NodeConfig, node *types.Node, user string, e "DOCKER_NET_V4_ADDR": c.Config.Mgmt.IPv4Subnet, "DOCKER_NET_V6_ADDR": c.Config.Mgmt.IPv6Subnet, } - node.Env = mergeStringMaps(defEnv, envs) + nodeCfg.Env = utils.MergeStringMaps(defEnv, envs) - if node.Env["CONNECTION_MODE"] == "macvtap" { + if nodeCfg.Env["CONNECTION_MODE"] == "macvtap" { // mount dev dir to enable macvtap - node.Binds = append(node.Binds, "/dev:/dev") + nodeCfg.Binds = append(nodeCfg.Binds, "/dev:/dev") } - node.Cmd = fmt.Sprintf("--username %s --password %s --hostname %s --connection-mode %s --trace", node.Env["USERNAME"], node.Env["PASSWORD"], node.ShortName, node.Env["CONNECTION_MODE"]) + nodeCfg.Cmd = fmt.Sprintf("--username %s --password %s --hostname %s --connection-mode %s --trace", nodeCfg.Env["USERNAME"], nodeCfg.Env["PASSWORD"], nodeCfg.ShortName, nodeCfg.Env["CONNECTION_MODE"]) return err } diff --git a/clab/vr-sros.go b/clab/vr-sros.go index d12fc3ec5..b2cf9bfac 100644 --- a/clab/vr-sros.go +++ b/clab/vr-sros.go @@ -13,26 +13,34 @@ import ( "github.com/srl-labs/containerlab/utils" ) -func initSROSNode(c *CLab, nodeCfg NodeConfig, node *types.Node, user string, envs map[string]string) error { +func initSROSNode(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) + // nodeCfg.Config, err = c.configInit(nodeDef, nodeCfg.Kind) + c.Config.Topology.GetNodeConfig(nodeCfg.ShortName) if err != nil { return err } - node.Image = c.imageInitialization(&nodeCfg, node.Kind) - node.Group = c.groupInitialization(&nodeCfg, node.Kind) - node.Position = c.positionInitialization(&nodeCfg, node.Kind) - node.User = user + // 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) - node.NodeType = c.typeInit(&nodeCfg, node.Kind) - + 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(&nodeCfg, node) + // lp, err := c.licenseInit(nodeDef, nodeCfg) + lp, err := c.Config.Topology.GetNodeLicense(nodeCfg.ShortName) if err != nil { return err } - node.License = lp + nodeCfg.License = lp // env vars are used to set launch.py arguments in vrnetlab container defEnv := map[string]string{ @@ -40,23 +48,23 @@ func initSROSNode(c *CLab, nodeCfg NodeConfig, node *types.Node, user string, en "DOCKER_NET_V4_ADDR": c.Config.Mgmt.IPv4Subnet, "DOCKER_NET_V6_ADDR": c.Config.Mgmt.IPv6Subnet, } - node.Env = mergeStringMaps(defEnv, envs) + nodeCfg.Env = utils.MergeStringMaps(defEnv, envs) // mount tftpboot dir - node.Binds = append(node.Binds, fmt.Sprint(path.Join(node.LabDir, "tftpboot"), ":/tftpboot")) - if node.Env["CONNECTION_MODE"] == "macvtap" { + nodeCfg.Binds = append(nodeCfg.Binds, fmt.Sprint(path.Join(nodeCfg.LabDir, "tftpboot"), ":/tftpboot")) + if nodeCfg.Env["CONNECTION_MODE"] == "macvtap" { // mount dev dir to enable macvtap - node.Binds = append(node.Binds, "/dev:/dev") + nodeCfg.Binds = append(nodeCfg.Binds, "/dev:/dev") } - node.Cmd = fmt.Sprintf("--trace --connection-mode %s --hostname %s --variant \"%s\"", node.Env["CONNECTION_MODE"], - node.ShortName, - node.NodeType, + nodeCfg.Cmd = fmt.Sprintf("--trace --connection-mode %s --hostname %s --variant \"%s\"", nodeCfg.Env["CONNECTION_MODE"], + nodeCfg.ShortName, + nodeCfg.NodeType, ) return err } -func (c *CLab) createVrSROSFiles(node *types.Node) error { +func (c *CLab) createVrSROSFiles(node *types.NodeConfig) error { // create config directory that will be bind mounted to vrnetlab container at / path utils.CreateDirectory(path.Join(node.LabDir, "tftpboot"), 0777) diff --git a/clab/vr-veos.go b/clab/vr-veos.go index 673609648..20a7e9ecd 100644 --- a/clab/vr-veos.go +++ b/clab/vr-veos.go @@ -8,15 +8,18 @@ import ( "fmt" "github.com/srl-labs/containerlab/types" + "github.com/srl-labs/containerlab/utils" ) -func initVrVeosNode(c *CLab, nodeCfg NodeConfig, node *types.Node, user string, envs map[string]string) error { +func initVrVeosNode(c *CLab, nodeDef *types.NodeDefinition, nodeCfg *types.NodeConfig, user string, envs map[string]string) error { var err error - - node.Image = c.imageInitialization(&nodeCfg, node.Kind) - node.Group = c.groupInitialization(&nodeCfg, node.Kind) - node.Position = c.positionInitialization(&nodeCfg, node.Kind) - node.User = user + // 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 // env vars are used to set launch.py arguments in vrnetlab container defEnv := map[string]string{ @@ -26,14 +29,14 @@ func initVrVeosNode(c *CLab, nodeCfg NodeConfig, node *types.Node, user string, "DOCKER_NET_V4_ADDR": c.Config.Mgmt.IPv4Subnet, "DOCKER_NET_V6_ADDR": c.Config.Mgmt.IPv6Subnet, } - node.Env = mergeStringMaps(defEnv, envs) + nodeCfg.Env = utils.MergeStringMaps(defEnv, envs) - if node.Env["CONNECTION_MODE"] == "macvtap" { + if nodeCfg.Env["CONNECTION_MODE"] == "macvtap" { // mount dev dir to enable macvtap - node.Binds = append(node.Binds, "/dev:/dev") + nodeCfg.Binds = append(nodeCfg.Binds, "/dev:/dev") } - node.Cmd = fmt.Sprintf("--username %s --password %s --hostname %s --connection-mode %s --trace", node.Env["USERNAME"], node.Env["PASSWORD"], node.ShortName, node.Env["CONNECTION_MODE"]) + nodeCfg.Cmd = fmt.Sprintf("--username %s --password %s --hostname %s --connection-mode %s --trace", nodeCfg.Env["USERNAME"], nodeCfg.Env["PASSWORD"], nodeCfg.ShortName, nodeCfg.Env["CONNECTION_MODE"]) return err } diff --git a/clab/vr-vmx.go b/clab/vr-vmx.go index 58731bd5d..adaea54ad 100644 --- a/clab/vr-vmx.go +++ b/clab/vr-vmx.go @@ -8,14 +8,18 @@ import ( "fmt" "github.com/srl-labs/containerlab/types" + "github.com/srl-labs/containerlab/utils" ) -func initVrVMXNode(c *CLab, nodeCfg NodeConfig, node *types.Node, user string, envs map[string]string) error { +func initVrVMXNode(c *CLab, nodeDef *types.NodeDefinition, nodeCfg *types.NodeConfig, user string, envs map[string]string) error { var err error - node.Image = c.imageInitialization(&nodeCfg, node.Kind) - node.Group = c.groupInitialization(&nodeCfg, node.Kind) - node.Position = c.positionInitialization(&nodeCfg, node.Kind) - node.User = user + // 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 // env vars are used to set launch.py arguments in vrnetlab container defEnv := map[string]string{ @@ -25,14 +29,14 @@ func initVrVMXNode(c *CLab, nodeCfg NodeConfig, node *types.Node, user string, e "DOCKER_NET_V4_ADDR": c.Config.Mgmt.IPv4Subnet, "DOCKER_NET_V6_ADDR": c.Config.Mgmt.IPv6Subnet, } - node.Env = mergeStringMaps(defEnv, envs) + nodeCfg.Env = utils.MergeStringMaps(defEnv, envs) - if node.Env["CONNECTION_MODE"] == "macvtap" { + if nodeCfg.Env["CONNECTION_MODE"] == "macvtap" { // mount dev dir to enable macvtap - node.Binds = append(node.Binds, "/dev:/dev") + nodeCfg.Binds = append(nodeCfg.Binds, "/dev:/dev") } - node.Cmd = fmt.Sprintf("--username %s --password %s --hostname %s --connection-mode %s --trace", node.Env["USERNAME"], node.Env["PASSWORD"], node.ShortName, node.Env["CONNECTION_MODE"]) + nodeCfg.Cmd = fmt.Sprintf("--username %s --password %s --hostname %s --connection-mode %s --trace", nodeCfg.Env["USERNAME"], nodeCfg.Env["PASSWORD"], nodeCfg.ShortName, nodeCfg.Env["CONNECTION_MODE"]) return err } diff --git a/clab/vr-xrv.go b/clab/vr-xrv.go index 9a648f27c..515d32b8f 100644 --- a/clab/vr-xrv.go +++ b/clab/vr-xrv.go @@ -8,15 +8,19 @@ import ( "fmt" "github.com/srl-labs/containerlab/types" + "github.com/srl-labs/containerlab/utils" ) -func initVrXRVNode(c *CLab, nodeCfg NodeConfig, node *types.Node, user string, envs map[string]string) error { +func initVrXRVNode(c *CLab, nodeDef *types.NodeDefinition, nodeCfg *types.NodeConfig, user string, envs map[string]string) error { var err error - node.Image = c.imageInitialization(&nodeCfg, node.Kind) - node.Group = c.groupInitialization(&nodeCfg, node.Kind) - node.Position = c.positionInitialization(&nodeCfg, node.Kind) - node.User = user + // 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 // env vars are used to set launch.py arguments in vrnetlab container defEnv := map[string]string{ @@ -26,14 +30,14 @@ func initVrXRVNode(c *CLab, nodeCfg NodeConfig, node *types.Node, user string, e "DOCKER_NET_V4_ADDR": c.Config.Mgmt.IPv4Subnet, "DOCKER_NET_V6_ADDR": c.Config.Mgmt.IPv6Subnet, } - node.Env = mergeStringMaps(defEnv, envs) + nodeCfg.Env = utils.MergeStringMaps(defEnv, envs) - if node.Env["CONNECTION_MODE"] == "macvtap" { + if nodeCfg.Env["CONNECTION_MODE"] == "macvtap" { // mount dev dir to enable macvtap - node.Binds = append(node.Binds, "/dev:/dev") + nodeCfg.Binds = append(nodeCfg.Binds, "/dev:/dev") } - node.Cmd = fmt.Sprintf("--username %s --password %s --hostname %s --connection-mode %s --trace", node.Env["USERNAME"], node.Env["PASSWORD"], node.ShortName, node.Env["CONNECTION_MODE"]) + nodeCfg.Cmd = fmt.Sprintf("--username %s --password %s --hostname %s --connection-mode %s --trace", nodeCfg.Env["USERNAME"], nodeCfg.Env["PASSWORD"], nodeCfg.ShortName, nodeCfg.Env["CONNECTION_MODE"]) return err } diff --git a/clab/vr-xrv9k.go b/clab/vr-xrv9k.go index cae87757e..d90a69040 100644 --- a/clab/vr-xrv9k.go +++ b/clab/vr-xrv9k.go @@ -8,15 +8,19 @@ import ( "fmt" "github.com/srl-labs/containerlab/types" + "github.com/srl-labs/containerlab/utils" ) -func initVrXRV9kNode(c *CLab, nodeCfg NodeConfig, node *types.Node, user string, envs map[string]string) error { +func initVrXRV9kNode(c *CLab, nodeDef *types.NodeDefinition, nodeCfg *types.NodeConfig, user string, envs map[string]string) error { var err error - node.Image = c.imageInitialization(&nodeCfg, node.Kind) - node.Group = c.groupInitialization(&nodeCfg, node.Kind) - node.Position = c.positionInitialization(&nodeCfg, node.Kind) - node.User = user + // 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 // env vars are used to set launch.py arguments in vrnetlab container defEnv := map[string]string{ @@ -28,14 +32,14 @@ func initVrXRV9kNode(c *CLab, nodeCfg NodeConfig, node *types.Node, user string, "DOCKER_NET_V4_ADDR": c.Config.Mgmt.IPv4Subnet, "DOCKER_NET_V6_ADDR": c.Config.Mgmt.IPv6Subnet, } - node.Env = mergeStringMaps(defEnv, envs) + nodeCfg.Env = utils.MergeStringMaps(defEnv, envs) - if node.Env["CONNECTION_MODE"] == "macvtap" { + if nodeCfg.Env["CONNECTION_MODE"] == "macvtap" { // mount dev dir to enable macvtap - node.Binds = append(node.Binds, "/dev:/dev") + nodeCfg.Binds = append(nodeCfg.Binds, "/dev:/dev") } - node.Cmd = fmt.Sprintf("--username %s --password %s --hostname %s --connection-mode %s --vcpu %s --ram %s --trace", node.Env["USERNAME"], node.Env["PASSWORD"], node.ShortName, node.Env["CONNECTION_MODE"], node.Env["VCPU"], node.Env["RAM"]) + nodeCfg.Cmd = fmt.Sprintf("--username %s --password %s --hostname %s --connection-mode %s --vcpu %s --ram %s --trace", nodeCfg.Env["USERNAME"], nodeCfg.Env["PASSWORD"], nodeCfg.ShortName, nodeCfg.Env["CONNECTION_MODE"], nodeCfg.Env["VCPU"], nodeCfg.Env["RAM"]) return err } diff --git a/cmd/deploy.go b/cmd/deploy.go index 9b6b60d66..55c0ef97e 100644 --- a/cmd/deploy.go +++ b/cmd/deploy.go @@ -151,7 +151,7 @@ var deployCmd = &cobra.Command{ var wg sync.WaitGroup wg.Add(len(c.Nodes)) for _, node := range c.Nodes { - go func(node *types.Node) { + go func(node *types.NodeConfig) { defer wg.Done() err := c.ExecPostDeployTasks(ctx, node, linksMaxWorkers) if err != nil { @@ -254,7 +254,7 @@ func hostsEntries(containers []types.GenericContainer, bridgeName string) []byte return buff.Bytes() } -func enrichNodes(containers []types.GenericContainer, nodes map[string]*types.Node, mgmtNet string) { +func enrichNodes(containers []types.GenericContainer, nodes map[string]*types.NodeConfig, mgmtNet string) { for _, c := range containers { name = c.Labels["clab-node-name"] if node, ok := nodes[name]; ok { diff --git a/cmd/generate.go b/cmd/generate.go index 2285b33f3..e4b584c60 100644 --- a/cmd/generate.go +++ b/cmd/generate.go @@ -135,9 +135,9 @@ func generateTopologyConfig(name, network, ipv4range, ipv6range string, images m config := &clab.Config{ Name: name, Mgmt: new(types.MgmtNet), - Topology: clab.Topology{ - Kinds: make(map[string]clab.NodeConfig), - Nodes: make(map[string]clab.NodeConfig), + Topology: &types.Topology{ + Kinds: make(map[string]*types.NodeDefinition), + Nodes: make(map[string]*types.NodeDefinition), }, } config.Mgmt.Network = network @@ -148,7 +148,7 @@ func generateTopologyConfig(name, network, ipv4range, ipv6range string, images m config.Mgmt.IPv6Subnet = ipv6range } for k, img := range images { - config.Topology.Kinds[k] = clab.NodeConfig{Image: img} + config.Topology.Kinds[k] = &types.NodeDefinition{Image: img} } for k, lic := range licenses { if knd, ok := config.Topology.Kinds[k]; ok { @@ -156,13 +156,13 @@ func generateTopologyConfig(name, network, ipv4range, ipv6range string, images m config.Topology.Kinds[k] = knd continue } - config.Topology.Kinds[k] = clab.NodeConfig{License: lic} + config.Topology.Kinds[k] = &types.NodeDefinition{License: lic} } if numStages == 1 { for j := uint(0); j < nodes[0].numNodes; j++ { node1 := fmt.Sprintf("%s1-%d", nodePrefix, j+1) if _, ok := config.Topology.Nodes[node1]; !ok { - config.Topology.Nodes[node1] = clab.NodeConfig{ + config.Topology.Nodes[node1] = &types.NodeDefinition{ Group: fmt.Sprintf("%s-1", groupPrefix), Kind: nodes[0].kind, Type: nodes[0].typ, @@ -178,7 +178,7 @@ func generateTopologyConfig(name, network, ipv4range, ipv6range string, images m for j := uint(0); j < nodes[i].numNodes; j++ { node1 := fmt.Sprintf("%s%d-%d", nodePrefix, i+1, j+1) if _, ok := config.Topology.Nodes[node1]; !ok { - config.Topology.Nodes[node1] = clab.NodeConfig{ + config.Topology.Nodes[node1] = &types.NodeDefinition{ Group: fmt.Sprintf("%s-%d", groupPrefix, i+1), Kind: nodes[i].kind, Type: nodes[i].typ, @@ -187,13 +187,13 @@ func generateTopologyConfig(name, network, ipv4range, ipv6range string, images m for k := uint(0); k < nodes[i+1].numNodes; k++ { node2 := fmt.Sprintf("%s%d-%d", nodePrefix, i+2, k+1) if _, ok := config.Topology.Nodes[node2]; !ok { - config.Topology.Nodes[node2] = clab.NodeConfig{ + config.Topology.Nodes[node2] = &types.NodeDefinition{ Group: fmt.Sprintf("%s-%d", groupPrefix, i+2), Kind: nodes[i+1].kind, Type: nodes[i+1].typ, } } - config.Topology.Links = append(config.Topology.Links, clab.LinkConfig{ + config.Topology.Links = append(config.Topology.Links, &types.LinkConfig{ Endpoints: []string{ node1 + ":" + fmt.Sprintf(interfaceFormat[nodes[i].kind], k+1+interfaceOffset), node2 + ":" + fmt.Sprintf(interfaceFormat[nodes[i+1].kind], j+1), diff --git a/cmd/tools_veth.go b/cmd/tools_veth.go index c770e44eb..3a40cb82e 100644 --- a/cmd/tools_veth.go +++ b/cmd/tools_veth.go @@ -58,14 +58,14 @@ var vethCreateCmd = &cobra.Command{ return err } - aNode := &types.Node{ + aNode := &types.NodeConfig{ LongName: vethAEndpoint.node, ShortName: vethAEndpoint.node, Kind: vethAEndpoint.kind, NSPath: "__host", // NSPath defaults to __host to make attachment to host. For attachment to containers the NSPath will be overwritten } - bNode := &types.Node{ + bNode := &types.NodeConfig{ LongName: vethBEndpoint.node, ShortName: vethBEndpoint.node, Kind: vethBEndpoint.kind, diff --git a/go.mod b/go.mod index 8aa573f65..0a8745091 100644 --- a/go.mod +++ b/go.mod @@ -22,7 +22,7 @@ require ( github.com/morikuni/aec v1.0.0 // indirect github.com/olekukonko/tablewriter v0.0.5-0.20201029120751-42e21c7531a3 github.com/opencontainers/runtime-spec v1.0.3-0.20210303205135-43e4633e40c1 - github.com/pkg/errors v0.9.1 // indirect + github.com/pkg/errors v0.9.1 github.com/sirupsen/logrus v1.8.1 github.com/spf13/cobra v1.0.0 github.com/vishvananda/netlink v1.1.1-0.20210330154013-f5de75959ad5 diff --git a/go.sum b/go.sum index 80a8dab5b..da3580ec3 100644 --- a/go.sum +++ b/go.sum @@ -36,6 +36,7 @@ github.com/Azure/go-autorest/autorest/mocks v0.4.0/go.mod h1:LTp+uSrOhSkaKrUy935 github.com/Azure/go-autorest/autorest/mocks v0.4.1/go.mod h1:LTp+uSrOhSkaKrUy935gNZuuIPPVsHlr9DSOxSayd+k= github.com/Azure/go-autorest/logger v0.2.0/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZmbF5NWuPV8+WeEW8= github.com/Azure/go-autorest/tracing v0.6.0/go.mod h1:+vhtPC754Xsa23ID7GlGsrdKBpUA79WCAKPPZVC2DeU= +github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/GeertJohan/go.incremental v1.0.0/go.mod h1:6fAjUhbVuX1KcMD3c8TEgVUqmo4seqhv0i0kdATSkM0= @@ -72,13 +73,11 @@ github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuy github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alexflint/go-filemutex v0.0.0-20171022225611-72bdc8eae2ae/go.mod h1:CgnQgUtFrFz9mxFNtED3jI5tLDjKlOM+oUF/sTk6ps0= -github.com/alexflint/go-filemutex v1.1.0/go.mod h1:7P4iRhttt/nUvUOrYIhcpMzv2G6CY9UnI16Z+UJqRyk= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY= github.com/awalterschulze/gographviz v2.0.1+incompatible h1:XIECBRq9VPEQqkQL5pw2OtjCAdrtIgFKoJU8eT98AS8= github.com/awalterschulze/gographviz v2.0.1+incompatible/go.mod h1:GEV5wmg4YquNw7v1kkyoX9etIk8yVmXj+AkDHuuETHs= github.com/aws/aws-sdk-go v1.15.11/go.mod h1:mFuSZ37Z9YOHbQEwBWztmVzqXrEkub65tZoCYDt7FT0= -github.com/aws/aws-sdk-go v1.34.9/go.mod h1:5zCpMtNQVjRREroY7sYe8lOMRSxkhG6MZveU8YkpAk0= github.com/beorn7/perks v0.0.0-20160804104726-4c0e84591b9a/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= @@ -90,9 +89,7 @@ github.com/blang/semver v3.1.0+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnweb github.com/blang/semver v3.5.1+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk= github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869/go.mod h1:Ekp36dRnpXw/yCqJaO+ZrUyxD+3VXMFFr56k5XYrpB4= github.com/bshuster-repo/logrus-logstash-hook v0.4.1/go.mod h1:zsTqEiSzDgAa/8GZR7E1qaXrhYNDKBYy5/dWPTIflbk= -github.com/bshuster-repo/logrus-logstash-hook v1.0.0/go.mod h1:zsTqEiSzDgAa/8GZR7E1qaXrhYNDKBYy5/dWPTIflbk= github.com/buger/jsonparser v0.0.0-20180808090653-f4dd9f5a6b44/go.mod h1:bbYlZJ7hK1yFx9hf58LP0zeX7UjIGs20ufpu3evjr+s= -github.com/buger/jsonparser v1.1.1/go.mod h1:6RYKKt7H4d4+iWqouImQ9R2FZql3VbhNgx27UK13J/0= github.com/bugsnag/bugsnag-go v0.0.0-20141110184014-b1d153021fcd/go.mod h1:2oa8nejYd4cQ/b0hMIopN0lCRxU0bueqREvZLWFrtK8= github.com/bugsnag/osext v0.0.0-20130617224835-0dd3f918b21b/go.mod h1:obH5gd0BsqsP2LwDJ9aOkm/6J86V6lyAXCoQWGw3K50= github.com/bugsnag/panicwrap v0.0.0-20151223152923-e2c28503fcd0/go.mod h1:D/8v3kj0zr8ZAKg1AQ6crr+5VwKN5eIywRkfhyM/+dE= @@ -117,10 +114,7 @@ github.com/cloudflare/cfssl v1.4.1/go.mod h1:KManx/OJPb5QY+y0+o/898AMcM128sF0bUR github.com/cloudflare/go-metrics v0.0.0-20151117154305-6a9aea36fb41/go.mod h1:eaZPlJWD+G9wseg1BuRXlHnjntPMrywMsyxf+LTOdP4= github.com/cloudflare/redoctober v0.0.0-20171127175943-746a508df14c/go.mod h1:6Se34jNoqrd8bTxrmJB2Bg2aoZ2CdSXonils9NsiNgo= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= -github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8= -github.com/compose-spec/compose-go v0.0.0-20210420125800-01e9e6b4c64c h1:kD6gVZH6fmAHOj32kxApucNKCsUu09L/+OZpYSrKn5s= -github.com/compose-spec/compose-go v0.0.0-20210420125800-01e9e6b4c64c/go.mod h1:6eIT9U2OgdHmkRD6szmqatCrWWEEUSwl/j2iJYH4jLo= github.com/containerd/aufs v0.0.0-20200908144142-dab0cbea06f4/go.mod h1:nukgQABAEopAHvB6j7cnP5zJ+/3aVcE7hCYqvIwAHyE= github.com/containerd/aufs v0.0.0-20201003224125-76a6863f2989/go.mod h1:AkGGQs9NM2vtYHaUen+NljV0/baGCAPELGm2q9ZXpWU= github.com/containerd/aufs v0.0.0-20210316121734-20793ff83c97/go.mod h1:kL5kd6KM5TzQjR79jljyi4olc1Vrx6XBlcyj3gNv2PU= @@ -154,10 +148,6 @@ github.com/containerd/containerd v1.5.0-beta.1/go.mod h1:5HfvG1V2FsKesEGQ17k5/T7 github.com/containerd/containerd v1.5.0-beta.3/go.mod h1:/wr9AVtEM7x9c+n0+stptlo/uBBoBORwEx6ardVcmKU= github.com/containerd/containerd v1.5.0-beta.4/go.mod h1:GmdgZd2zA2GYIBZ0w09ZvgqEq8EfBp/m3lcVZIvPHhI= github.com/containerd/containerd v1.5.0-rc.0/go.mod h1:V/IXoMqNGgBlabz3tHD2TWDoTJseu1FGOKuoA4nNb2s= -github.com/containerd/containerd v1.5.0 h1:p9b9VlMObAOuIuZ3EakDGMsq8V59VBlTXi8b8DCLa6o= -github.com/containerd/containerd v1.5.0/go.mod h1:kYiJ+LvywDUKzyax6+UKCk5xwQNCfcGR6KsSdShdg5U= -github.com/containerd/containerd v1.5.1 h1:xWHPAoe6VkUiI9GAvndJM7s/0MTrmwX3AQiYTr3olf0= -github.com/containerd/containerd v1.5.1/go.mod h1:0DOxVqwDy2iZvrZp2JUx/E+hS0UNTVn7dJnIOwtYR4g= github.com/containerd/containerd v1.5.2 h1:MG/Bg1pbmMb61j3wHCFWPxESXHieiKr2xG64px/k8zQ= github.com/containerd/containerd v1.5.2/go.mod h1:0DOxVqwDy2iZvrZp2JUx/E+hS0UNTVn7dJnIOwtYR4g= github.com/containerd/continuity v0.0.0-20190426062206-aaeac12a7ffc/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y= @@ -177,8 +167,6 @@ github.com/containerd/fifo v1.0.0 h1:6PirWBr9/L7GDamKr+XM0IeUFXu5mf3M/BPpH9gaLBU github.com/containerd/fifo v1.0.0/go.mod h1:ocF/ME1SX5b1AOlWi9r677YJmCPSwwWnQ9O123vzpE4= github.com/containerd/go-cni v1.0.1/go.mod h1:+vUpYxKvAF72G9i1WoDOiPGRtQpqsNW/ZHtSlv++smU= github.com/containerd/go-cni v1.0.2/go.mod h1:nrNABBHzu0ZwCug9Ije8hL2xBCYh/pjfMb1aZGrrohk= -github.com/containerd/go-cni v1.0.3-0.20210427061315-4efee5f0b4db h1:5nHa+ymnvI9mUui+H84Ovvh9mteXD3SeGMv8TOMbirw= -github.com/containerd/go-cni v1.0.3-0.20210427061315-4efee5f0b4db/go.mod h1:nrNABBHzu0ZwCug9Ije8hL2xBCYh/pjfMb1aZGrrohk= github.com/containerd/go-runc v0.0.0-20180907222934-5a6d9f37cfa3/go.mod h1:IV7qH3hrUgRmyYrtgEeGWJfWbgcHL9CSRruz2Vqcph0= github.com/containerd/go-runc v0.0.0-20190911050354-e029b79d8cda/go.mod h1:IV7qH3hrUgRmyYrtgEeGWJfWbgcHL9CSRruz2Vqcph0= github.com/containerd/go-runc v0.0.0-20200220073739-7016d3ce2328/go.mod h1:PpyHrqVs8FTi9vpyHwPwiNEGaACDxT/N/pLcvMSRA9g= @@ -189,15 +177,9 @@ github.com/containerd/imgcrypt v1.0.4-0.20210301171431-0ae5c75f59ba/go.mod h1:6T github.com/containerd/imgcrypt v1.1.1-0.20210312161619-7ed62a527887/go.mod h1:5AZJNI6sLHJljKuI9IHnw1pWqo/F0nGDOuR9zgTs7ow= github.com/containerd/imgcrypt v1.1.1 h1:LBwiTfoUsdiEGAR1TpvxE+Gzt7469oVu87iR3mv3Byc= github.com/containerd/imgcrypt v1.1.1/go.mod h1:xpLnwiQmEUJPvQoAapeb2SNCxz7Xr6PJrXQb0Dpc4ms= -github.com/containerd/nerdctl v0.8.2 h1:etaBerH89nAx8hGQD12EnkCJ40LeTfs9ulRp9Q9tbZI= -github.com/containerd/nerdctl v0.8.2/go.mod h1:m52DjCYyZbVR7E3nuNCUYdyjktq7KEekcj4G56U6J/w= github.com/containerd/nri v0.0.0-20201007170849-eb1350a75164/go.mod h1:+2wGSDGFYfE5+So4M5syatU0N0f0LbWpuqyMi4/BE8c= github.com/containerd/nri v0.0.0-20210316161719-dbaa18c31c14/go.mod h1:lmxnXF6oMkbqs39FiCt1s0R2HSMhcLel9vNL3m4AaeY= github.com/containerd/nri v0.1.0/go.mod h1:lmxnXF6oMkbqs39FiCt1s0R2HSMhcLel9vNL3m4AaeY= -github.com/containerd/stargz-snapshotter v0.6.0 h1:/mNpDq+iD3bFOymaceI5YWZ8V5OjinmfZmrwi2n792U= -github.com/containerd/stargz-snapshotter v0.6.0/go.mod h1:EW78+RcA6kw8UbsTRXeLn5L/6PZxXCB7RawHE9HC1Aw= -github.com/containerd/stargz-snapshotter/estargz v0.6.0 h1:YTaJU7Dne7+qTDJ8s1WJtDk2/f/EYOX849ncH8Pangc= -github.com/containerd/stargz-snapshotter/estargz v0.6.0/go.mod h1:EWzzlJ+yd7i8d4MtDmdOm4m6eG7/jr3T4frIjJPnwbc= github.com/containerd/ttrpc v0.0.0-20190828154514-0e0f228740de/go.mod h1:PvCDdDGpgqzQIzDW1TphrGLssLDZp2GuS+X5DkEJB8o= github.com/containerd/ttrpc v0.0.0-20190828172938-92c8520ef9f8/go.mod h1:PvCDdDGpgqzQIzDW1TphrGLssLDZp2GuS+X5DkEJB8o= github.com/containerd/ttrpc v0.0.0-20191028202541-4f1b8fe65a5c/go.mod h1:LPm1u0xBw8r8NOKoOdNMeVHSawSsltak+Ihv+etqsE8= @@ -218,13 +200,9 @@ github.com/containernetworking/cni v0.7.1/go.mod h1:LGwApLUm2FpoOfxTDEeq8T9ipbpZ github.com/containernetworking/cni v0.8.0/go.mod h1:LGwApLUm2FpoOfxTDEeq8T9ipbpZ61X79hmU3w8FmsY= github.com/containernetworking/cni v0.8.1 h1:7zpDnQ3T3s4ucOuJ/ZCLrYBxzkg0AELFfII3Epo9TmI= github.com/containernetworking/cni v0.8.1/go.mod h1:LGwApLUm2FpoOfxTDEeq8T9ipbpZ61X79hmU3w8FmsY= -github.com/containernetworking/cni v1.0.0-rc1 h1:xgLI0bhFq/nK8PjG0CHQNbaCurmiflapvrY5muVuRfw= -github.com/containernetworking/cni v1.0.0-rc1/go.mod h1:AKuhXbN5EzmD4yTNtfSsX3tPcmtrBI6QcRV0NiNt15Y= github.com/containernetworking/plugins v0.8.6/go.mod h1:qnw5mN19D8fIwkqW7oHHYDHVlzhJpcY6TQxn/fUyDDM= github.com/containernetworking/plugins v0.9.1 h1:FD1tADPls2EEi3flPc2OegIY1M9pUa9r2Quag7HMLV8= github.com/containernetworking/plugins v0.9.1/go.mod h1:xP/idU2ldlzN6m4p5LmGiwRDjeJr6FLK6vuiUwoH7P8= -github.com/containernetworking/plugins v1.0.0-rc1 h1:QUOr/I00pRbtTnhUcgBvlczJCMLStB7wQHYhNltQUjU= -github.com/containernetworking/plugins v1.0.0-rc1/go.mod h1:sOshQjk8XBfjw6BVWt6bGfSZ06OrwiocMpagWmB198k= github.com/containers/ocicrypt v1.0.1/go.mod h1:MeJDzk1RJHv89LjsH0Sp5KTY3ZYkjXO/C+bKAeWFIrc= github.com/containers/ocicrypt v1.1.0/go.mod h1:b8AOe0YR67uU8OqfVNcznfFpAzu3rdgUV4GP9qXPfu4= github.com/containers/ocicrypt v1.1.1 h1:prL8l9w3ntVqXvNH1CiNn5ENjcCnr38JqpSyvKKB4GI= @@ -242,16 +220,12 @@ github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e h1:Wf6HqHfScWJN9 github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/coreos/go-systemd/v22 v22.0.0/go.mod h1:xO0FLkIi5MaZafQlIrOotqXZ90ih+1atmu1JpKERPPk= github.com/coreos/go-systemd/v22 v22.1.0/go.mod h1:xO0FLkIi5MaZafQlIrOotqXZ90ih+1atmu1JpKERPPk= -github.com/coreos/go-systemd/v22 v22.2.0/go.mod h1:xO0FLkIi5MaZafQlIrOotqXZ90ih+1atmu1JpKERPPk= -github.com/coreos/go-systemd/v22 v22.3.1 h1:7OO2CXWMYNDdaAzP51t4lCCZWwpQHmvPbm9sxWjm3So= -github.com/coreos/go-systemd/v22 v22.3.1/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/cpuguy83/go-md2man/v2 v2.0.0 h1:EoUDS0afbrsXAZ9YQ9jdu/mZ2sXgT1/2yyNng4PGlyM= github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= -github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/cyphar/filepath-securejoin v0.2.2 h1:jCwT2GTP+PY5nBz3c/YL5PAIbusElVrPujOBSCj8xRg= github.com/cyphar/filepath-securejoin v0.2.2/go.mod h1:FpkQEhXnPnOthhzymB7CGsFk2G9VLXONKD9G7QGMM+4= github.com/d2g/dhcp4 v0.0.0-20170904100407-a1d1b6c41b1c/go.mod h1:Ct2BUK8SB0YC1SMSibvLzxjeJLnrYEVLULFNiHY9YfQ= @@ -268,19 +242,13 @@ github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZm github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= github.com/digitalocean/go-openvswitch v0.0.0-20201214180534-ce0f183468d8 h1:RQAD2flP6n+U5sAudMpru+EuLJ6VQduu6yenl6LwM5E= github.com/digitalocean/go-openvswitch v0.0.0-20201214180534-ce0f183468d8/go.mod h1:MpzfscrezUxa94/T4sy2tDaxB+hQ6w0EmRBPv+xHWEs= -github.com/distribution/distribution/v3 v3.0.0-20210316161203-a01c71e2477e h1:n81KvOMrLZa+VWHwST7dun9f0G98X3zREHS1ztYzZKU= -github.com/distribution/distribution/v3 v3.0.0-20210316161203-a01c71e2477e/go.mod h1:xpWTC2KnJMiDLkoawhsPQcXjvwATEBcbq0xevG2YR9M= github.com/dnaeon/go-vcr v1.0.1/go.mod h1:aBB1+wY4s93YsC3HHjMBMrwTj2R9FHDzUr9KyGc8n1E= -github.com/docker/cli v20.10.6+incompatible h1:LAyI6Lnwv+AUjtp2ZyN1lxqXBtkeFUqm4H7CZMWZuP8= -github.com/docker/cli v20.10.6+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= github.com/docker/distribution v0.0.0-20190905152932-14b96e55d84c/go.mod h1:0+TTO4EOBfRPhZXAeF1Vu+W3hHZ8eLp8PgKVZlcvtFY= github.com/docker/distribution v2.7.1-0.20190205005809-0d3efadf0154+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= github.com/docker/distribution v2.7.1+incompatible h1:a5mlkVzth6W5A4fOsS3D2EO5BUmsJpcB+cRlLU7cSug= github.com/docker/distribution v2.7.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= github.com/docker/docker v20.10.6+incompatible h1:oXI3Vas8TI8Eu/EjH4srKHJBVqraSzJybhxY7Om9faQ= github.com/docker/docker v20.10.6+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= -github.com/docker/docker-credential-helpers v0.6.3 h1:zI2p9+1NQYdnG6sMU26EX4aVGlqbInSQxQXLvzJ4RPQ= -github.com/docker/docker-credential-helpers v0.6.3/go.mod h1:WRaJzqw3CTB9bk10avuGsjVBZsD05qeibJ1/TYlvc0Y= github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ= github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec= github.com/docker/go-events v0.0.0-20170721190031-9461782956ad/go.mod h1:Uw6UezgYA44ePAFQYUehOuCzmy5zmg/+nl2ZfMWGkpA= @@ -302,14 +270,9 @@ github.com/emicklei/go-restful v2.9.5+incompatible/go.mod h1:otzb+WCGbkyDHkqmQmT github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= -github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/evanphx/json-patch v4.9.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= -github.com/fanliao/go-promise v0.0.0-20141029170127-1890db352a72/go.mod h1:PjfxuH4FZdUyfMdtBio2lsRr1AKEaVPwelzuHuh8Lqc= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= -github.com/fatih/color v1.10.0 h1:s36xzo75JdqLaaWoiEHk767eHiwo0598uUxyfiPkDsg= -github.com/fatih/color v1.10.0/go.mod h1:ELkj/draVOlAH/xkhN6mQ50Qd0MPOk5AAr3maGEBuJM= -github.com/felixge/httpsnoop v1.0.1/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= github.com/form3tech-oss/jwt-go v3.2.2+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k= github.com/frankban/quicktest v1.11.3/go.mod h1:wRf/ReqHper53s+kmmSZizM8NamnL3IM0I9ntUbOk+k= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= @@ -339,16 +302,12 @@ github.com/go-openapi/swag v0.19.2/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= github.com/go-sql-driver/mysql v1.3.0 h1:pgwjLi/dvffoP9aabwkT3AKpXQM93QARkjFhDDqC1UE= github.com/go-sql-driver/mysql v1.3.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= -github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/godbus/dbus v0.0.0-20151105175453-c7fdd8b5cd55/go.mod h1:/YcGZj5zSblfDWMMoOzV4fas9FZnQYTkDnsGvmh2Grw= github.com/godbus/dbus v0.0.0-20180201030542-885f9cc04c9c/go.mod h1:/YcGZj5zSblfDWMMoOzV4fas9FZnQYTkDnsGvmh2Grw= github.com/godbus/dbus v0.0.0-20190422162347-ade71ed3457e h1:BWhy2j3IXJhjCbC68FptL43tDKIq8FladmaTs3Xs7Z8= github.com/godbus/dbus v0.0.0-20190422162347-ade71ed3457e/go.mod h1:bBOAhwG1umN6/6ZUMtDFBMQR8jRg9O75tm9K00oMsK4= github.com/godbus/dbus/v5 v5.0.3/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= -github.com/godbus/dbus/v5 v5.0.4 h1:9349emZab16e7zQvpmsbtjc18ykshndd8y2PG3sgJbA= -github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= -github.com/gofrs/flock v0.8.0/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU= github.com/gogo/googleapis v1.2.0/go.mod h1:Njal3psf3qN6dwBtQfUmBZh2ybovJ0tlu3o/AC7HYjU= github.com/gogo/googleapis v1.4.0 h1:zgVt4UpGxcqVOw97aRGxT4svlcmdK35fynLNctY32zI= github.com/gogo/googleapis v1.4.0/go.mod h1:5YRNX2z1oM5gXdAkurHa942MDgEJyk02w4OecKY87+c= @@ -386,9 +345,6 @@ github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QD github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.4.3 h1:JjCZWpVbqXDqFVmTfYWEVTMIYrL/NPdPSCHPJ0T/raM= github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= -github.com/golang/snappy v0.0.3 h1:fHPg5GQYlCeLIPB9BZqMVR5nR9A+IM5zcgeTdjMYmLA= -github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -github.com/gomodule/redigo v1.8.2/go.mod h1:P9dn9mFrCBvWhGE1wpxx6fgq7BAeLBk+UUUzlpkBYO0= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/certificate-transparency-go v1.0.21 h1:Yf1aXowfZ2nuboBsg7iYGLmwsOARdV86pfH3g95wXmE= @@ -402,7 +358,6 @@ github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.4 h1:L8R9j+yAqZuZjsqh/z+F1NCffTKKLShY6zXTItVIZ8M= github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.6 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ= github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= @@ -426,11 +381,8 @@ github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5m github.com/googleapis/gnostic v0.4.1/go.mod h1:LRhVm6pbyptWbWbuZ38d1eyptfvIytN3ir6b65WBswg= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gorilla/handlers v0.0.0-20150720190736-60c7bfde3e33/go.mod h1:Qkdc/uu4tH4g6mTK6auzZ766c4CA0Ng8+o/OAirnOIQ= -github.com/gorilla/handlers v1.5.1/go.mod h1:t8XrUpc4KVXb7HGyJ4/cEnwQiaxrX/hz1Zv/4g96P1Q= github.com/gorilla/mux v1.7.2 h1:zoNxOV7WjqXptQOVngLmcSQgXmgk4NMz1HibBchjl/I= github.com/gorilla/mux v1.7.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= -github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI= -github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= @@ -440,49 +392,36 @@ github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= -github.com/hanwen/go-fuse v1.0.0/go.mod h1:unqXarDXqzAk0rt98O2tVndEPIpUgLD9+rwFisZH3Ok= -github.com/hanwen/go-fuse/v2 v2.1.0/go.mod h1:oRyA5eK+pvJyv5otpO/DgccS8y/RvYMaO00GgRLGryc= github.com/hashicorp/errwrap v0.0.0-20141028054710-7554cd9344ce/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/go-multierror v0.0.0-20161216184304-ed905158d874/go.mod h1:JMRHfdO9jKNzS/+BTlxCjKNQHg/jZAft8U7LloJvN7I= github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= -github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM= github.com/hashicorp/go-version v1.2.1 h1:zEfKbn2+PDgroKdiOzqiE8rsmLqU2uwi5PB5pBJ3TkI= github.com/hashicorp/go-version v1.2.1/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= -github.com/hashicorp/golang-lru v0.5.3/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= -github.com/hugelgupf/socketpair v0.0.0-20190730060125-05d35a94e714/go.mod h1:2Goc3h8EklBH5mspfHFxBnEoURQCGzQQH1ga9Myjvis= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/imdario/mergo v0.3.5/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= github.com/imdario/mergo v0.3.8/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= github.com/imdario/mergo v0.3.10/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= github.com/imdario/mergo v0.3.11/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= -github.com/imdario/mergo v0.3.12 h1:b6R2BslTbIEToALKP7LxUvijTsNI9TAe80pLWN2g/HU= -github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= -github.com/insomniacslk/dhcp v0.0.0-20210120172423-cc9239ac6294/go.mod h1:TKl4jN3Voofo4UJIicyNhWGp/nlQqQkFxmwIFTvBkKI= github.com/j-keck/arping v0.0.0-20160618110441-2cf9dc699c56/go.mod h1:ymszkNOg6tORTn+6F6j+Jc8TOr5osrynvN6ivFWZ2GA= -github.com/j-keck/arping v1.0.1/go.mod h1:aJbELhR92bSk7tp79AWM/ftfc90EfEi2bQJrbBFOsPw= -github.com/jamescun/tuntap v0.0.0-20190712092105-cb1fb277045c/go.mod h1:zzwpsgcYhzzIP5WyF8g9ivCv38cY9uAV9Gu0m3lThhE= github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= github.com/jmespath/go-jmespath v0.0.0-20160202185014-0b12d6b521d8/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= github.com/jmespath/go-jmespath v0.0.0-20160803190731-bd40a432e4c7/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= -github.com/jmespath/go-jmespath v0.3.0/go.mod h1:9QtRXoHjLGCJ5IBSaohpXITPlowMeeYCZ7fLUTSywik= github.com/jmhodges/clock v0.0.0-20160418191101-880ee4c33548/go.mod h1:hGT6jSUVzF6no3QaDSMLGLEHtHSBSefs+MgcDWnmhmo= github.com/jmoiron/sqlx v0.0.0-20180124204410-05cef0741ade h1:ryslCsfLTV4Cm/9NXqCJirlbYodWqFiTH454IaSn/fY= github.com/jmoiron/sqlx v0.0.0-20180124204410-05cef0741ade/go.mod h1:IiEW3SEiiErVyFdH8NTuWjSifiEQKUoyK3LNqr2kCHU= -github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg= github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= github.com/josharian/native v0.0.0-20200817173448-b6b71def0850 h1:uhL5Gw7BINiiPAo24A2sxkcDI0Jt/sqp1v5xQCniEFA= github.com/josharian/native v0.0.0-20200817173448-b6b71def0850/go.mod h1:7X/raswPFr05uY3HiLlYeyQntB6OO7E/d2Cu7qoaN2w= github.com/jsimonetti/rtnetlink v0.0.0-20190606172950-9527aa82566a/go.mod h1:Oz+70psSo5OFh8DBl0Zv2ACw7Esh6pPUphlvZG9x7uw= github.com/jsimonetti/rtnetlink v0.0.0-20200117123717-f846d4f6c1f4/go.mod h1:WGuG/smIU4J/54PblvSbh+xvCZmpJnFgr3ds6Z55XMQ= github.com/jsimonetti/rtnetlink v0.0.0-20201009170750-9c6f07d100c1/go.mod h1:hqoO/u39cqLeBLebZ8fWdE96O7FxrAsRYhnVOdgHxok= -github.com/jsimonetti/rtnetlink v0.0.0-20201110080708-d2c240429e6c/go.mod h1:huN4d1phzjhlOsNIjFsw2SVRbwIHj3fJDMEU2SDPTmg= github.com/jsimonetti/rtnetlink v0.0.0-20201216134343-bde56ed16391/go.mod h1:cR77jAZG3Y3bsb8hF6fHJbFoyFukLFOkQ98S0pQz3xw= github.com/jsimonetti/rtnetlink v0.0.0-20201220180245-69540ac93943/go.mod h1:z4c53zj6Eex712ROyh8WI0ihysb5j2ROyV42iNogmAs= github.com/jsimonetti/rtnetlink v0.0.0-20210122163228-8d122574c736/go.mod h1:ZXpIyOK59ZnN7J0BV99cZUPmsqDRZ3eq5X+st7u/oSA= @@ -506,8 +445,6 @@ github.com/kisom/goutils v1.1.0/go.mod h1:+UBTfd78habUYWFbNWTJNG+jNG/i/lGURakr4A github.com/klauspost/compress v1.11.3/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= github.com/klauspost/compress v1.11.13 h1:eSvu8Tmq6j2psUJqJrLcWH6K3w5Dwc+qipbaA6eVEN4= github.com/klauspost/compress v1.11.13/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= -github.com/klauspost/compress v1.12.2 h1:2KCfW3I9M7nSc5wOqXAlW2v2U6v+w6cbjvbfp+OykW8= -github.com/klauspost/compress v1.12.2/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= @@ -520,9 +457,7 @@ github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/pty v1.1.5/go.mod h1:9r2w37qlBe7rQ6e1fg1S/9xpWHSnaqNdHD3WcMdbPDA= github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= -github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/kylelemons/go-gypsy v0.0.0-20160905020020-08cad365cd28/go.mod h1:T/T7jsxVqf9k/zYOqbgNAsANsjxTd1Yq3htjDhQ1H0c= -github.com/kylelemons/godebug v0.0.0-20170820004349-d65d576e9348/go.mod h1:B69LEHPfb2qLo0BaaOLcbitczOKLWTsrBG9LczfCD4k= github.com/lib/pq v0.0.0-20180201184707-88edab080323 h1:Ou506ViB5uo2GloKFWIYi5hwRJn4AAOXuLVv8RMY9+4= github.com/lib/pq v0.0.0-20180201184707-88edab080323/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= @@ -531,23 +466,16 @@ github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN github.com/mailru/easyjson v0.7.0/go.mod h1:KAzv3t3aY1NaHWoQz1+4F1ccyAH66Jk7yos7ldAVICs= github.com/marstr/guid v1.1.0/go.mod h1:74gB1z2wpxxInTG6yaqA7KrtM0NZ+RbrcqDvYHefzho= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= -github.com/mattn/go-colorable v0.1.8 h1:c1ghPdyEDarC70ftn0y+A/Ee++9zz8ljHG1b13eJ0s8= -github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= -github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY= -github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= github.com/mattn/go-runewidth v0.0.7 h1:Ei8KR0497xHyKJPAv59M1dkC+rOZCMBJ+t3fZ+twI54= github.com/mattn/go-runewidth v0.0.7/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= github.com/mattn/go-shellwords v1.0.3/go.mod h1:3xCvwCdWdlDJUrvuMn7Wuy9eWs4pE8vqg+NOMyg4B2o= -github.com/mattn/go-shellwords v1.0.11 h1:vCoR9VPpsk/TZFW2JwK5I9S0xdrtUq2bph6/YjEPnaw= -github.com/mattn/go-shellwords v1.0.11/go.mod h1:EZzvwXDESEeg03EKmM+RmDnNOPKG4lLtQsUlTZDWQ8Y= github.com/mattn/go-sqlite3 v1.10.0 h1:jbhqpg7tQe4SupckyijYiy0mJJ/pRyHvXf7JdWK860o= github.com/mattn/go-sqlite3 v1.10.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369 h1:I0XW9+e1XWDxdcEniV4rQAIOPUGDq67JSCiRCgGCZLI= github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= -github.com/mdlayher/ethernet v0.0.0-20190606142754-0394541c37b7/go.mod h1:U6ZQobyTjI/tJyq2HG+i/dfSoFUt8/aZCM+GKtmFk/Y= github.com/mdlayher/ethtool v0.0.0-20210210192532-2b88debcdd43 h1:WgyLFv10Ov49JAQI/ZLUkCZ7VJS3r74hwFIGXJsgZlY= github.com/mdlayher/ethtool v0.0.0-20210210192532-2b88debcdd43/go.mod h1:+t7E0lkKfbBsebllff1xdTmyJt8lH37niI6kwFk9OTo= github.com/mdlayher/genetlink v1.0.0 h1:OoHN1OdyEIkScEmRgxLEe2M9U8ClMytqA5niynLtfj0= @@ -562,16 +490,12 @@ github.com/mdlayher/netlink v1.2.2-0.20210123213345-5cc92139ae3e/go.mod h1:bacnN github.com/mdlayher/netlink v1.3.0/go.mod h1:xK/BssKuwcRXHrtN04UBkwQ6dY9VviGGuriDdoPSWys= github.com/mdlayher/netlink v1.4.0 h1:n3ARR+Fm0dDv37dj5wSWZXDKcy+U0zwcXS3zKMnSiT0= github.com/mdlayher/netlink v1.4.0/go.mod h1:dRJi5IABcZpBD2A3D0Mv/AiX8I9uDEu5oGkAVrekmf8= -github.com/mdlayher/raw v0.0.0-20190606142536-fef19f00fc18/go.mod h1:7EpbotpCmVZcu+KCX4g9WaRNuu11uyhiW7+Le1dKawg= -github.com/mdlayher/raw v0.0.0-20191009151244-50f2db8cc065/go.mod h1:7EpbotpCmVZcu+KCX4g9WaRNuu11uyhiW7+Le1dKawg= github.com/miekg/pkcs11 v1.0.3 h1:iMwmD7I5225wv84WxIG/bmxz9AXjWvTWIbM/TYHvWtw= github.com/miekg/pkcs11 v1.0.3/go.mod h1:XsNlhZGX73bx86s2hdc/FuaLm2CPZJemRLMA+WTFxgs= github.com/mistifyio/go-zfs v2.1.2-0.20190413222219-f784269be439+incompatible/go.mod h1:8AuVvqP/mXw1px98n46wfvcGfQ4ci2FwoAjKYxuo3Z4= github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= -github.com/mitchellh/mapstructure v1.4.1 h1:CpVNEelQCZBooIPDn+AR3NpivK/TIKU8bDxdASFVQag= -github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/mitchellh/osext v0.0.0-20151018003038-5e2d6d41470f/go.mod h1:OkQIRizQZAeMln+1tSwduZz7+Af5oFlKirV/MSYes2A= github.com/moby/locker v1.0.1 h1:fOXqR41zeveg4fFODix+1Ch4mj/gT0NE1XJbp/epuBg= github.com/moby/locker v1.0.1/go.mod h1:S7SDdo5zpBK84bzzVlKr2V0hz+7x9hWbYC/kq7oQppc= @@ -581,7 +505,6 @@ github.com/moby/sys/mountinfo v0.4.1/go.mod h1:rEr8tzG/lsIZHBtN/JjGG+LMYx9eXgW2J github.com/moby/sys/symlink v0.1.0/go.mod h1:GGDODQmbFOjFsXvfLVn3+ZRxkch54RkSiGqsZeMYowQ= github.com/moby/term v0.0.0-20200312100748-672ec06f55cd h1:aY7OQNf2XqY/JQ6qREWamhI/81os/agb2BAGpcx5yWI= github.com/moby/term v0.0.0-20200312100748-672ec06f55cd/go.mod h1:DdlQx2hp0Ss5/fLikoLlEeIYiATotOjgB//nb973jeo= -github.com/moby/vpnkit v0.5.0/go.mod h1:KyjUrL9cb6ZSNNAUwZfqRjhwwgJ3BJN+kXh0t43WTUQ= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= @@ -610,13 +533,10 @@ github.com/onsi/ginkgo v1.10.3/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+ github.com/onsi/ginkgo v1.11.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.12.1 h1:mFwc4LvZ0xpSvDZ3E+k8Yte0hLOMxXUlP+yXtJqkYfQ= github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= -github.com/onsi/ginkgo v1.13.0 h1:M76yO2HkZASFjXL0HSoZJ1AYEmQxNJmY41Jx1zNUq1Y= -github.com/onsi/ginkgo v1.13.0/go.mod h1:+REjRxOmWfHCjfv9TTWB1jD1Frx4XydAD3zm1lskyM0= github.com/onsi/gomega v0.0.0-20151007035656-2152b45fa28a/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= -github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= github.com/onsi/gomega v1.10.3 h1:gph6h/qe9GSUw1NhH1gp+qb+h8rXD8Cy60Z32Qw3ELA= github.com/onsi/gomega v1.10.3/go.mod h1:V9xEwhxec5O8UDM77eCW8vLymOMltsqPVYWrpDsH8xc= github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk= @@ -694,15 +614,9 @@ github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1 github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= -github.com/rootless-containers/rootlesskit v0.14.2 h1:jmsSyNyRG0QdWc3usppt5jEy5qOheeUsIINcymPrOFg= -github.com/rootless-containers/rootlesskit v0.14.2/go.mod h1:nV3TpRISvwhZQSwo0nmQQnxjCxXr3mvrMi0oASLvzcg= -github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= -github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= -github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/safchain/ethtool v0.0.0-20190326074333-42ed695e3de8/go.mod h1:Z0q5wiBQGYcxhMZ6gUqHn6pYNLypFAvaL3UvgZLR0U4= github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= -github.com/sclevine/agouti v3.0.0+incompatible/go.mod h1:b4WX9W9L1sfQKXeJf1mUTLZKJ48R1S7H23Ji7oFO5Bw= github.com/seccomp/libseccomp-golang v0.9.1/go.mod h1:GbW5+tmTXfcxTToHLXlScSlAvWlF4P2Ca7zGrPiEpWo= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/sirupsen/logrus v1.0.4-0.20170822132746-89742aefa4b2/go.mod h1:pMByvHTf9Beacp5x1UXfOR9xyW/9antXMhjMPG0dEzc= @@ -718,7 +632,6 @@ github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= github.com/smartystreets/goconvey v0.0.0-20190330032615-68dc04aab96a/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= -github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= @@ -746,25 +659,20 @@ github.com/stretchr/testify v0.0.0-20180303142811-b89eecf5ca5d/go.mod h1:a8OnRci github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= -github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/syndtr/gocapability v0.0.0-20170704070218-db04d3cc01c8/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww= github.com/syndtr/gocapability v0.0.0-20180916011248-d98352740cb2/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww= github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww= github.com/tchap/go-patricia v2.2.6+incompatible/go.mod h1:bmLyhP68RS6kStMGxByiQ23RP/odRBOTVjwp2cDyi6I= github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= -github.com/u-root/u-root v7.0.0+incompatible/go.mod h1:RYkpo8pTHrNjW08opNd/U6p/RJE7K0D8fXO0d47+3YY= github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc= github.com/urfave/cli v0.0.0-20171014202726-7bc6a0acffa5/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= github.com/urfave/cli v1.22.2 h1:gsqYFH8bb9ekPA12kRo0hfjngWQjkJPlN9R0N78BoUo= github.com/urfave/cli v1.22.2/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= -github.com/urfave/cli/v2 v2.3.0 h1:qph92Y649prgesehzOrQjdWyxFOp/QVM+6imKHad91M= -github.com/urfave/cli/v2 v2.3.0/go.mod h1:LJmUH05zAU44vOAcrfzZQKsZbVcdbOG8rtL3/XcUArI= github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= github.com/valyala/fasttemplate v1.0.1/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8= github.com/vishvananda/netlink v0.0.0-20181108222139-023a6dafdcdf/go.mod h1:+SR5DhBJrl6ZM7CoCKvpw5BKroDKQ+PJqOg65H/2ktk= @@ -777,8 +685,6 @@ github.com/vishvananda/netns v0.0.0-20180720170159-13995c7128cc/go.mod h1:ZjcWmF github.com/vishvananda/netns v0.0.0-20191106174202-0a2b9b5464df/go.mod h1:JP3t17pCcGlemwknint6hfoeCVQrEMVwxRLRjXpq+BU= github.com/vishvananda/netns v0.0.0-20200728191858-db3c7e526aae h1:4hwBBUfQCFe3Cym0ZtKyq7L16eZUtYKs+BaHDN6mAns= github.com/vishvananda/netns v0.0.0-20200728191858-db3c7e526aae/go.mod h1:DD4vA1DwXk04H54A1oHXtwZmA0grkVMdPxx/VGLCah0= -github.com/vishvananda/netns v0.0.0-20210104183010-2eb08e3e575f h1:p4VB7kIXpOQvVn1ZaTIVp+3vuYAXFe3OJEvjbUYJLaA= -github.com/vishvananda/netns v0.0.0-20210104183010-2eb08e3e575f/go.mod h1:DD4vA1DwXk04H54A1oHXtwZmA0grkVMdPxx/VGLCah0= github.com/weppos/publicsuffix-go v0.4.0/go.mod h1:z3LCPQ38eedDQSwmsSRW4Y7t2L8Ln16JPQ02lHAdn5k= github.com/weppos/publicsuffix-go v0.5.0 h1:rutRtjBJViU/YjcI5d80t4JAVvDltS6bciJg2K1HrLU= github.com/weppos/publicsuffix-go v0.5.0/go.mod h1:z3LCPQ38eedDQSwmsSRW4Y7t2L8Ln16JPQ02lHAdn5k= @@ -790,8 +696,6 @@ github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2 github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 h1:EzJWgHovont7NscjpAxXsDA8S8BMYve8Y5+7cuRE7R0= github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ= github.com/xeipuuv/gojsonschema v0.0.0-20180618132009-1d523034197f/go.mod h1:5yf86TLmAcydyeJq5YvxkGPE2fm/u4myDekKRoLuqhs= -github.com/xeipuuv/gojsonschema v1.2.0 h1:LhYJRs+L4fBtjZUfuSZIKGeVu0QRy8e5Xi7D17UxZ74= -github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y= github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= @@ -832,7 +736,6 @@ golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8U golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20200128174031-69ecbb4d6d5d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200728195943-123391ffb6de/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= @@ -867,6 +770,7 @@ golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.3.0 h1:RM4zey1++hCTbCVQfnWeKs9/IEsaBLA8vTkd0WVtmH4= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -878,7 +782,6 @@ golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73r golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190419010253-1f3472d942ba/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= @@ -898,7 +801,6 @@ golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLL golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20201006153459-a7d1128ccaa0/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201010224723-4f7140c49acb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= @@ -924,8 +826,6 @@ golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201207232520-09787c993a3a h1:DcqTD9SDLc+1P/r1EmRBwnVsrOwW+kk2vWf9n+1sGhs= golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20210220032951-036812b2e83c h1:5KslGYwFpkhGh+Q16bwMP3cOontH8FOep7tGV86Y7SQ= -golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -935,14 +835,12 @@ golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5h golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190411185658-b44545bcd369/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190418153312-f0ce4c0180be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190514135907-3a4b5fb9f71f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190522044717-8097e1b27ff5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190602015325-4c4f7f33c9ed/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190606122018-79a91cf218c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190606203320-7fc4e5ec1444/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190616124812-15dcb6c0061f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -965,7 +863,6 @@ golang.org/x/sys v0.0.0-20191210023423-ac6580df4449/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200120151820-655fe14d7479/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200124204421-9fbb57f87de9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -975,7 +872,6 @@ golang.org/x/sys v0.0.0-20200217220822-9197077df867/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200622214017-ed371f2e16b4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200728102440-3e129f6d46b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -985,7 +881,6 @@ golang.org/x/sys v0.0.0-20200916030750-2334cc1a136f/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200922070232-aee5d888a860/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201009025420-dfb3f7c4e634/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201101102859-da207088b7d1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201112073958-5cba982894dd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201117170446-d9b008d0a637/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201118182958-a01c418693c7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -994,19 +889,13 @@ golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20201202213521-69691e467435/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201218084310-7d0127a74742/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210110051926-789bb1bd4061/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210123111255-9b0068b26619/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210216163648-f7da38b97c65/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210324051608-47abb6519492 h1:Paq34FxTluEPvVyayQqMPgHm+vTOrIifmcYxFBx9TLg= golang.org/x/sys v0.0.0-20210324051608-47abb6519492/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210414055047-fe65e336abe0 h1:g9s1Ppvvun/fI+BptTMj909BBIcGrzQ32k9FNlcevOE= -golang.org/x/sys v0.0.0-20210414055047-fe65e336abe0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210420072515-93ed5bcd2bfe h1:WdX7u8s3yOigWAhHEaDl8r9G+4XwFQEQFtBMYyN+kXQ= -golang.org/x/sys v0.0.0-20210420072515-93ed5bcd2bfe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1 h1:v+OssWQX+hTHEmOBgwxdZxK4zHq3yOs8F9J7mk0PY8E= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= -golang.org/x/term v0.0.0-20210406210042-72f3dc4e9b72/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210503060354-a79de5458b56 h1:b8jxX3zqjpqb2LklXPzKSGJhzyxCOZSz8ncv8Nv+y7w= golang.org/x/term v0.0.0-20210503060354-a79de5458b56/go.mod h1:tfny5GFUkzUvx4ps4ajbZsCe5lw1metzhBm9T3x7oIY= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -1058,6 +947,7 @@ golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapK golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20210106214847-113979e3529a h1:CB3a9Nez8M13wwlr/E2YtwoU+qYHKfC+JrDa45RXXoQ= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -1119,8 +1009,6 @@ google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8 google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= google.golang.org/grpc v1.33.2 h1:EQyQC3sa8M+p6Ulc8yy9SWSS2GVwyRc83gAbG8lrl4o= google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= -google.golang.org/grpc v1.35.0 h1:TwIQcH3es+MojMVojxxfQ3l3OF2KzlRxML2xZq0kRo8= -google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= @@ -1155,7 +1043,6 @@ gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWD gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= @@ -1174,6 +1061,7 @@ honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWh honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= +honnef.co/go/tools v0.0.1-2020.1.3 h1:sXmLre5bzIR6ypkjXCDI3jHPssRhc8KD/Ome589sc3U= honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= k8s.io/api v0.20.1/go.mod h1:KqwcCVogGxQY3nBlRpwt+wpAMF/KjaCc7RpywacvqUo= k8s.io/api v0.20.4/go.mod h1:++lNL1AJMkDymriNniQsWRkMDzRaX2Y/POTUi8yvqYQ= diff --git a/runtime/containerd/containerd.go b/runtime/containerd/containerd.go index 57a2d2ec2..a778b1efc 100644 --- a/runtime/containerd/containerd.go +++ b/runtime/containerd/containerd.go @@ -125,7 +125,7 @@ func (c *ContainerdRuntime) PullImageIfRequired(ctx context.Context, imagename s return nil } -func (c *ContainerdRuntime) CreateContainer(ctx context.Context, node *types.Node) error { +func (c *ContainerdRuntime) CreateContainer(ctx context.Context, node *types.NodeConfig) error { ctx = namespaces.WithNamespace(ctx, containerdNamespace) var img containerd.Image diff --git a/runtime/docker/docker.go b/runtime/docker/docker.go index 0c9c15664..ae7d32051 100644 --- a/runtime/docker/docker.go +++ b/runtime/docker/docker.go @@ -208,7 +208,7 @@ func (c *DockerRuntime) DeleteNet(ctx context.Context) (err error) { } // CreateContainer creates a docker container -func (c *DockerRuntime) CreateContainer(ctx context.Context, node *types.Node) (err error) { +func (c *DockerRuntime) CreateContainer(ctx context.Context, node *types.NodeConfig) (err error) { log.Infof("Creating container: %s", node.ShortName) nctx, cancel := context.WithTimeout(ctx, c.timeout) diff --git a/runtime/runtime.go b/runtime/runtime.go index 1a45d6774..cce50b8d6 100644 --- a/runtime/runtime.go +++ b/runtime/runtime.go @@ -30,7 +30,7 @@ type ContainerRuntime interface { // Pull container image if not present PullImageIfRequired(context.Context, string) error // Create container - CreateContainer(context.Context, *types.Node) error + CreateContainer(context.Context, *types.NodeConfig) error // Start pre-created container by its name StartContainer(context.Context, string) error // Stop running container by its name diff --git a/types/node_definition.go b/types/node_definition.go new file mode 100644 index 000000000..6cb90692a --- /dev/null +++ b/types/node_definition.go @@ -0,0 +1,150 @@ +package types + +// NodeDefinition represents a configuration a given node can have in the lab definition file +type NodeDefinition struct { + Kind string `yaml:"kind,omitempty"` + Group string `yaml:"group,omitempty"` + Type string `yaml:"type,omitempty"` + Config string `yaml:"config,omitempty"` + Image string `yaml:"image,omitempty"` + License string `yaml:"license,omitempty"` + Position string `yaml:"position,omitempty"` + Cmd string `yaml:"cmd,omitempty"` + // list of bind mount compatible strings + Binds []string `yaml:"binds,omitempty"` + // list of port bindings + Ports []string `yaml:"ports,omitempty"` + // user-defined IPv4 address in the management network + MgmtIPv4 string `yaml:"mgmt_ipv4,omitempty"` + // user-defined IPv6 address in the management network + MgmtIPv6 string `yaml:"mgmt_ipv6,omitempty"` + // list of ports to publish with mysocketctl + Publish []string `yaml:"publish,omitempty"` + // environment variables + Env map[string]string `yaml:"env,omitempty"` + // linux user used in a container + User string `yaml:"user,omitempty"` + // container labels + Labels map[string]string `yaml:"labels,omitempty"` + // container networking mode. if set to `host` the host networking will be used for this node, else bridged network + NetworkMode string `yaml:"network-mode,omitempty"` +} + +func (n *NodeDefinition) GetKind() string { + if n == nil { + return "" + } + return n.Kind +} + +func (n *NodeDefinition) GetGroup() string { + if n == nil { + return "" + } + return n.Group +} + +func (n *NodeDefinition) GetType() string { + if n == nil { + return "" + } + return n.Type +} + +func (n *NodeDefinition) GetConfig() string { + if n == nil { + return "" + } + return n.Config +} + +func (n *NodeDefinition) GetImage() string { + if n == nil { + return "" + } + return n.Image +} + +func (n *NodeDefinition) GetLicense() string { + if n == nil { + return "" + } + return n.License +} + +func (n *NodeDefinition) GetPostion() string { + if n == nil { + return "" + } + return n.Position +} + +func (n *NodeDefinition) GetCmd() string { + if n == nil { + return "" + } + return n.Cmd +} + +func (n *NodeDefinition) GetBinds() []string { + if n == nil { + return nil + } + return n.Binds +} + +func (n *NodeDefinition) GetPorts() []string { + if n == nil { + return nil + } + return n.Ports +} + +func (n *NodeDefinition) GetMgmtIPv4() string { + if n == nil { + return "" + } + return n.MgmtIPv4 +} + +func (n *NodeDefinition) GetMgmtIPv6() string { + if n == nil { + return "" + } + return n.MgmtIPv4 +} + +func (n *NodeDefinition) GetPublish() []string { + if n == nil { + return nil + } + return n.Publish +} + +func (n *NodeDefinition) GetEnv() map[string]string { + if n == nil { + return nil + } + return n.Env +} + +func (n *NodeDefinition) GetUser() string { + if n == nil { + return "" + } + return n.User +} + +func (n *NodeDefinition) GetLabels() map[string]string { + if n == nil { + return nil + } + return n.Labels +} + +func (n *NodeDefinition) GetNetworkMode() string { + if n == nil { + return "" + } + return n.NetworkMode +} diff --git a/types/topology.go b/types/topology.go new file mode 100644 index 000000000..9c12c40e9 --- /dev/null +++ b/types/topology.go @@ -0,0 +1,288 @@ +package types + +import ( + "os" + "path/filepath" + + "github.com/docker/go-connections/nat" + "github.com/mitchellh/go-homedir" + "github.com/srl-labs/containerlab/utils" +) + +// Topology represents a lab topology +type Topology struct { + Defaults *NodeDefinition `yaml:"defaults,omitempty"` + Kinds map[string]*NodeDefinition `yaml:"kinds,omitempty"` + Nodes map[string]*NodeDefinition `yaml:"nodes,omitempty"` + Links []*LinkConfig `yaml:"links,omitempty"` +} + +func NewTopology() *Topology { + return &Topology{ + Defaults: new(NodeDefinition), + Kinds: make(map[string]*NodeDefinition), + Nodes: make(map[string]*NodeDefinition), + Links: make([]*LinkConfig, 0), + } +} + +type LinkConfig struct { + Endpoints []string + Labels map[string]string `yaml:"labels,omitempty"` +} + +func (t *Topology) GetDefaults() *NodeDefinition { + if t.Defaults != nil { + return t.Defaults + } + return new(NodeDefinition) +} + +func (t *Topology) GetKind(kind string) *NodeDefinition { + if t.Kinds == nil { + return new(NodeDefinition) + } + if kdef, ok := t.Kinds[kind]; ok { + return kdef + } + return new(NodeDefinition) +} + +func (t *Topology) GetKinds() map[string]*NodeDefinition { + if t.Kinds == nil { + return make(map[string]*NodeDefinition) + } + return t.Kinds +} + +func (t *Topology) GetNodeBinds(name string) []string { + if ndef, ok := t.Nodes[name]; ok { + if len(ndef.Binds) > 0 { + return ndef.Binds + } + if t.Kinds != nil { + if kdef, ok := t.Kinds[ndef.Kind]; ok && kdef != nil { + return t.Kinds[ndef.Kind].Binds + } + } + return t.Defaults.Binds + } + return nil +} + +func (t *Topology) GetNodePorts(name string) (nat.PortSet, nat.PortMap, error) { + if ndef, ok := t.Nodes[name]; ok { + // node level ports + if len(ndef.Ports) != 0 { + ps, pb, err := nat.ParsePortSpecs(ndef.Ports) + if err != nil { + return nil, nil, err + } + return ps, pb, nil + } + // kind level ports + if kdef, ok := t.Kinds[ndef.Kind]; ok && kdef != nil { + if len(kdef.Ports) > 0 { + ps, pb, err := nat.ParsePortSpecs(kdef.Ports) + if err != nil { + return nil, nil, err + } + return ps, pb, nil + } + } + // default ports ? + return nil, nil, nil + } + return nil, nil, nil +} + +func (t *Topology) GetNodeEnv(name string) map[string]string { + if ndef, ok := t.Nodes[name]; ok { + return utils.MergeStringMaps( + utils.MergeStringMaps(t.GetDefaults().GetEnv(), + t.GetKind(ndef.GetKind()).GetEnv()), + ndef.Env) + } + return nil +} + +func (t *Topology) GetNodePublish(name string) []string { + if ndef, ok := t.Nodes[name]; ok { + if len(ndef.Publish) > 0 { + return ndef.Publish + } + if kdef, ok := t.Kinds[ndef.Kind]; ok && kdef != nil { + if len(kdef.Publish) > 0 { + return kdef.Publish + } + } + return t.Defaults.Publish + } + return nil +} + +func (t *Topology) GetNodeLabels(name string) map[string]string { + if ndef, ok := t.Nodes[name]; ok { + return utils.MergeStringMaps( + utils.MergeStringMaps(t.Defaults.GetLabels(), + t.GetKind(ndef.GetKind()).GetLabels()), + ndef.Labels) + } + return nil +} + +func (t *Topology) GetNodeConfig(name string) (string, error) { + var cfg string + if ndef, ok := t.Nodes[name]; ok { + var err error + cfg = ndef.Config + if kdef, ok := t.Kinds[ndef.Kind]; ok && cfg == "" { + cfg = kdef.Config + } + if cfg == "" { + cfg = t.Defaults.Config + } + if cfg != "" { + cfg, err = resolvePath(cfg) + if err != nil { + return "", err + } + _, err = os.Stat(cfg) + return cfg, err + } + } + return cfg, nil +} + +func (t *Topology) GetNodeLicense(name string) (string, error) { + var license string + if ndef, ok := t.Nodes[name]; ok { + var err error + license = ndef.License + if license == "" { + license = t.GetKind(ndef.GetKind()).GetLicense() + } + if license == "" { + license = t.Defaults.GetLicense() + } + if license != "" { + license, err = resolvePath(license) + if err != nil { + return "", err + } + _, err = os.Stat(license) + return license, err + } + } + return license, nil +} + +func (t *Topology) GetNodeImage(name string) string { + if ndef, ok := t.Nodes[name]; ok { + if ndef.Image != "" { + return ndef.Image + } + if kdef, ok := t.Kinds[ndef.Kind]; ok && kdef != nil { + if kdef.Image != "" { + return kdef.Image + } + } + return t.Defaults.Image + } + return "" +} + +func (t *Topology) GetNodeGroup(name string) string { + if ndef, ok := t.Nodes[name]; ok { + if ndef.Group != "" { + return ndef.Group + } + if kdef, ok := t.Kinds[ndef.Kind]; ok && kdef != nil { + if kdef.Group != "" { + return kdef.Group + } + } + return t.Defaults.Group + } + return "" +} + +func (t *Topology) GetNodeType(name string) string { + if ndef, ok := t.Nodes[name]; ok { + if ndef.Type != "" { + return ndef.Type + } + if kdef, ok := t.Kinds[ndef.Kind]; ok && kdef != nil { + if kdef.Type != "" { + return kdef.Type + } + } + return t.Defaults.Type + } + return "" +} + +func (t *Topology) GetNodePosition(name string) string { + if ndef, ok := t.Nodes[name]; ok { + if ndef.Position != "" { + return ndef.Position + } + if kdef, ok := t.Kinds[ndef.Kind]; ok && kdef != nil { + if kdef.Position != "" { + return kdef.Position + } + } + return t.Defaults.Position + } + return "" +} + +func (t *Topology) GetNodeCmd(name string) string { + if ndef, ok := t.Nodes[name]; ok { + if ndef.GetCmd() != "" { + return ndef.GetCmd() + } + if t.GetKind(ndef.GetKind()).GetCmd() != "" { + return t.GetKind(ndef.GetKind()).GetCmd() + } + return t.Defaults.GetCmd() + } + return "" +} + +func (t *Topology) GetNodeUser(name string) string { + if ndef, ok := t.Nodes[name]; ok { + if ndef.User != "" { + return ndef.User + } + if kdef, ok := t.Kinds[ndef.Kind]; ok && kdef != nil { + if kdef.User != "" { + return kdef.User + } + } + return t.Defaults.User + } + return "" +} + +//resolvePath resolves a string path by expanding `~` to home dir or getting Abs path for the given path +func resolvePath(p string) (string, error) { + if p == "" { + return "", nil + } + var err error + switch { + // resolve ~/ path + case p[0] == '~': + p, err = homedir.Expand(p) + if err != nil { + return "", err + } + default: + p, err = filepath.Abs(p) + if err != nil { + return "", err + } + } + return p, nil +} diff --git a/types/types.go b/types/types.go index 3b37add26..34c77bdd6 100644 --- a/types/types.go +++ b/types/types.go @@ -26,7 +26,7 @@ type Link struct { // Endpoint is a struct that contains information of a link endpoint type Endpoint struct { - Node *Node + Node *NodeConfig // e1-x, eth, etc EndpointName string // mac address @@ -43,8 +43,8 @@ type MgmtNet struct { MTU string `yaml:"mtu,omitempty"` } -// Node is a struct that contains the information of a container element -type Node struct { +// NodeConfig is a struct that contains the information of a container element +type NodeConfig struct { ShortName string LongName string Fqdn string @@ -89,7 +89,7 @@ type Node struct { } // GenerateConfig generates configuration for the nodes -func (node *Node) GenerateConfig(dst, defaultTemplatePath string) error { +func (node *NodeConfig) GenerateConfig(dst, defaultTemplatePath string) error { if utils.FileExists(dst) && (node.Config == defaultTemplatePath) { log.Debugf("config file '%s' for node '%s' already exists and will not be generated", dst, node.ShortName) return nil diff --git a/utils/env.go b/utils/env.go index d8d56f946..2e7d64375 100644 --- a/utils/env.go +++ b/utils/env.go @@ -12,3 +12,24 @@ func ConvertEnvs(m map[string]string) []string { } return s } + +// mergeStringMaps merges map m1 into m2 and return a resulting map as a new map +// maps that are passed for merging will not be changed +func MergeStringMaps(m1, m2 map[string]string) map[string]string { + if m1 == nil { + return m2 + } + if m2 == nil { + return m1 + } + // make a copy of a map + m := make(map[string]string) + for k, v := range m1 { + m[k] = v + } + + for k, v := range m2 { + m[k] = v + } + return m +}