Skip to content

Commit

Permalink
Update README (#9)
Browse files Browse the repository at this point in the history
* Update README

Signed-off-by: Atanas Dinov <[email protected]>

* Update installation steps

Signed-off-by: Atanas Dinov <[email protected]>

* Add complete example

Signed-off-by: Atanas Dinov <[email protected]>

---------

Signed-off-by: Atanas Dinov <[email protected]>
  • Loading branch information
atanasdinov authored Nov 20, 2023
1 parent 6af2b82 commit 1d3b917
Show file tree
Hide file tree
Showing 2 changed files with 136 additions and 80 deletions.
214 changes: 135 additions & 79 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,111 +1,167 @@
# nm-configurator

A tool capable of identifying & storing the relevant NetworkManager settings
for a given host out of a pool of predefined desired configurations.
nm-configurator (or NMC) is a CLI tool which makes it easy to generate and apply NetworkManager configurations.

Typically used with [Combustion](https://documentation.suse.com/sle-micro/5.4/single-html/SLE-Micro-deployment/#cha-images-combustion)
in order to bootstrap multiple nodes using the same provisioning artefact instead of depending on different custom images per machine.
## How to install it?

## What are the prerequisites?
### Download from release

### Desired network configurations per host
Each release is published with NMC already built for `amd64` and `arm64` Linux systems:

`nm-configurator` depends on having the desired network state for all known nodes beforehand.
```shell
$ curl -o nmc -L https://github.com/suse-edge/nm-configurator/releases/latest/download/nmc-linux-$(uname -m)
$ chmod +x nmc
```

[NetworkManager](https://documentation.suse.com/sle-micro/5.4/html/SLE-Micro-all/cha-nm-configuration.html)
is using connection profiles defined as files stored under `/etc/NetworkManager/system-connections`.
These config files (*.nmconnection) can be generated using [nmstate](https://nmstate.io/features/gen_conf.html).
### Build from source

Each file contains the desired state for a single network interface (e.g. `eth0`).
Configurations for all interfaces for all known hosts must be generated using `nmstate`.
```shell
$ git clone https://github.com/suse-edge/nm-configurator.git
$ cd nm-configurator
$ cargo build --release # only supports Linux based systems
```

### Network interface mapping
## How to run it?

Network interface mapping is required in order for `nm-configurator`
to identify the proper configurations for each host it is running on.
### Generate config

This additional config must be provided in a YAML format mapping the logical name of the interface to its MAC address:
NMC depends on having the desired network state for all known nodes beforehand.

```yaml
host_config:
- hostname: node1.example.com
interfaces:
- logical_name: eth0
mac_address: 00:10:20:30:40:50
- logical_name: eth1
mac_address: 10:20:30:40:50:60
- hostname: node2.example.com
interfaces:
- logical_name: eth0
mac_address: 00:11:22:33:44:55
```
[NetworkManager](https://documentation.suse.com/sle-micro/5.5/html/SLE-Micro-all/cha-nm-configuration.html)
is using connection profiles defined as files stored under `/etc/NetworkManager/system-connections`.
In order to generate these config (*.nmconnection) files, NMC uses the
[nmstate](https://github.com/nmstate/nmstate) library and requires a configuration directory as an input.
This directory must contain the desired network state for all hosts in a <i>hostname</i>.yaml file format.

**NOTE:** Interface names during the installation of nodes might differ from the preconfigured logical ones.
This is expected and `nm-configurator` will rely on the MAC addresses and use the actual names for the
NetworkManager configurations instead e.g. settings for interface with a predefined logical name `eth0` but
actually named `eth0.101` will automatically be adjusted and stored to `/etc/NetworkManager/eth0.101.nmconnection`.
#### Prepare desired states

## How to install it?
```shell
mkdir "desired-states"

cat <<- EOF > desired-states/node1.yaml
interfaces:
- name: eth0
type: ethernet
state: up
mac-address: FE:C4:05:42:8B:AA
ipv4:
address:
- ip: 192.168.122.250
prefix-length: 24
enabled: true
ipv6:
address:
- ip: 2001:db8::1:1
prefix-length: 64
enabled: true
EOF

cat <<- EOF > desired-states/node2.yaml
interfaces:
- name: eth1
type: ethernet
state: up
mac-address: FE:C4:05:42:8B:AB
ipv4:
address:
- ip: 192.168.123.250
prefix-length: 24
enabled: true
ipv6:
enabled: false
EOF

cat <<- EOF > desired-states/node3.yaml
interfaces:
- name: eth4
type: ethernet
state: up
mac-address: FE:C4:05:42:8B:AC
ipv4:
address:
- ip: 192.168.124.250
prefix-length: 24
enabled: true
ipv6:
enabled: false
EOF
```

### Standard method:
Please refer to the official nmstate docs for more extensive [examples](https://nmstate.io/examples.html).

Each release is published with `nm-configurator` already built for `amd64` and `arm64` Linux systems:
#### Run NMC

For AMD64 / x86_64 based systems:
```shell
$ curl -o nm-configurator -L https://github.com/suse-edge/nm-configurator/releases/latest/download/nm-configurator-amd64
$ chmod +x nm-configurator
$ export RUST_LOG=info # set log level ("error" by default)
$ ./nmc generate --config-dir desired-states --output-dir network-config
[2023-11-20T10:55:56Z INFO nmc::generate_conf] Generating config from "desired-states/node1.yaml"...
[2023-11-20T10:55:56Z INFO nmc::generate_conf] Generating config from "desired-states/node2.yaml"...
[2023-11-20T10:55:56Z INFO nmc::generate_conf] Generating config from "desired-states/node3.yaml"...
[2023-11-20T10:55:56Z INFO nmc] Successfully generated and stored network config
```

For ARM64 based systems:
```shell
$ curl -o nm-configurator -L https://github.com/suse-edge/nm-configurator/releases/latest/download/nm-configurator-arm64
$ chmod +x nm-configurator
```
#### Examine results

### Manual method:
The output is the following:

```shell
$ git clone https://github.com/suse-edge/nm-configurator.git
$ cd nm-configurator
$ go build . # optionally specify GOOS and GOARCH flags if cross compiling
```
$ ls -R network-config
network-config:
host_config.yaml node1 node2 node3

## How to run it?
network-config/node1:
eth0.nmconnection

Using an example configuration of three known nodes (with hostnames `node1.example.com`, `node2.example.com`
and `node3.example.com` and their respective NetworkManager settings) and interface mapping defined in `host_config.yaml`:

```text
config
├── node1.example.com
│ ├── eth0.nmconnection
│ └── eth1.nmconnection
├── node2.example.com
│ └── eth0.nmconnection
├── node3.example.com
│ ├── bond0.nmconnection
│ └── eth1.nmconnection
└── host_config.yaml
network-config/node2:
eth1.nmconnection

network-config/node3:
eth4.nmconnection
```

```shell
$ ./nm-configurator -config-dir=config -hosts-config-file=host_config.yaml
INFO[2023-08-17T17:32:23+03:00] starting network manager configurator...
INFO[2023-08-17T17:32:23+03:00] successfully identified host: node1.example.com
INFO[2023-08-17T17:32:23+03:00] storing file /etc/NetworkManager/system-connections/eth0.nmconnection...
INFO[2023-08-17T17:32:23+03:00] storing file /etc/NetworkManager/system-connections/eth1.nmconnection...
INFO[2023-08-17T17:32:23+03:00] successfully configured network manager
There are separate directories for each host (identified by their input <i>hostname</i>.yaml).
Each of these contains the configuration files for the desired network interfaces (e.g. `eth0`).

The `host_config.yaml` file on the root level maps the hosts to all of their preconfigured interfaces.
This is necessary in order for NMC to identify which host it is running on when applying the network configurations later.

```yaml
- hostname: node1
interfaces:
- logical_name: eth0
mac_address: FE:C4:05:42:8B:AA
- hostname: node2
interfaces:
- logical_name: eth1
mac_address: FE:C4:05:42:8B:AB
- hostname: node3
interfaces:
- logical_name: eth4
mac_address: FE:C4:05:42:8B:AC
```
*Note:* The default values for `-config-dir` and `-hosts-config-file` flags are `config` and `host_config.yaml`
respectively so providing them is not necessary with the file structure in the example:
### Apply config
NMC will use the previously generated configurations to identify and store the relevant NetworkManager settings for a given host.
Typically used with [Combustion](https://documentation.suse.com/sle-micro/5.5/single-html/SLE-Micro-deployment/#cha-images-combustion)
in order to bootstrap multiple nodes using the same provisioning artefact instead of depending on different custom images per machine.
#### Prepare network configurations
Simply copy the directory containing the results from `nmc generate` (`network-config` in the example above) to the target host.

#### Run NMC

```shell
$ ./nm-configurator
INFO[2023-08-17T17:45:41+03:00] starting network manager configurator...
INFO[2023-08-17T17:45:41+03:00] successfully identified host: node1.example.com
INFO[2023-08-17T17:45:41+03:00] storing file /etc/NetworkManager/system-connections/eth0.nmconnection...
INFO[2023-08-17T17:45:41+03:00] storing file /etc/NetworkManager/system-connections/eth1.nmconnection...
INFO[2023-08-17T17:45:41+03:00] successfully configured network manager
$ export RUST_LOG=info # set log level ("error" by default)
$ ./nmc apply --config-dir network-config/
[2023-11-20T11:05:36Z INFO nmc::apply_conf] Identified host: node2
[2023-11-20T11:05:36Z INFO nmc::apply_conf] Copying file... "network-config/node2/eth1.nmconnection"
[2023-11-20T11:05:36Z INFO nmc] Successfully applied config
```

**NOTE:** Interface names during the installation of nodes might differ from the preconfigured logical ones.
This is expected and NMC will rely on the MAC addresses and use the actual names for the NetworkManager
configurations instead e.g. settings for interface with a predefined logical name `eth0` but actually named
`eth2` will automatically be adjusted and stored to `/etc/NetworkManager/eth2.nmconnection`.
2 changes: 1 addition & 1 deletion src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ fn main() {
clap::Arg::new("CONFIG-DIR")
.long("config-dir")
.default_value("config")
.help("Config dir containing host mapping ('host_config.yaml')\
.help("Config dir containing host mapping ('host_config.yaml') \
and subdirectories containing *.nmconnection files per host")
)
);
Expand Down

0 comments on commit 1d3b917

Please sign in to comment.