Skip to Content

Nmstate API: Simplifying Complex Network Configurations on RHEL

When I first encountered the Nmstate API, I was intrigued by its declarative approach to network configuration.

As someone who has spent time managing network settings on Red Hat Enterprise Linux (RHEL) systems, I often found myself frustrated with the manual processes involved in setting up network interfaces. Nmstate promised a more streamlined way to handle these tasks, and I was eager to dive in.

One of the standout features for me was the ability to define network configurations in a human-readable YAML format. This was a game changer; instead of dealing with complex command-line syntax, I could simply write down the desired state of my network in a clear and structured way.

This not only made it easier to understand what changes I was making but also simplified sharing configurations with my team.

Get Your Free Linux training!

Join our free Linux training and discover the power of open-source technology. Enhance your skills and boost your career! Learn Linux for Free!

Using the nmstatectl command-line utility felt intuitive right from the start. I appreciated how I could quickly query the current state of my network, apply new configurations, and even roll back changes if something didn’t work as expected. The atomic nature of the operations gave me confidence, knowing that if a configuration failed, I wouldn’t end up with a partially applied setup that could lead to network issues.

Another aspect that resonated with me was the support for partial updates. In previous setups, I often had to reconfigure entire interfaces when I only wanted to tweak a few settings. With Nmstate, I could modify just the specific parameters I needed, leaving the rest intact. This flexibility saved me a lot of time and hassle.

What is the Nmstate API?

Nmstate is a declarative API for managing network configuration on Red Hat Enterprise Linux (RHEL) systems. It allows you to specify the desired state of the network in a human-readable YAML or JSON format and then apply that configuration atomically. This ensures consistent and persistent network settings across your systems.

The primary components of the Nmstate API are:

  • libnmstate: A Python library that provides programmatic access to Nmstate functionality. Developers can integrate libnmstate into their applications for automated network configuration.
  • nmstatectl: A command-line utility that leverages the libnmstate library to interact with the Nmstate API. Administrators can use nmstatectl for a variety of network management tasks, including:
    • Querying the current network state
    • Exporting the network configuration to a file
    • Applying a desired network configuration from a file
    • Showing the status of specific network interfaces

Benefits of using the Nmstate API

  • Stable and Extensible Interface: It offers a consistent and well-defined way to manage RHEL network capabilities.
  • Atomic and Transactional Operations: Ensures that changes are applied as a single unit. If any part of the configuration fails, the entire operation is rolled back, preventing inconsistent states.
  • Partial Editing: You can modify only the specific settings you need. Any existing settings not specified in your instructions are preserved.
  • Plugin Support: Allows administrators to extend Nmstate functionality with custom plugins.

Examples of using the Nmstate API with nmstatectl

1. Configuring an Ethernet Connection with Static IP Settings

Create a YAML file (e.g., ~/create-ethernet-profile.yml) with the desired network settings:

---
interfaces:
  - name: enp1s0
    type: ethernet
    state: up
    ipv4:
      enabled: true
      address:
        - ip: 192.0.2.1
          prefix-length: 24
      dhcp: false
    ipv6:
      enabled: true
      address:
        - ip: 2001:db8:1::1
          prefix-length: 64
      autoconf: false
      dhcp: false
routes:
  config:
    - destination: 0.0.0.0/0
      next-hop-address: 192.0.2.254
      next-hop-interface: enp1s0
    - destination: ::/0
      next-hop-address: 2001:db8:1::fffe
      next-hop-interface: enp1s0
dns-resolver:
  config:
    search:
      - example.com
    server:
      - 192.0.2.200
      - 2001:db8:1::ffbb

Apply the settings to the system:

# nmstatectl apply ~/create-ethernet-profile.yml 

2. Configuring an Ethernet Connection for Dynamic IP Settings

Create a YAML file (e.g., ~/create-ethernet-profile.yml) similar to the previous example, but set dhcp to true for both IPv4 and IPv6:

---
interfaces:
  - name: enp1s0
    type: ethernet
    state: up
    ipv4:
      enabled: true
      dhcp: true
    ipv6:
      enabled: true
      dhcp: true 

Apply the settings:

# nmstatectl apply ~/create-ethernet-profile.yml

3. Configuring a Network Bond

Create a YAML file (e.g., ~/create-bond.yml) defining the bond interface and its members:

---
interfaces:
  - name: bond0
    type: bond
    state: up
    ipv4:
      enabled: true
      address:
        - ip: 192.0.2.1
          prefix-length: 24
      dhcp: false
    ipv6:
      enabled: true
      address:
        - ip: 2001:db8:1::1
          prefix-length: 64
      autoconf: false
      dhcp: false
    link-aggregation:
      mode: active-backup  
      port:
        - enp1s0
        - enp7s0
routes:
  config:
    - destination: 0.0.0.0/0
      next-hop-address: 192.0.2.254
      next-hop-interface: bond0
    - destination: ::/0
      next-hop-address: 2001:db8:1::fffe
      next-hop-interface: bond0
dns-resolver:
  config:
    search:
      - example.com
    server:
      - 192.0.2.200
      - 2001:db8:1::ffbb

Apply the settings:

# nmstatectl apply ~/create-bond.yml

4. Configuring VLAN Tagging

Create a YAML file (e.g., ~/create-vlan.yml) specifying the VLAN interface and its parent interface:

