From f41a84f9b76ecb7cdb5dc0c12e3d66c4d2481210 Mon Sep 17 00:00:00 2001 From: Alex Bortok <431965+bortok@users.noreply.github.com> Date: Mon, 27 Nov 2023 18:55:10 -0800 Subject: [PATCH 1/4] added --name argument --- Makefile | 9 +++++ README.md | 1 + nrx/nrx.py | 19 +++++++---- tests/site1/data/ABC.clab.yaml | 60 ++++++++++++++++++++++++++++++++++ 4 files changed, 83 insertions(+), 6 deletions(-) create mode 100644 tests/site1/data/ABC.clab.yaml diff --git a/Makefile b/Makefile index f607ded..5100678 100644 --- a/Makefile +++ b/Makefile @@ -145,6 +145,15 @@ test-site1-cyjs-2-clab: for f in *; do echo Comparing file $$f ...; diff $$f ../data/$$f || exit 1; done @echo +test-site1-cyjs-2-clab-rename: + @echo "#################################################################" + @echo "# Site1: read from CYJS and export as Containerlab with a custom name" + @echo "#################################################################" + mkdir -p tests/site1/test && cd tests/site1/test && rm -rf * && \ + ../../../nrx.py -c ../nrx.conf -i cyjs -f ../data/site1.cyjs -o clab --name ABC -d && \ + for f in *; do echo Comparing file $$f ...; diff $$f ../data/$$f || exit 1; done + @echo + test-site1-cyjs-template-2-clab: @echo "#################################################################" @echo "# Site1: replace Platform in the template, read from CYJS and export as Containerlab" diff --git a/README.md b/README.md index c1ff11f..d9bc74e 100644 --- a/README.md +++ b/README.md @@ -140,6 +140,7 @@ optional arguments: -a, --api API netbox API URL -s, --site SITE netbox site to export -t, --tags TAGS netbox tags to export, for multiple tags use a comma-separated list: tag1,tag2,tag3 (uses AND logic) + -N, --name NAME name of the exported topology (site name or tags by default) -n, --noconfigs disable device configuration export (enabled by default) -k, --insecure allow insecure server connections when using TLS -d, --debug enable debug output diff --git a/nrx/nrx.py b/nrx/nrx.py index 276fad8..42923eb 100755 --- a/nrx/nrx.py +++ b/nrx/nrx.py @@ -123,7 +123,10 @@ class NBFactory: def __init__(self, config): self.config = config self.nb_net = NBNetwork() - if len(config['export_site']) > 0: + # Determine the name of the topology if not provided in the configuration + if len(config['topology_name']) > 0: + self.topology_name = config['topology_name'] + elif len(config['export_site']) > 0: self.topology_name = config['export_site'] elif len(config['export_tags']) > 0: self.topology_name = "-".join(config['export_tags']) @@ -410,6 +413,8 @@ def __init__(self, config): # lists of device_index values grouped by role (e.g. {'spine': [1, 2], 'leaf': [3, 4]}) 'roles': {}, } + if len(config['topology_name']) > 0: + self.topology['name'] = config['topology_name'] self.j2env = jinja2.Environment( loader=jinja2.FileSystemLoader(self.config['templates_path'], followlinks=True), extensions=['jinja2.ext.do'], @@ -425,14 +430,10 @@ def __init__(self, config): def build_from_file(self, file): self._read_network_graph(file) - if "name" in self.G.graph.keys(): - self.topology['name'] = self.G.graph["name"] self._build_topology() def build_from_graph(self, graph): self.G = graph - if "name" in self.G.graph.keys(): - self.topology['name'] = self.G.graph["name"] self._build_topology() def _read_network_graph(self, file): @@ -542,6 +543,8 @@ def _build_topology(self): # Parse graph G into lists of: nodes and links. # Keep list of interfaces per device in `device_interfaces_map`, and then add them to each device try: + if self.topology['name'] is None and "name" in self.G.graph.keys(): + self.topology['name'] = self.G.graph["name"] for n in self.G.nodes: if not self._append_if_node_is_device(n): self._append_if_node_is_interface(n) @@ -559,7 +562,6 @@ def export_topology(self): # Create a directory for output files self.files_path = create_output_directory(self.topology['name'], self.config['output_dir']) # Generate topology data structure - self.topology['name'] = self.G.name self.topology['nodes'] = self._render_emulated_nodes() self._initialize_emulated_links() self._render_topology() @@ -768,6 +770,7 @@ def parse_args(): parser.add_argument('-a', '--api', required=False, help='netbox API URL') parser.add_argument('-s', '--site', required=False, help='netbox site to export') parser.add_argument('-t', '--tags', required=False, help='netbox tags to export, for multiple tags use a comma-separated list: tag1,tag2,tag3 (uses AND logic)') + parser.add_argument('-N', '--name', required=False, help='name of the exported topology (site name or tags by default)'), parser.add_argument('-n', '--noconfigs', required=False, help='disable device configuration export (enabled by default)', action=argparse.BooleanOptionalAction) parser.add_argument('-k', '--insecure', required=False, help='allow insecure server connections when using TLS', @@ -812,6 +815,7 @@ def load_toml_config(filename): }, 'export_site': '', 'export_tags': [], + 'topology_name': '', 'export_configs': True, 'templates_path': ['.'], 'output_dir': '', @@ -878,6 +882,9 @@ def load_config(args): if args.insecure: config['tls_validate'] = False + if args.name is not None and len(args.name) > 0: + config['topology_name'] = args.name + if args.output is not None and len(args.output) > 0: config['output_format'] = args.output diff --git a/tests/site1/data/ABC.clab.yaml b/tests/site1/data/ABC.clab.yaml new file mode 100644 index 0000000..ee7ba76 --- /dev/null +++ b/tests/site1/data/ABC.clab.yaml @@ -0,0 +1,60 @@ +name: ABC +topology: + nodes: + graphite: + kind: linux + image: netreplica/graphite:latest + env: + HOST_CONNECTION: ${SSH_CONNECTION} + binds: + - __clabDir__/topology-data.json:/htdocs/default/default.json:ro + - __clabDir__/ansible-inventory.yml:/htdocs/lab/default/ansible-inventory.yml:ro + ports: + - 8080:80 + exec: + - sh -c 'graphite_motd.sh 8080' + labels: + graph-hide: yes + + site1-r1: + kind: sonic-vs + image: netreplica/docker-sonic-vs:latest + labels: + graph-icon: router + graph-level: 6 + role: Router + group: site1 + platform: SONiC + vendor: Edgecore + model: 5912-54X-O-AC-F + site1-h1: + kind: linux + image: netreplica/ubuntu-host:latest + cmd: /start.sh -sS + exec: + - bash -c "echo root:root | chpasswd" + labels: + graph-icon: server + graph-level: 10 + role: server + group: site1 + platform: Linux + vendor: Dell + model: PowerEdge R640 + site1-h2: + kind: linux + image: netreplica/ubuntu-host:latest + cmd: /start.sh -sS + exec: + - bash -c "echo root:root | chpasswd" + labels: + graph-icon: server + graph-level: 10 + role: server + group: site1 + platform: Linux + vendor: Dell + model: PowerEdge R640 + links: + - endpoints: ["site1-r1:eth1", "site1-h1:eth1"] + - endpoints: ["site1-r1:eth2", "site1-h2:eth1"] From bd954be258102757960ecbecfb66fd96e8f1a4ae Mon Sep 17 00:00:00 2001 From: Alex Bortok <431965+bortok@users.noreply.github.com> Date: Mon, 27 Nov 2023 19:12:20 -0800 Subject: [PATCH 2/4] use -n for --name instead of --noconfigs --- README.md | 4 ++-- nrx/nrx.py | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index d9bc74e..8361738 100644 --- a/README.md +++ b/README.md @@ -140,8 +140,8 @@ optional arguments: -a, --api API netbox API URL -s, --site SITE netbox site to export -t, --tags TAGS netbox tags to export, for multiple tags use a comma-separated list: tag1,tag2,tag3 (uses AND logic) - -N, --name NAME name of the exported topology (site name or tags by default) - -n, --noconfigs disable device configuration export (enabled by default) + -n, --name NAME name of the exported topology (site name or tags by default) + --noconfigs disable device configuration export (enabled by default) -k, --insecure allow insecure server connections when using TLS -d, --debug enable debug output -f, --file FILE file with the network graph to import diff --git a/nrx/nrx.py b/nrx/nrx.py index 42923eb..019ef05 100755 --- a/nrx/nrx.py +++ b/nrx/nrx.py @@ -770,8 +770,8 @@ def parse_args(): parser.add_argument('-a', '--api', required=False, help='netbox API URL') parser.add_argument('-s', '--site', required=False, help='netbox site to export') parser.add_argument('-t', '--tags', required=False, help='netbox tags to export, for multiple tags use a comma-separated list: tag1,tag2,tag3 (uses AND logic)') - parser.add_argument('-N', '--name', required=False, help='name of the exported topology (site name or tags by default)'), - parser.add_argument('-n', '--noconfigs', required=False, help='disable device configuration export (enabled by default)', + parser.add_argument('-n', '--name', required=False, help='name of the exported topology (site name or tags by default)') + parser.add_argument('--noconfigs', required=False, help='disable device configuration export (enabled by default)', action=argparse.BooleanOptionalAction) parser.add_argument('-k', '--insecure', required=False, help='allow insecure server connections when using TLS', action=argparse.BooleanOptionalAction) From 7038bf1122e7d107a77e8cd521e2b259a2887354 Mon Sep 17 00:00:00 2001 From: Alex Bortok <431965+bortok@users.noreply.github.com> Date: Mon, 4 Dec 2023 19:56:13 -0800 Subject: [PATCH 3/4] added test-site1-cyjs-2-clab-rename to test --- Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index 5100678..8006724 100644 --- a/Makefile +++ b/Makefile @@ -2,12 +2,12 @@ lint: pylint nrx/*.py test-local: test-dc1 test-dc2 test-colo test-site1 test-h88 test-lrg -test: test-dc1-cyjs-2-clab test-dc2-cyjs-2-cml test-site1-cyjs-2-clab test-dc1-cyjs-2-graphite test-dc2-cyjs-2-graphite test-h88-cyjs-2-clab test-dc1-cyjs-2-d2 test-lrg-cyjs-2-graphite +test: test-dc1-cyjs-2-clab test-dc2-cyjs-2-cml test-site1-cyjs-2-clab test-site1-cyjs-2-clab-rename test-dc1-cyjs-2-graphite test-dc2-cyjs-2-graphite test-h88-cyjs-2-clab test-dc1-cyjs-2-d2 test-lrg-cyjs-2-graphite test-dc1: test-dc1-nb-2-cyjs-current test-dc1-nb-2-cyjs-latest test-dc1-cyjs-2-clab test-dc1-cyjs-2-graphite test-dc1-cyjs-2-d2 test-dc2: test-dc2-nb-2-cyjs-current test-dc2-nb-2-cyjs-latest test-dc2-cyjs-2-cml test-dc2-cyjs-2-graphite test-colo: test-colo-nb-2-cyjs-current test-colo-nb-2-cyjs-latest -test-site1: test-site1-nb-2-cyjs-current test-site1-nb-2-cyjs-latest test-site1-cyjs-2-clab +test-site1: test-site1-nb-2-cyjs-current test-site1-nb-2-cyjs-latest test-site1-cyjs-2-clab test-site1-cyjs-2-clab-rename test-h88: test-h88-nb-2-cyjs-current test-h88-nb-2-cyjs-latest test-h88-nb-2-cyjs-latest-noconfigs test-h88-cyjs-2-clab test-lrg: test-lrg-nb-2-cyjs-latest test-lrg-cyjs-2-graphite From 79e092aeefc3eb2d3672db9e39f0bc340c99a9a3 Mon Sep 17 00:00:00 2001 From: Alex Bortok <431965+bortok@users.noreply.github.com> Date: Mon, 4 Dec 2023 20:02:40 -0800 Subject: [PATCH 4/4] document TOPOLOGY_NAME conf parameter --- docs/CONFIGURATION.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/CONFIGURATION.md b/docs/CONFIGURATION.md index a32c689..0b2ac07 100644 --- a/docs/CONFIGURATION.md +++ b/docs/CONFIGURATION.md @@ -20,6 +20,8 @@ API_TIMEOUT = 10 interfaces_block_size = 4 cables_block_size = 64 +# Name of the topology, optional. Alternatively, use --name argument +TOPOLOGY_NAME = 'DemoSite' # Output format to use for export: 'gml' | 'cyjs' | 'clab'. Alternatively, use --output argument OUTPUT_FORMAT = 'clab' # Override output directory. By default, a subdirectory matching topology name will be created. Alternatively, use --dir argument