Skip to content

Commit

Permalink
Merge pull request #473 from srl-labs/scrapli-netconf
Browse files Browse the repository at this point in the history
removed juniper/go-netconf in favor of scrapli
  • Loading branch information
hellt committed Jun 29, 2021
2 parents 930d9ad + bedba64 commit 54216f9
Show file tree
Hide file tree
Showing 25 changed files with 377 additions and 116 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/cicd.yml
Original file line number Diff line number Diff line change
Expand Up @@ -118,8 +118,8 @@ jobs:
uses: docker/login-action@v1
with:
registry: ghcr.io
username: hellt
password: ${{ secrets.GHCR_READ_PKG_PAT }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Pull ceos image
run: docker pull ghcr.io/srl-labs/ceos:4.25.0F && docker tag ghcr.io/srl-labs/ceos:4.25.0F ceos:4.25.0F
- name: Run ceos tests
Expand Down
116 changes: 116 additions & 0 deletions .golangci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
linters-settings:
depguard:
list-type: blacklist
dupl:
threshold: 100
funlen:
lines: 100
statements: 50
gci:
local-prefixes: github.com/golangci/golangci-lint
goconst:
min-len: 2
min-occurrences: 2
gocritic:
enabled-tags:
- diagnostic
- experimental
- opinionated
- performance
- style
disabled-checks:
- dupImport # https://github.com/go-critic/go-critic/issues/845
- ifElseChain
- octalLiteral
- whyNoLint
- wrapperFunc
gocyclo:
min-complexity: 15
goimports:
local-prefixes: github.com/golangci/golangci-lint
gomnd:
settings:
mnd:
# don't include the "operation" and "assign"
checks: [argument, case, condition, return]
govet:
check-shadowing: true
settings:
printf:
funcs:
- (github.com/golangci/golangci-lint/pkg/logutils.Log).Infof
- (github.com/golangci/golangci-lint/pkg/logutils.Log).Warnf
- (github.com/golangci/golangci-lint/pkg/logutils.Log).Errorf
- (github.com/golangci/golangci-lint/pkg/logutils.Log).Fatalf
lll:
line-length: 150
misspell:
locale: US
nolintlint:
allow-leading-space: true # don't require machine-readable nolint directives (i.e. with no leading space)
allow-unused: false # report any unused nolint directives
require-explanation: false # don't require an explanation for nolint directives
require-specific: false # don't require nolint directives to be specific about which linter is being skipped
linters:
# please, do not use `enable-all`: it's deprecated and will be removed soon.
# inverted configuration with `enable-all` and `disable` is not scalable during updates of golangci-lint
disable-all: true
enable:
- bodyclose
- deadcode
- depguard
- dogsled
- dupl
- errcheck
- exhaustive
- funlen
- gochecknoinits
- goconst
- gocritic
- gocyclo
- gofmt
- goimports
- gomnd
- goprintffuncname
- gosec
- gosimple
- govet
- ineffassign
- lll
- misspell
- nakedret
- noctx
- nolintlint
- revive
- rowserrcheck
- exportloopref
- staticcheck
- structcheck
- stylecheck
- typecheck
- unconvert
- unparam
- unused
- varcheck
- whitespace
- asciicheck
- gochecknoglobals
- gocognit
- godot
- godox
- goerr113
- nestif
- prealloc
- testpackage
- wsl

issues:
# Excluding configuration per-path, per-linter, per-text and per-source
exclude-rules:
- path: _test\.go
linters:
- gomnd

run:
skip-dirs:
- private
7 changes: 0 additions & 7 deletions clab/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,13 +59,6 @@ var kinds = []string{
"host",
}

// DefaultCredentials holds default username and password per each kind
var DefaultCredentials = map[string][]string{
"vr-sros": {"admin", "admin"},
"vr-vmx": {"admin", "admin@123"},
"vr-xrv9k": {"clab", "clab@123"},
}

// Config defines lab configuration as it is provided in the YAML file
type Config struct {
Name string `json:"name,omitempty"`
Expand Down
96 changes: 9 additions & 87 deletions cmd/save.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,23 +7,14 @@ package cmd
import (
"context"
"fmt"
"io/ioutil"
"strings"
"sync"

"github.com/Juniper/go-netconf/netconf"
log "github.com/sirupsen/logrus"
"github.com/spf13/cobra"
"github.com/srl-labs/containerlab/clab"
"github.com/srl-labs/containerlab/types"
"github.com/srl-labs/containerlab/nodes"
)

var saveCommand = map[string][]string{
"srl": {"sr_cli", "-d", "tools", "system", "configuration", "generate-checkpoint"},
"ceos": {"Cli", "-p", "15", "-c", "copy running flash:conf-saved.conf"},
"crpd": {"cli", "show", "conf"},
}

// saveCmd represents the save command
var saveCmd = &cobra.Command{
Use: "save",
Expand All @@ -46,64 +37,21 @@ Refer to the https://containerlab.srlinux.dev/cmd/save/ documentation to see the
ctx, cancel := context.WithCancel(context.Background())
defer cancel()

labels := []*types.GenericFilter{{FilterType: "label", Match: c.Config.Name, Field: "containerlab", Operator: "="}}
containers, err := c.Runtime.ListContainers(ctx, labels)
if err != nil {
return fmt.Errorf("could not list containers: %v", err)
}
if len(containers) == 0 {
return fmt.Errorf("no containers found")
if err := c.ParseTopology(); err != nil {
return err
}

var wg sync.WaitGroup
wg.Add(len(containers))
for _, cont := range containers {
go func(cont types.GenericContainer) {
wg.Add(len(c.Nodes))
for _, node := range c.Nodes {
go func(node nodes.Node) {
defer wg.Done()
kind := cont.Labels["clab-node-kind"]

switch kind {
case "vr-sros",
"vr-vmx":
netconfSave(cont)
return
}

// skip saving if we have no command map
if _, ok := saveCommand[kind]; !ok {
return
}
stdout, stderr, err := c.Runtime.Exec(ctx, cont.ID, saveCommand[kind])
err := node.SaveConfig(ctx, c.Runtime)
if err != nil {
log.Errorf("%s: failed to execute cmd: %v", cont.Names, err)

}
if len(stderr) > 0 {
log.Infof("%s errors: %s", strings.TrimLeft(cont.Names[0], "/"), string(stderr))
}
switch {
// for srl kinds print the full stdout
case kind == "srl":
if len(stdout) > 0 {
confPath := cont.Labels["clab-node-dir"] + "/config/checkpoint/checkpoint-0.json"
log.Infof("saved SR Linux configuration from %s node to %s\noutput:\n%s", strings.TrimLeft(cont.Names[0], "/"), confPath, string(stdout))
}

case kind == "crpd":
// path by which to save a config
confPath := cont.Labels["clab-node-dir"] + "/config/conf-saved.conf"
err := ioutil.WriteFile(confPath, stdout, 0777)
if err != nil {
log.Errorf("failed to write config by %s path from %s container: %v", confPath, strings.TrimLeft(cont.Names[0], "/"), err)
}
log.Infof("saved cRPD configuration from %s node to %s", strings.TrimLeft(cont.Names[0], "/"), confPath)

case kind == "ceos":
// path by which a config was saved
confPath := cont.Labels["clab-node-dir"] + "/flash/conf-saved.conf"
log.Infof("saved cEOS configuration from %s node to %s", strings.TrimLeft(cont.Names[0], "/"), confPath)
log.Errorf("err: %v", err)
}
}(cont)
}(node)
}
wg.Wait()

Expand All @@ -114,29 +62,3 @@ Refer to the https://containerlab.srlinux.dev/cmd/save/ documentation to see the
func init() {
rootCmd.AddCommand(saveCmd)
}

func netconfSave(cont types.GenericContainer) {
kind := cont.Labels["clab-node-kind"]
config := netconf.SSHConfigPassword(clab.DefaultCredentials[kind][0],
clab.DefaultCredentials[kind][1])

host := strings.TrimLeft(cont.Names[0], "/")
ncHost := host + ":830"

s, err := netconf.DialSSH(ncHost, config)
if err != nil {
log.Errorf("%s: Could not connect SSH to %s %s", cont.Names[0], host, err)
return
}
defer s.Close()

save := `<copy-config><target><startup/></target><source><running/></source></copy-config>`

_, err = s.Exec(netconf.RawMethod(save))
if err != nil {
log.Errorf("%s: Could not send Netconf save to %s %s", cont.Names[0], host, err)
return
}

log.Infof("saved %s configuration from node %s\n", kind, host)
}
3 changes: 1 addition & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ module github.com/srl-labs/containerlab
go 1.16

require (
github.com/Juniper/go-netconf v0.1.1
github.com/awalterschulze/gographviz v2.0.1+incompatible
github.com/cloudflare/cfssl v1.4.1
github.com/containerd/containerd v1.5.2
Expand All @@ -23,10 +22,10 @@ require (
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
github.com/scrapli/scrapligo v0.0.0-20210627135102-7fd8d8e86545
github.com/sirupsen/logrus v1.8.1
github.com/spf13/cobra v1.0.0
github.com/vishvananda/netlink v1.1.1-0.20210330154013-f5de75959ad5
github.com/ziutek/telnet v0.0.0-20180329124119-c3b780dc415b // indirect
golang.org/x/term v0.0.0-20210503060354-a79de5458b56
gopkg.in/yaml.v2 v2.4.0
)
13 changes: 8 additions & 5 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,6 @@ github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03
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=
github.com/GeertJohan/go.rice v1.0.0/go.mod h1:eH6gbSOAUv07dQuZVnBmoDP8mgsM1rtixis4Tib9if0=
github.com/Juniper/go-netconf v0.1.1 h1:5fx/T7L2Fwq51UnESPOP1CXgGCs7IYxR/pnyC5quu/k=
github.com/Juniper/go-netconf v0.1.1/go.mod h1:2Fy6tQTWnL//D/Ll1hb0RYXN4jndcTyneRn6xj5E1VE=
github.com/Microsoft/go-winio v0.4.11/go.mod h1:VhR8bwka0BXejwEJY73c50VrPtXAaKcyvVC4A4RozmA=
github.com/Microsoft/go-winio v0.4.14/go.mod h1:qXqCSQ3Xa7+6tgxaGTIe4Kpcdsi+P8jBhyzoq1bpyYA=
github.com/Microsoft/go-winio v0.4.15-0.20190919025122-fc70bd9a86b5/go.mod h1:tTuCMEN+UleMWgg9dVx4Hu52b1bJo+59jBh3ajtinzw=
Expand Down Expand Up @@ -217,6 +215,8 @@ github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfc
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/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.11 h1:07n33Z8lZxZ2qwegKbObQohDhXDQxiMMz1NOUGYlesw=
github.com/creack/pty v1.1.11/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
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=
github.com/d2g/dhcp4client v1.0.0/go.mod h1:j0hNfjhrt2SxUOw55nL0ATM/z4Yt3t2Kd1mW34z5W5s=
Expand Down Expand Up @@ -592,8 +592,12 @@ github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFR
github.com/russross/blackfriday/v2 v2.0.1/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/scrapli/scrapligo v0.0.0-20210627135102-7fd8d8e86545 h1:fhksj/v/SQEKV6QHHG9InCnDzr2QjjqoVQPeEhNB3So=
github.com/scrapli/scrapligo v0.0.0-20210627135102-7fd8d8e86545/go.mod h1:+csimZHh80jQXjdDdHmAIKCwiXPZvXQ7ZgKEQWmFpK8=
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/sirikothe/gotextfsm v1.0.0 h1:4kKwbUziG9G+31PfLY+vI3FzYK/kcByh4ndT3NyPMkc=
github.com/sirikothe/gotextfsm v1.0.0/go.mod h1:CJYqpTg9u5VPCoD0VEl9E68prCIiWQD8m457k098DdQ=
github.com/sirupsen/logrus v1.0.4-0.20170822132746-89742aefa4b2/go.mod h1:pMByvHTf9Beacp5x1UXfOR9xyW/9antXMhjMPG0dEzc=
github.com/sirupsen/logrus v1.0.6/go.mod h1:pMByvHTf9Beacp5x1UXfOR9xyW/9antXMhjMPG0dEzc=
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
Expand Down Expand Up @@ -673,8 +677,6 @@ github.com/yvasiyarov/go-metrics v0.0.0-20140926110328-57bccd1ccd43/go.mod h1:aX
github.com/yvasiyarov/gorelic v0.0.0-20141212073537-a9bba5b9ab50/go.mod h1:NUSPSUX/bi6SeDMUh6brw0nXpxHnc96TguQh0+r/ssA=
github.com/yvasiyarov/newrelic_platform_go v0.0.0-20140908184405-b21fdbd4370f/go.mod h1:GlGEuHIJweS1mbCqG+7vt2nvWLzLLnRHbXz5JKd/Qbg=
github.com/ziutek/mymysql v1.5.4/go.mod h1:LMSpPZ6DbqWFxNCHW77HeMg9I646SAhApZ/wKdgO/C0=
github.com/ziutek/telnet v0.0.0-20180329124119-c3b780dc415b h1:VfPXB/wCGGt590QhD1bOpv2J/AmC/RJNTg/Q59HKSB0=
github.com/ziutek/telnet v0.0.0-20180329124119-c3b780dc415b/go.mod h1:IZpXDfkJ6tWD3PhBK5YzgQT+xJWh7OsdwiG8hA2MkO4=
github.com/zmap/rc2 v0.0.0-20131011165748-24b9757f5521/go.mod h1:3YZ9o3WnatTIZhuOtot4IcUfzoKVjUHqu6WALIyI0nE=
github.com/zmap/zcertificate v0.0.0-20180516150559-0e3d58b1bac4/go.mod h1:5iU54tB79AMBcySS0R2XIyZBAVmeHranShAFELYx7is=
github.com/zmap/zcrypto v0.0.0-20190729165852-9051775e6a2e h1:mvOa4+/DXStR4ZXOks/UsjeFdn5O5JpLUtzqk9U8xXw=
Expand Down Expand Up @@ -707,8 +709,9 @@ golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8U
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=
golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2 h1:It14KIkyBFYkHkwZ7k45minvA9aorojkyjGk9KJ5B/w=
golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b h1:7mWr3k41Qtv8XlltBkDkl8LoP3mpSgBW8BUoxtEdbXg=
golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
Expand Down
3 changes: 3 additions & 0 deletions nodes/bridge/bridge.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,3 +36,6 @@ func (s *bridge) PostDeploy(ctx context.Context, r runtime.ContainerRuntime, ns
return nil
}
func (s *bridge) WithMgmtNet(*types.MgmtNet) {}
func (s *bridge) SaveConfig(ctx context.Context, r runtime.ContainerRuntime) error {
return nil
}
Loading

0 comments on commit 54216f9

Please sign in to comment.