---
interfaces:
  - name: vlan10 
    type: vlan
    state: up
    ipv4:
      enabled: true
      address:
        - ip: 192.0.2.1
          prefix-length: 24
      dhcp: false
    ipv6:
      enabled: true
      address:
        - ip: 2001:db8:1::1
          prefix-length: 64
      autoconf: false
      dhcp: false
    vlan:
      base-iface: enp1s0 
      id: 10
  - name: enp1s0 
    type: ethernet
    state: up 

Apply the settings:

# nmstatectl apply ~/create-vlan.yml

5. Configuring a Network Bridge

Create a YAML file (e.g., ~/create-bridge.yml) describing the bridge interface and its members:

---
interfaces:
 - name: bridge0
   type: bridge
   state: up
   ipv4:
     enabled: true
     address:
        - ip: 192.0.2.1 
          prefix-length: 24
     dhcp: false
   ipv6:
     enabled: true
     address:
        - ip: 2001:db8:1::1
          prefix-length: 64
     autoconf: false
     dhcp: false
   bridge:
     port:
       - enp1s0 
       - enp7s0 
routes:
 config:
   - destination: 0.0.0.0/0
     next-hop-address: 192.0.2.254 
     next-hop-interface: bridge0
   - destination: ::/0
     next-hop-address: 2001:db8:1::fffe 
     next-hop-interface: bridge0
dns-resolver:
 config:
    search:
     - example.com
    server:
     - 192.0.2.200 
     - 2001:db8:1::ffbb

Apply the settings:

# nmstatectl apply ~/create-bridge.yml

6. Setting the Default Gateway

Create a YAML file (e.g., ~/set-default-gateway.yml) with the gateway settings:

---
routes:
  config:
   - destination: 0.0.0.0/0 
      next-hop-address: 192.0.2.1 
      next-hop-interface: enp1s0 

Apply the settings:

# nmstatectl apply ~/set-default-gateway.yml

7. Configuring a MACsec Connection

Create a YAML file (e.g., create-macsec-connection.yml) with the MACsec settings:

---
interfaces:
 - name: macsec0 
   type: macsec
   state: up
   macsec:
      icv-length: 16
      encrypt

: true
      protect-frames: true
      replay-protect: true
      window: 1
   link-aggregation:
     mode: active-backup
     port:
       - enp0s1 

Apply the settings:

# nmstatectl apply create-macsec-connection.yml 

8. Enabling Promiscuous Mode on an Interface

Edit the existing YAML file for the connection (e.g., enp1s0.yml) and add the following content:

---
interfaces:
  - name: enp1s0
    type: ethernet
    state: up
    accept-all-mac-addresses: true 

Apply the settings:

# nmstatectl apply ~/enp1s0.yml

9. Enabling LLDP on an Interface

Create a YAML file (e.g., enable-LLDP-enp1s0.yml) with the following content:

---
interfaces:
 - name: enp1s0
   type: ethernet
   state: up
   lldp:
     enabled: true

Apply the settings:

# nmstatectl apply ~/enable-LLDP-enp1s0.yml

10. Configuring 802.1X Network Authentication

Create a YAML file (e.g., ~/create-ethernet-profile.yml) with the desired network settings and 802.1X configuration:

---
interfaces:
 - name: enp1s0
   type: ethernet
   state: up
   ipv4:
     enabled: true
     address:
       - ip: 192.0.2.1
         prefix-length: 24
     dhcp: false
   ipv6:
     enabled: true
     address:
       - ip: 2001:db8:1::1 
         prefix-length: 64
     autoconf: false
     dhcp: false
   "802-1x":
     eap:
        identity: "username"
        tls:
           phase2-auth: "mschapv2"
           ca-cert: "/etc/pki/tls/certs/ca.crt"
           client-cert: "/etc/pki/tls/certs/client.crt"
           private-key: "/etc/pki/tls/private/client.key"
routes:
   config:
     - destination: 0.0.0.0/0 
       next-hop-address: 192.0.2.254 
       next-hop-interface: enp1s0
     - destination: ::/0 
       next-hop-address: 2001:db8:1::fffe
       next-hop-interface: enp1s0
dns-resolver:
   config:
      search:
        - example.com
      server:
        - 192.0.2.200 
        - 2001:db8:1::ffbb 

Apply the settings:

# nmstatectl apply ~/create-ethernet-profile.yml

Using libnmstate in a Python Application

The libnmstate library allows for more dynamic and programmatic network configuration within Python applications. Here is an example from the sources demonstrating how to query the network state using libnmstate:

import json
import libnmstate
from libnmstate.schema import Interface

net_state = libnmstate.show()
for iface_state in net_state[Interface.KEY]:
    print(iface_state[Interface.NAME] + ": " + iface_state[Interface.STATE])

This code snippet imports the necessary libraries, retrieves the current network state, and then iterates through each interface, printing its name and current state.

Nmstate and the network RHEL System Role

The network RHEL System Role is an Ansible role for automating network configuration on RHEL systems. The role supports Nmstate through the network_state variable, allowing you to manage network settings using a declarative approach within your Ansible playbooks.

Using the network_state variable provides several advantages:

  • Declarative Configuration: You describe the intended state of the network, and Ansible handles the necessary steps to achieve that state.
  • Partial Updates: You only need to specify the settings you want to change. Existing settings are retained.

Conclusion

The Nmstate API offers a powerful and flexible way to manage network configuration on RHEL systems.

Whether you use the nmstatectl command-line utility for ad-hoc tasks or integrate libnmstate into your applications for programmatic control, Nmstate provides a robust and reliable framework for network management.