Skip to content

Commit

Permalink
Merge branch 'master' into docs-publish
Browse files Browse the repository at this point in the history
  • Loading branch information
hellt committed Aug 11, 2021
2 parents fbf4123 + 3087f30 commit ee41f68
Show file tree
Hide file tree
Showing 20 changed files with 407 additions and 152 deletions.
43 changes: 41 additions & 2 deletions .github/workflows/cicd.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ on:
env:
GOVER: 1.16.5
CGO_ENABLED: 0
MKDOCS_MATERIAL_VER: 7.1.8
MKDOCS_MATERIAL_VER: 7.2.2

jobs:
file-changes:
Expand Down Expand Up @@ -96,7 +96,9 @@ jobs:
runs-on: ubuntu-20.04
strategy:
matrix:
runtime: ["docker", "containerd"]
runtime:
- "docker"
# - "containerd"
needs:
- unit-test
steps:
Expand Down Expand Up @@ -135,6 +137,43 @@ jobs:
name: 03-basic-ceos-log
path: ./tests/out/*.html

srlinux-basic-tests:
runs-on: ubuntu-20.04
strategy:
matrix:
runtime:
- "docker"
# - "containerd"
needs:
- unit-test
steps:
- name: Checkout
uses: actions/checkout@v2
with:
fetch-depth: 0
- name: Set up Go
uses: actions/setup-go@v2
with:
go-version: ${{ env.GOVER }}
- name: Build containerlab
run: go build && sudo mv ./containerlab /usr/bin/containerlab
- uses: actions/setup-python@v2
with:
python-version: "3.8"
- name: Install robotframework
run: |
python -m pip install --upgrade pip
pip install -r tests/requirements.txt
- name: Run srlinux tests
run: |
bash ./tests/rf-run.sh ${{ matrix.runtime }} ./tests/02-basic-srl
# upload test reports as a zip file
- uses: actions/upload-artifact@v2
if: always()
with:
name: 02-basic-srl-log
path: ./tests/out/*.html

docs-test:
runs-on: ubuntu-20.04
needs: file-changes
Expand Down
3 changes: 2 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
BIN_DIR = $(shell pwd)/bin
BINARY = $(shell pwd)/bin/containerlab
MKDOCS_VER = 7.2.2

all: build

Expand All @@ -22,4 +23,4 @@ docs:

.PHONY: site
site:
docker run -it --rm -p 8000:8000 -v $$(pwd):/docs squidfunk/mkdocs-material:7.1.8
docker run -it --rm -p 8000:8000 -v $$(pwd):/docs squidfunk/mkdocs-material:$(MKDOCS_VER)
26 changes: 20 additions & 6 deletions clab/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ import (

const (
// prefix is used to distinct containerlab created files/dirs/containers
prefix = "clab"
defaultPrefix = "clab"
// a name of a docker network that nodes management interfaces connect to
dockerNetName = "clab"
dockerNetIPv4Addr = "172.20.20.0/24"
Expand Down Expand Up @@ -66,6 +66,7 @@ var kinds = []string{
// Config defines lab configuration as it is provided in the YAML file
type Config struct {
Name string `json:"name,omitempty"`
Prefix *string `json:"prefix,omitempty"`
Mgmt *types.MgmtNet `json:"mgmt,omitempty"`
Topology *types.Topology `json:"topology,omitempty"`
ConfigPath string `yaml:"config_path,omitempty"`
Expand All @@ -79,12 +80,21 @@ func (c *CLab) parseTopology() error {
if c.Config.ConfigPath == "" {
c.Config.ConfigPath, _ = filepath.Abs(os.Getenv("PWD"))
}
if c.Config.Prefix == nil {
c.Config.Prefix = new(string)
*c.Config.Prefix = defaultPrefix
}

c.Dir = new(Directory)
c.Dir.Lab = c.Config.ConfigPath + "/" + prefix + "-" + c.Config.Name
c.Dir.LabCA = c.Dir.Lab + "/" + "ca"
c.Dir.LabCARoot = c.Dir.LabCA + "/" + "root"
c.Dir.LabGraph = c.Dir.Lab + "/" + "graph"
labDir := c.Config.Name
if c.Config.Prefix != nil && *c.Config.Prefix != "" {
labDir = strings.Join([]string{*c.Config.Prefix, c.Config.Name}, "-")
}
c.Dir.Lab = path.Join(c.Config.ConfigPath, labDir)

c.Dir.LabCA = path.Join(c.Dir.Lab, "ca")
c.Dir.LabCARoot = path.Join(c.Dir.LabCA, "root")
c.Dir.LabGraph = path.Join(c.Dir.Lab, "graph")

// initialize Nodes and Links variable
c.Nodes = make(map[string]nodes.Node)
Expand Down Expand Up @@ -193,9 +203,13 @@ func (c *CLab) NewNode(nodeName, nodeRuntime string, nodeDef *types.NodeDefiniti
}

func (c *CLab) createNodeCfg(nodeName string, nodeDef *types.NodeDefinition, idx int) (*types.NodeConfig, error) {
longName := strings.Join([]string{c.Config.Name, nodeName}, "-")
if c.Config.Prefix != nil && *c.Config.Prefix != "" {
longName = strings.Join([]string{*c.Config.Prefix, longName}, "-")
}
nodeCfg := &types.NodeConfig{
ShortName: nodeName,
LongName: strings.Join([]string{prefix, c.Config.Name, nodeName}, "-"),
LongName: longName,
Fqdn: strings.Join([]string{nodeName, c.Config.Name, ".io"}, "."),
LabDir: path.Join(c.Dir.Lab, nodeName),
Index: idx,
Expand Down
41 changes: 41 additions & 0 deletions clab/config/send.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package config

import (
"fmt"

"github.com/srl-labs/containerlab/clab/config/transport"
"github.com/srl-labs/containerlab/nodes"
)

func Send(cs *NodeConfig, action string) error {
var tx transport.Transport
var err error

ct, ok := cs.TargetNode.Labels["config.transport"]
if !ok {
ct = "ssh"
}

if ct == "ssh" {
tx, err = transport.NewSSHTransport(
cs.TargetNode,
transport.WithUserNamePassword(
nodes.DefaultCredentials[cs.TargetNode.Kind][0],
nodes.DefaultCredentials[cs.TargetNode.Kind][1]),
transport.HostKeyCallback(),
)
if err != nil {
return err
}
} else if ct == "grpc" {
// NewGRPCTransport
} else {
return fmt.Errorf("unknown transport: %s", ct)
}

err = transport.Write(tx, cs.TargetNode.LongName, cs.Data, cs.Info)
if err != nil {
return err
}
return nil
}
33 changes: 13 additions & 20 deletions clab/config/template.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import (
jT "github.com/kellerza/template"

log "github.com/sirupsen/logrus"
"github.com/srl-labs/containerlab/nodes"
"github.com/srl-labs/containerlab/types"
"gopkg.in/yaml.v2"
)
Expand Down Expand Up @@ -45,9 +44,7 @@ func LoadTemplates(tmpl *template.Template, role string) error {
return nil
}

func RenderAll(nodes map[string]nodes.Node, links map[int]*types.Link) (map[string]*NodeConfig, error) {
// A map with the ShortName as the key
res := make(map[string]*NodeConfig)
func RenderAll(allnodes map[string]*NodeConfig) error {

if len(TemplatePaths) == 0 { // default is the install path
TemplatePaths = []string{"@"}
Expand All @@ -63,45 +60,41 @@ func RenderAll(nodes map[string]nodes.Node, links map[int]*types.Link) (map[stri
var err error
TemplateNames, err = GetTemplateNamesInDirs(TemplatePaths)
if err != nil {
return nil, err
return err
}
log.Infof("No template names specified (-l) using: %s", strings.Join(TemplateNames, ", "))
}

tmpl := template.New("").Funcs(jT.Funcs)

for nodeName, vars := range PrepareVars(nodes, links) {
res[nodeName] = &NodeConfig{
TargetNode: nodes[nodeName].Config(),
Vars: vars,
}
for _, nc := range allnodes {

for _, baseN := range TemplateNames {
tmplN := fmt.Sprintf("%s__%s.tmpl", baseN, vars[vkRole])
tmplN := fmt.Sprintf("%s__%s.tmpl", baseN, nc.Vars[vkRole])

if tmpl.Lookup(tmplN) == nil {
err := LoadTemplates(tmpl, fmt.Sprintf("%s", vars[vkRole]))
err := LoadTemplates(tmpl, fmt.Sprintf("%s", nc.Vars[vkRole]))
if err != nil {
return nil, err
return err
}
if tmpl.Lookup(tmplN) == nil {
return nil, fmt.Errorf("template not found %s", tmplN)
return fmt.Errorf("template not found %s", tmplN)
}
}

var buf strings.Builder
err := tmpl.ExecuteTemplate(&buf, tmplN, vars)
err := tmpl.ExecuteTemplate(&buf, tmplN, nc.Vars)
if err != nil {
res[nodeName].Print(true, true)
return nil, err
nc.Print(true, true)
return err
}

data := strings.ReplaceAll(strings.Trim(buf.String(), "\n \t\r"), "\n\n\n", "\n\n")
res[nodeName].Data = append(res[nodeName].Data, data)
res[nodeName].Info = append(res[nodeName].Info, tmplN)
nc.Data = append(nc.Data, data)
nc.Info = append(nc.Info, tmplN)
}
}
return res, nil
return nil
}

// Implement stringer for NodeConfig
Expand Down
21 changes: 12 additions & 9 deletions clab/config/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,15 +29,15 @@ const (
type Dict map[string]interface{}

// Prepare variables for all nodes. This will also prepare all variables for the links
func PrepareVars(nodes map[string]nodes.Node, links map[int]*types.Link) map[string]Dict {
func PrepareVars(nodes map[string]nodes.Node, links map[int]*types.Link) map[string]*NodeConfig {

res := make(map[string]Dict)
res := make(map[string]*NodeConfig)

// preparing all nodes vars
for _, node := range nodes {
nodeCfg := node.Config()
name := nodeCfg.ShortName
vars := make(Dict)
vars := make(map[string]interface{})
vars[vkNodeName] = name

// Init array for this node
Expand All @@ -57,7 +57,10 @@ func PrepareVars(nodes map[string]nodes.Node, links map[int]*types.Link) map[str
vars[vkRole] = nodeCfg.Kind
}

res[name] = vars
res[name] = &NodeConfig{
TargetNode: nodeCfg,
Vars: vars,
}
}

// prepare all links
Expand All @@ -68,20 +71,20 @@ func PrepareVars(nodes map[string]nodes.Node, links map[int]*types.Link) map[str
if err != nil {
log.Errorf("cannot prepare link vars for %d. %s: %s", lIdx, link.String(), err)
}
res[link.A.Node.ShortName][vkLinks] = append(res[link.A.Node.ShortName][vkLinks].([]interface{}), varsA)
res[link.B.Node.ShortName][vkLinks] = append(res[link.B.Node.ShortName][vkLinks].([]interface{}), varsB)
res[link.A.Node.ShortName].Vars[vkLinks] = append(res[link.A.Node.ShortName].Vars[vkLinks].([]interface{}), varsA)
res[link.B.Node.ShortName].Vars[vkLinks] = append(res[link.B.Node.ShortName].Vars[vkLinks].([]interface{}), varsB)
}

// Prepare top-level map of nodes
// copy 1-level deep
all_nodes := make(Dict)
for name, vars := range res {
for name, nc := range res {
n := make(Dict)
all_nodes[name] = n
for k, v := range vars {
for k, v := range nc.Vars {
n[k] = v
}
vars[vkNodes] = all_nodes
nc.Vars[vkNodes] = all_nodes
}
return res
}
Expand Down
Loading

0 comments on commit ee41f68

Please sign in to comment.