Skip to main content

cml2gns

Network lab topology translation and GNS3 deployment.

CI PyPI Python 3.9–3.14 License: MIT

cml2gns converts Cisco Modeling Labs (CML) and VIRL topologies into GNS3 project files, deploys them against templates installed on a GNS3 server, and provides supporting tools for validation, comparison, visualization, reverse conversion, and containerlab export.

The package name stays focused on its primary workflow—CML to GNS3—while the project now presents itself honestly as a broader topology toolkit. Renaming the Python package would break existing commands and imports without improving interoperability.

What works

  • CML YAML in list-based and dictionary-based layouts
  • VIRL XML parsed with defusedxml
  • GNS3 2.x project generation using the official node_type project field
  • Server-backed deployment using real, installed GNS3 template IDs
  • Link, node-position, annotation, and sidecar startup-config preservation
  • GNS3-to-CML best-effort reverse conversion
  • containerlab import and export
  • Topology validation, diffing, batch conversion, and ASCII visualization
  • GNS3 portable archives with the .gns3project extension

The test suite covers Python 3.9 through 3.14 in GitHub Actions.

Installation

Install the latest release from PyPI:

python -m pip install cml2gns

To install from source instead:

git clone https://github.com/daniissac/cml2gns.git
cd cml2gns
python -m pip install .

For development:

python -m pip install -e ".[dev]"
python -m pytest -q

To verify the HTTP contract against a real GNS3 server, run the opt-in check:

GNS3_URL=http://localhost:3080 python -m pytest tests/test_gns3_api.py -q

Choose a conversion mode

Create an offline GNS3 project

cml2gns convert \
  --input branch-lab.yaml \
  --output build/branch-lab \
  --portable

This writes a schema-valid .gns3 file and, when requested, a .gns3project archive. CML startup configurations are written unchanged into the output's configs/ directory.

Offline conversion cannot discover proprietary images or machine-specific GNS3 template settings. QEMU, IOU, and Docker nodes still need compatible images and properties on the system that opens the project.

Deploy through a running GNS3 server

cml2gns deploy \
  --input branch-lab.yaml \
  --host localhost \
  --port 3080

Deployment resolves only the templates needed by the topology, creates nodes from their real server-side templates, connects their interfaces, and rolls back the new project if a later step fails. Template names come from the built-in mappings or a custom mapping file.

For token authentication, set GNS3_API_TOKEN. For basic authentication, pass --user and set GNS3_PASSWORD.

Startup configs are not injected during server deployment because the destination filename and mechanism depend on the emulator and appliance. Use offline conversion to preserve them as sidecars, then apply them through the appropriate GNS3/device workflow.

Common commands

# Validate without writing files
cml2gns validate --input branch-lab.yaml

# Preview an offline conversion
cml2gns convert -i branch-lab.yaml -o build/branch-lab --dry-run

# Fail instead of creating generic fallback nodes
cml2gns convert -i branch-lab.yaml -o build/branch-lab --strict

# Check installed templates on a GNS3 server
cml2gns server-check --host localhost --port 3080

# Convert a GNS3 project back to CML YAML (best effort)
cml2gns reverse -i project.gns3 -o recovered.yaml

# Export any supported topology to containerlab
cml2gns export-clab -i branch-lab.yaml -o branch-lab.clab.yml

# Compare or visualize topologies
cml2gns diff -a before.yaml -b after.yaml
cml2gns show -i branch-lab.yaml

# Inspect built-in node mappings
cml2gns list-mappings

Run cml2gns --help or cml2gns COMMAND --help for every option.

Custom node mappings

Custom mappings override built-in mappings by CML node_definition:

{
  "iosv": {
    "gns3_template": "My IOSv Template",
    "console_type": "telnet",
    "compute_type": "qemu",
    "symbol": ":/symbols/classic/router.svg",
    "properties": {
      "ram": 768,
      "adapters": 4,
      "adapter_type": "e1000"
    }
  }
}

Use it with --mapping mappings.json. For server deployment, gns3_template must match an installed template name. A real template_id may also be supplied; the server verifies that it exists.

Conversion boundaries

Topology formats do not share a perfect one-to-one model. Keep these boundaries in mind:

  • Device images are never bundled. Cisco and other vendor images must be supplied under their own licenses.
  • GNS3-to-CML node definitions are inferred from GNS3 emulator types when the original CML metadata is unavailable.
  • Interface labels are matched first; adapter/port numbers are used as a fallback.
  • The optional --normalize-config transform only removes quotes around a quoted hostname. Secrets and other configuration lines are preserved.
  • Portable archives contain the generated project and sidecar files, not missing appliance images.

Contributing

See CONTRIBUTING.md. Please include a regression test for parser, generator, or API behavior changes.

License

MIT

Metadata

Release files for cml2gns 0.2.2

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for cml2gns 0.2.2
File Size Uploaded
cml2gns-0.2.2.tar.gz 50.7 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for cml2gns 0.2.2
File Interpreter ABI Platform
cml2gns-0.2.2-py3-none-any.whl Python 3 none any Details

Total release size: 95.2 kB

Release files / cml2gns-0.2.2.tar.gz

Download URL cml2gns-0.2.2.tar.gz
Size 50.7 kB
Tags Source
SHA-256 checksum
How to use checksums
6d6320b4a6f98904740c6fda1ff2298e8eff7a6980ddc84b0825d6a21d9cba7c
BLAKE2b-256 checksum
How to use checksums
6b70e1f50457a8b5e01fd47bd933a558b25171381f4a77173bc4377e8d2fbfd4
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 10, 2026.

Transparency log

Release files / cml2gns-0.2.2-py3-none-any.whl

Download URL cml2gns-0.2.2-py3-none-any.whl
Size 44.5 kB
Tags Python 3
SHA-256 checksum
How to use checksums
8620f8399ff21dcc3557f9707edfacaee40d8ba283fa417b7c2f661ab301db34
BLAKE2b-256 checksum
How to use checksums
f143d2ab7224ee26adebb191421e4f6bdde85fecf72b5368987b599404701dc6
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 10, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.2.2 This release

2 release files

0.2.1

2 release files

0.2.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page