Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

adds support for __clabNodeName__ magic var #2257

Merged
merged 4 commits into from
Jan 3, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 6 additions & 4 deletions clab/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,9 @@ const (
DefaultVethLinkMTU = 9500

// clab specific topology variables.
clabDirVar = "__clabDir__"
nodeDirVar = "__clabNodeDir__"
clabDirVar = "__clabDir__"
nodeDirVar = "__clabNodeDir__"
nodeNameVar = "__clabNodeName__"
)

// Config defines lab configuration as it is provided in the YAML file.
Expand Down Expand Up @@ -261,8 +262,9 @@ func (c *CLab) createNodeCfg(nodeName string, nodeDef *types.NodeDefinition, idx
// It handles remote files, local files and embedded configs.
// Returns an absolute path to the startup-config file.
func (c *CLab) processStartupConfig(nodeCfg *types.NodeConfig) error {
// process startup-config
p := c.Config.Topology.GetNodeStartupConfig(nodeCfg.ShortName)
// replace __clabNodeName__ magic var in startup-config path with node short name
r := strings.NewReplacer(nodeNameVar, nodeCfg.ShortName)
p := r.Replace(c.Config.Topology.GetNodeStartupConfig(nodeCfg.ShortName))

// embedded config is a config that is defined as a multi-line string in the topology file
// it contains at least one newline
Expand Down
44 changes: 44 additions & 0 deletions clab/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -731,3 +731,47 @@ func TestSuppressConfigInit(t *testing.T) {
})
}
}

func TestStartupConfigInit(t *testing.T) {
tests := map[string]struct {
got string
node string
want string
}{
"kinds_startup": {
got: "test_data/topo13.yml",
node: "node1",
want: "/test_data/configs/fabric/node1.cfg",
},
"node_startup": {
got: "test_data/topo14.yml",
node: "node1",
want: "/test_data/configs/fabric/node1.cfg",
},
"default_startup": {
got: "test_data/topo15.yml",
node: "node1",
want: "/test_data/configs/fabric/node1.cfg",
},
}

teardownTestCase := setupTestCase(t)
defer teardownTestCase(t)

for name, tc := range tests {
t.Run(name, func(t *testing.T) {
opts := []ClabOption{
WithTopoPath(tc.got, ""),
}
c, err := NewContainerLab(opts...)
if err != nil {
t.Error(err)
}

cwd, _ := os.Getwd()
if c.Nodes[tc.node].Config().StartupConfig != filepath.Join(cwd, tc.want) {
t.Errorf("want startup-config %q got startup-config %q", filepath.Join(cwd, tc.want), c.Nodes[tc.node].Config().StartupConfig)
}
})
}
}
8 changes: 8 additions & 0 deletions clab/test_data/topo13.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
name: topo13
topology:
kinds:
nokia_srlinux:
startup-config: ./configs/fabric/__clabNodeName__.cfg
nodes:
node1:
kind: nokia_srlinux
6 changes: 6 additions & 0 deletions clab/test_data/topo14.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
name: topo14
topology:
nodes:
node1:
kind: nokia_srlinux
startup-config: ./configs/fabric/__clabNodeName__.cfg
7 changes: 7 additions & 0 deletions clab/test_data/topo15.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
name: topo15
topology:
defaults:
startup-config: ./configs/fabric/__clabNodeName__.cfg
nodes:
node1:
kind: nokia_srlinux
67 changes: 67 additions & 0 deletions docs/manual/nodes.md
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,73 @@ topology:

Check the particular kind documentation to see if the startup-config is supported and how it is applied.

???info "Startup-config path variable"
By default, the startup-config references are either provided as an absolute or a relative (to the current working dir) path to the file to be used.

Consider a two-node lab `mylab.clab.yml` with seed configs that the user may wish to use in their lab. A user could create a directory for such files similar to this:

```
.
├── cfgs
│   ├── node1.partial.cfg
│   └── node2.partial.cfg
└── mylab.clab.yml

2 directories, 3 files
```

Then to leverage these configs, the node could be configured with startup-config references like this:

```yaml
name: mylab
topology:
nodes:
node1:
startup-config: cfgs/node1.partial.cfg
node2:
startup-config: cfgs/node2.partial.cfg
```

while this configuration is correct, it might be considered verbose as the number of nodes grows. To remove this verbosity, the users can use a special variable `__clabNodeName__` in their startup-config paths. This variable will expand to the node-name for the parent node that the startup-config reference falls under.

```yaml
name: mylab
topology:
nodes:
node1:
startup-config: cfg/__clabNodeName__.partial.cfg
node2:
startup-config: cfgs/__clabNodeName__.partial.cfg
```

The `__clabNodeName__` variable can also be used in the kind and default sections of the config. Using the same directory structure from the example above, the following shows how to use the magic varable for a kind.

```yaml
name: mylab
topology:
defaults:
kind: nokia_srlinux
kinds:
nokia_srlinux:
startup-config: cfgs/__clabNodeName__.partial.cfg
nodes:
node1:
node2:
```

The following example shows how one would do it using defaults.

```yaml
name: mylab
topology:
defaults:
kind: nokia_srlinux
startup-config: cfgs/__clabNodeName__.partial.cfg
nodes:
node1:
node2:
```

#### embedded startup-config

It is possible to embed the startup configuraion in the topology file itself. This is done by providing the startup-config as a multiline string.
Expand Down
1 change: 1 addition & 0 deletions mocks/dependency_manager.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

31 changes: 31 additions & 0 deletions mocks/mocknodes/default_node.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 4 additions & 3 deletions mocks/mocknodes/node.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions mocks/mockruntime/runtime.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading