Skip to content

Module System

sat edited this page Aug 12, 2026 · 23 revisions

Module System

This page explains how to use modules in dot2net.

Overview

Modules extend dot2net with platform-specific functionality. Loading a module adds:

  • File definitions - Platform-specific output files (e.g., topo.yaml, spec.yaml)
  • FormatStyles - Pre-defined formatting rules for specific config formats
  • Internal classes - Network/node/interface classes for platform integration
  • Requirements - Expected config blocks or parameters from user configuration

Loading Modules

Modules are loaded via the module section in YAML configuration:

module:
  - containerlab
  - frr

What Happens When a Module is Loaded

1. File Definitions Are Added

Each module defines its output files. For example:

Module File Description
containerlab topo.yaml Containerlab topology file
tinet spec.yaml TiNET specification file

These files are generated automatically based on the network model.

2. FormatStyles Become Available

Modules may provide FormatStyles for specific configuration formats:

# FRR module provides these FormatStyles
interfaceclass:
  - name: ospf
    config:
      - name: ospf_config
        format: frrVtysh      # Provided by frr module
        template:
          - "router ospf"
          - " network {{ .ip_network }} area 0"
Module FormatStyles
frr frrVtysh, frrDaemons, frrVtyshConf
containerlab clabCmd
tinet tinetSpecCmd

3. Requirements Are Established

Modules may require specific config blocks or parameters:

Module Required Parameters
containerlab image, kind
tinet image
kathara image (a device without one takes Kathara's base image)
frr -

If requirements are not met, dot2net reports an error.

Where a module and a scenario meet

A module and a scenario have to pass names to each other, and which names may cross is a short list rather than a growing one. Two kinds, and no others:

What crosses Where the scenario writes it What it means
the class names a module publishes use: "give this node what that class carries"
the value names a module publishes values: "and set it up like this"
the hook names dot2net itself owns config: - name: "run this, wherever this platform runs such things"

A module's own block names are its business. A scenario naming one would be reaching into a module's insides, and the ways the two can talk to each other would multiply with every module and every feature until nobody could say what they are.

The hooks

Hook When Where each platform puts it
startup once the node is up containerlab exec:, TiNET cmds:, Kathara <device>.startup
teardown while the node is still up, before the lab is destroyed the entry script runs them
nodeclass:
  - name: router
    config:
      - name: startup
        template:
          - "ip link set lo up"

A class pulled in with use: can define a template under a hook name too, and what the module has to do is merged ahead of what the scenario asked for there — a scenario's commands run on ground the module has prepared. So a scenario writes one line and nothing else:

nodeclass:
  - name: router
    use: [frrLogFile]      # the module adds its own commands to this node's startup

Two classes of the scenario's own naming one hook is still rejected: nothing would say which of them wins.

Names that begin with an underscore

A module's internal classes are named _clabNode, _katharaInterface and so on. The underscore says the same thing the rule above says: these are not for a scenario to name.

Combining Modules

Multiple modules can be loaded together. Each module's files are generated simultaneously:

module:
  - containerlab    # Generates topo.yaml
  - frr             # Provides FormatStyles for FRR config

This generates:

  • topo.yaml - Containerlab topology with node definitions
  • r1/frr.conf, r2/frr.conf - FRR configuration files (user-defined)

Example: Containerlab + FRR

module:
  - containerlab
  - frr

file:
  - name: frr.conf
    path: /etc/frr/frr.conf

nodeclass:
  - name: router
    values:
      image: quay.io/frrouting/frr:8.5.0
      kind: linux
    config:
      - file: frr.conf
        format: frrVtysh        # From frr module
        template:
          - "hostname {{ .name }}"
          - "!"

      - name: startup
        template:
          - "vtysh -b"

Result:

output/
├── topo.yaml           # From containerlab module
├── r1/
│   └── frr.conf        # User-defined, formatted with frrVtysh
└── r2/
    └── frr.conf

Available Modules

Module Purpose Documentation
containerlab Containerlab topology generation Module: Containerlab
tinet TiNET specification generation Module: TiNET
frr FRR configuration FormatStyles Module: FRR

See Also

Clone this wiki locally