Skip to content

Commit

Permalink
added env var expansion for topo file
Browse files Browse the repository at this point in the history
  • Loading branch information
hellt committed May 11, 2023
1 parent f029162 commit 754e0bb
Show file tree
Hide file tree
Showing 4 changed files with 44 additions and 5 deletions.
6 changes: 5 additions & 1 deletion clab/file.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import (
"strings"
"text/template"

"github.com/a8m/envsubst"
"github.com/hairyhenderson/gomplate/v3"
"github.com/hairyhenderson/gomplate/v3/data"

Expand Down Expand Up @@ -70,7 +71,10 @@ func (c *CLab) GetTopology(topo, varsFile string) error {
log.Debugf("topology:\n%s\n", buf.String())

// expand env vars if any
yamlFile := []byte(os.ExpandEnv(buf.String()))
yamlFile, err := envsubst.Bytes(buf.Bytes())
if err != nil {
return err
}

Check warning on line 77 in clab/file.go

View check run for this annotation

Codecov / codecov/patch

clab/file.go#L76-L77

Added lines #L76 - L77 were not covered by tests
err = yaml.UnmarshalStrict(yamlFile, c.Config)
if err != nil {
return err
Expand Down
40 changes: 36 additions & 4 deletions docs/manual/topo-def-file.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
Containerlab builds labs based on the topology information that users pass to it. This topology information is expressed as a code contained in the _topology definition file_ which structure is the prime focus of this document.


<div class="mxgraph" style="max-width:100%;border:1px solid transparent;margin:0 auto; display:block;" data-mxgraph="{&quot;page&quot;:4,&quot;zoom&quot;:1,&quot;highlight&quot;:&quot;#0000ff&quot;,&quot;nav&quot;:true,&quot;check-visible-state&quot;:true,&quot;resize&quot;:true,&quot;url&quot;:&quot;https://raw.githubusercontent.com/srl-labs/containerlab/diagrams/containerlab.drawio&quot;}"></div>

<script type="text/javascript" src="https://viewer.diagrams.net/js/viewer-static.min.js" async></script>

## Topology definition components

The topology definition file is a configuration file expressed in YAML and has a name pattern of `*.clab.yml`[^1]. In this document, we take a pre-packaged [Nokia SR Linux and Arista cEOS](../lab-examples/srl-ceos.md) lab and explain the topology definition structure using its definition file [srlceos01.clab.yml](https://github.com/srl-labs/containerlab/tree/main/lab-examples/srlceos01/srlceos01.clab.yml) which is pasted below:

```yaml
Expand Down Expand Up @@ -35,6 +35,7 @@ This topology results in the two nodes being started up and interconnected with
Let's touch on the key components of the topology definition file used in this example.

### Name

The topology must have a name associated with it. The name is used to distinct one topology from another, to allow multiple topologies to be deployed on the same host without clashes.

```yaml
Expand All @@ -48,6 +49,7 @@ The name is a free-formed string, though it is better not to use dashes (`-`) as
When containerlab starts the containers, their names will be generated using the following pattern: `clab-{{lab-name}}-{{node-name}}`. The lab name here is used to make the container's names unique between two different labs, even if the nodes are named the same.

### Prefix

It is possible to change the prefix that containerlab adds to node names. The `prefix` parameter is in charge of that. It follows the below-mentioned logic:

1. When `prefix` is not present in the topology file, the default prefix logic applies. Containers will be named as `clab-<lab-name>-<node-name>`.
Expand Down Expand Up @@ -84,9 +86,11 @@ Examples:
Even when you change the prefix, the lab directory is still uniformly named using the `clab-<lab-name>` pattern.

### Topology

The topology object inside the topology definition is the core element of the file. Under the `topology` element you will find all the main building blocks of a topology such as `nodes`, `kinds`, `defaults` and `links`.

#### Nodes

As with every other topology the nodes are in the center of things. With nodes we define which lab elements we want to run, in what configuration and flavor.

Let's zoom into the two nodes we have defined in our topology:
Expand Down Expand Up @@ -117,6 +121,7 @@ srl:
Refer to the [node configuration](nodes.md) document to meet all other options a node can have.

#### Links

Although it is totally fine to define a node without any links (like in [this lab](../lab-examples/single-srl.md)) most of the time we interconnect the nodes to make datapaths. One of containerlab purposes is to make the interconnection of nodes simple.

Links are defined under the `topology.links` container in the following manner:
Expand Down Expand Up @@ -146,8 +151,8 @@ endpoints: ["srl:e1-1", "ceos:eth1"]
will result in a creation of a p2p link between the node named `srl` and its `e1-1` interface and the node named `ceos` and its `eth1` interface. The p2p link is realized with a veth pair.

#### Kinds
Kinds define the behavior and the nature of a node, it says if the node is a specific containerized Network OS, virtualized router or something else. We go into details of kinds in its own [document section](kinds/index.md), so here we will discuss what happens when `kinds` section appears in the topology definition:

Kinds define the behavior and the nature of a node, it says if the node is a specific containerized Network OS, virtualized router or something else. We go into details of kinds in its own [document section](kinds/index.md), so here we will discuss what happens when `kinds` section appears in the topology definition:

```yaml
topology:
Expand Down Expand Up @@ -190,6 +195,7 @@ topology:
A lot of unnecessary repetition which is eliminated when we set `srl` kind properties on kind level.

#### Defaults

`kinds` set the values for the properties of a specific kind, whereas with the `defaults` container it is possible to set values globally.

For example, to set the environment variable for all the nodes of a topology:
Expand All @@ -207,8 +213,34 @@ topology:

Now every node in this topology will have environment variable `MYENV` set to `VALUE`.

## Environment variables

Topology definition file may contain environment variables anywhere in the file. The syntax is the same as in the bash shell:

```yaml
name: linux

topology:
nodes:
l1:
kind: linux
image: alpine:${ALPINE_VERSION:=3}
```

In the example above, the `ALPINE_VERSION` environment variable is used to set the version of the alpine image. If the variable is not set, the value of `3` will be used. The following syntax is used to expand the environment variable:

| __Expression__ | __Meaning__ |
| ------------------ | -------------------------------------------------------------------- |
| `${var}` | Value of var (same as `$var`) |
| `${var-$DEFAULT}` | If var not set, evaluate expression as $DEFAULT |
| `${var:-$DEFAULT}` | If var not set or is empty, evaluate expression as $DEFAULT |
| `${var=$DEFAULT}` | If var not set, evaluate expression as $DEFAULT |
| `${var:=$DEFAULT}` | If var not set or is empty, evaluate expression as $DEFAULT |
| `${var+$OTHER}` | If var set, evaluate expression as $OTHER, otherwise as empty string |
| `${var:+$OTHER}` | If var set, evaluate expression as $OTHER, otherwise as empty string |
| `$$var` | Escape expressions. Result will be `$var`. |

## Generated topologies
:warning: Advanced topic

To further simplify parametrization of the topology files, containerlab allows users to template the topology files using Go Template engine.

Expand All @@ -221,4 +253,4 @@ To help you get started, we created the following lab examples which demonstrate
* [Leaf-Spine topology with parametrized number of leaves/spines](lab-examples/../../lab-examples/templated01.md)
* [5-stage Clos topology with parametrized number of pods and super-spines](lab-examples/../../lab-examples/templated02.md)

[^1]: if the filename has `.clab.yml` or `-clab.yml` suffix, the YAML file will have autocompletion and linting support in VSCode editor.
[^1]: if the filename has `.clab.yml` or `-clab.yml` suffix, the YAML file will have autocompletion and linting support in VSCode editor.
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ require (
cloud.google.com/go/compute/metadata v0.2.3 // indirect
github.com/AdaLogics/go-fuzz-headers v0.0.0-20230106234847-43070de90fa1 // indirect
github.com/AdamKorcz/go-118-fuzz-build v0.0.0-20221215162035-5330a85ea652 // indirect
github.com/a8m/envsubst v1.4.2 // indirect
github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 // indirect
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.14.4 // indirect
github.com/blang/semver/v4 v4.0.0 // indirect
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -549,6 +549,8 @@ github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6/go.mod h1:3eOhrU
github.com/VividCortex/ewma v1.2.0 h1:f58SaIzcDXrSy3kWaHNvuJgJ3Nmz59Zji6XoJR/q1ow=
github.com/VividCortex/ewma v1.2.0/go.mod h1:nz4BbCtbLyFDeC9SUHbtcT5644juEuWfUAUnGx7j5l4=
github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g=
github.com/a8m/envsubst v1.4.2 h1:4yWIHXOLEJHQEFd4UjrWDrYeYlV7ncFWJOCBRLOZHQg=
github.com/a8m/envsubst v1.4.2/go.mod h1:MVUTQNGQ3tsjOOtKCNd+fl8RzhsXcDvvAEzkhGtlsbY=
github.com/acarl005/stripansi v0.0.0-20180116102854-5a71ef0e047d h1:licZJFw2RwpHMqeKTCYkitsPqHNxTmd4SNR5r94FGM8=
github.com/acarl005/stripansi v0.0.0-20180116102854-5a71ef0e047d/go.mod h1:asat636LX7Bqt5lYEZ27JNDcqxfjdBQuJ/MM4CN/Lzo=
github.com/acomagu/bufpipe v1.0.3 h1:fxAGrHZTgQ9w5QqVItgzwj235/uYZYgbXitB+dLupOk=
Expand Down

0 comments on commit 754e0bb

Please sign in to comment.