Spaces:
Running
Running
| #!/usr/bin/env python3 | |
| """ | |
| Create a simple CCNA-level topology in the overgrowth GNS3 project | |
| Topology: 2 routers connected to 1 switch | |
| """ | |
| import requests | |
| import json | |
| import time | |
| import os | |
| GNS3_SERVER = os.getenv("GNS3_SERVER", "http://localhost:3080") | |
| GNS3_API = f"{GNS3_SERVER}/v2" | |
| PROJECT_NAME = os.getenv("GNS3_PROJECT_NAME", "overgrowth") | |
| def get_project_id(name): | |
| """Get project ID by name""" | |
| resp = requests.get(f"{GNS3_API}/projects") | |
| projects = resp.json() | |
| project = next((p for p in projects if p['name'] == name), None) | |
| return project['project_id'] if project else None | |
| def get_appliances(): | |
| """Get available appliances""" | |
| resp = requests.get(f"{GNS3_API}/appliances") | |
| return resp.json() | |
| def create_node(project_id, name, node_type, x, y, template_id=None): | |
| """Create a node in the project""" | |
| data = { | |
| "name": name, | |
| "node_type": node_type, | |
| "compute_id": "local", | |
| "x": x, | |
| "y": y | |
| } | |
| if template_id: | |
| data["template_id"] = template_id | |
| resp = requests.post( | |
| f"{GNS3_API}/projects/{project_id}/nodes", | |
| json=data | |
| ) | |
| if resp.status_code != 201: | |
| print(f" Error creating node: {resp.status_code}") | |
| print(f" Response: {resp.text}") | |
| return None | |
| return resp.json() | |
| def get_templates(): | |
| """Get available templates""" | |
| resp = requests.get(f"{GNS3_API}/templates") | |
| return resp.json() | |
| def create_link(project_id, node1_id, port1, node2_id, port2): | |
| """Create a link between two nodes""" | |
| data = { | |
| "nodes": [ | |
| { | |
| "node_id": node1_id, | |
| "adapter_number": port1, | |
| "port_number": 0 | |
| }, | |
| { | |
| "node_id": node2_id, | |
| "adapter_number": port2, | |
| "port_number": 0 | |
| } | |
| ] | |
| } | |
| resp = requests.post( | |
| f"{GNS3_API}/projects/{project_id}/links", | |
| json=data | |
| ) | |
| return resp.json() | |
| def main(): | |
| # Get project | |
| project_id = get_project_id(PROJECT_NAME) | |
| if not project_id: | |
| print(f"Project '{PROJECT_NAME}' not found!") | |
| return | |
| print(f"Working with project: {PROJECT_NAME} ({project_id})") | |
| # Get available templates | |
| print("\nFetching templates...") | |
| templates = get_templates() | |
| # Find Cisco IOS router and switch templates | |
| router_template = None | |
| switch_template = None | |
| for t in templates: | |
| name = t.get('name', '').lower() | |
| if 'router' in name or 'ios' in name or 'c7200' in name or 'c3725' in name: | |
| router_template = t | |
| print(f" Found router template: {t['name']}") | |
| if 'switch' in name or 'l2-ios' in name or 'iosvl2' in name: | |
| switch_template = t | |
| print(f" Found switch template: {t['name']}") | |
| if not router_template: | |
| # Try to use Ethernet switch as fallback | |
| print("\n No router template found - will use Ethernet devices") | |
| print(" Available templates:") | |
| for t in templates[:20]: | |
| print(f" - {t['name']} ({t.get('category', 'unknown')})") | |
| # Create simple ethernet topology instead | |
| print("\nCreating simple ethernet topology...") | |
| # Create 3 ethernet switches | |
| sw1 = create_node(project_id, "Switch-1", "ethernet_switch", -100, 0) | |
| print(f" Created {sw1['name']}") | |
| time.sleep(0.5) | |
| sw2 = create_node(project_id, "Switch-2", "ethernet_switch", 100, -100) | |
| print(f" Created {sw2['name']}") | |
| time.sleep(0.5) | |
| sw3 = create_node(project_id, "Switch-3", "ethernet_switch", 100, 100) | |
| print(f" Created {sw3['name']}") | |
| time.sleep(0.5) | |
| # Create links | |
| print("\nCreating links...") | |
| link1 = create_link(project_id, sw1['node_id'], 0, sw2['node_id'], 0) | |
| print(f" Linked {sw1['name']} <-> {sw2['name']}") | |
| link2 = create_link(project_id, sw1['node_id'], 1, sw3['node_id'], 0) | |
| print(f" Linked {sw1['name']} <-> {sw3['name']}") | |
| print("\n✓ Simple topology created!") | |
| print(" Note: This is a basic ethernet topology.") | |
| print(" To use routers/switches, you'll need to add Cisco IOS templates to GNS3.") | |
| else: | |
| print("\nCreating CCNA topology...") | |
| # Use IOSv which is qemu-based, not dynamips | |
| # Create 2 routers | |
| r1 = create_node(project_id, "Router-1", "qemu", -150, -100, router_template['template_id']) | |
| if r1: | |
| print(f" Created {r1['name']}") | |
| time.sleep(0.5) | |
| else: | |
| print(" Failed to create Router-1") | |
| return | |
| r2 = create_node(project_id, "Router-2", "qemu", 150, -100, router_template['template_id']) | |
| if r2: | |
| print(f" Created {r2['name']}") | |
| time.sleep(0.5) | |
| else: | |
| print(" Failed to create Router-2") | |
| return | |
| # Create 1 switch using ethernet_switch (simple and always works) | |
| sw1 = create_node(project_id, "Switch-1", "ethernet_switch", 0, 100) | |
| if sw1: | |
| print(f" Created {sw1['name']}") | |
| time.sleep(0.5) | |
| else: | |
| print(" Failed to create Switch-1") | |
| return | |
| # Create links | |
| print("\nCreating links...") | |
| link1 = create_link(project_id, r1['node_id'], 0, sw1['node_id'], 0) | |
| print(f" Linked {r1['name']} <-> {sw1['name']}") | |
| link2 = create_link(project_id, r2['node_id'], 0, sw1['node_id'], 1) | |
| print(f" Linked {r2['name']} <-> {sw1['name']}") | |
| print("\n✓ CCNA topology created!") | |
| if __name__ == "__main__": | |
| main() | |