Spaces:
Sleeping
Sleeping
| #!/usr/bin/env python3 | |
| """ | |
| Complete the CCNA topology links after switches have booted | |
| Run this AFTER you start the switches in GNS3 GUI | |
| """ | |
| import requests | |
| 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): | |
| 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_nodes(project_id): | |
| resp = requests.get(f"{GNS3_API}/projects/{project_id}/nodes") | |
| all_nodes = resp.json() | |
| return {n['name']: n for n in all_nodes} | |
| def start_all_switches(project_id, nodes): | |
| """Start all switches""" | |
| switches = [n for name, n in nodes.items() if 'SW' in name] | |
| print(f"Starting {len(switches)} switches...") | |
| for sw in switches: | |
| if sw['status'] != 'started': | |
| requests.post(f"{GNS3_API}/projects/{project_id}/nodes/{sw['node_id']}/start") | |
| print(f" ✓ Starting {sw['name']}") | |
| if switches: | |
| print("\n⏱️ Waiting 30 seconds for switches to boot...") | |
| print(" (Cisco IOSvL2 takes time to initialize all interfaces)") | |
| for i in range(30, 0, -5): | |
| print(f" {i} seconds remaining...") | |
| time.sleep(5) | |
| def create_link(project_id, node1_id, adapter1, port1, node2_id, adapter2, port2, desc=""): | |
| data = { | |
| "nodes": [ | |
| {"node_id": node1_id, "adapter_number": adapter1, "port_number": port1}, | |
| {"node_id": node2_id, "adapter_number": adapter2, "port_number": port2} | |
| ] | |
| } | |
| resp = requests.post(f"{GNS3_API}/projects/{project_id}/links", json=data) | |
| if resp.status_code in [200, 201]: | |
| print(f" ✓ {desc}") | |
| return True | |
| else: | |
| print(f" ✗ {desc} - {resp.status_code}: {resp.text[:100]}") | |
| return False | |
| def main(): | |
| project_id = get_project_id(PROJECT_NAME) | |
| if not project_id: | |
| print(f"Project '{PROJECT_NAME}' not found!") | |
| return | |
| print("="*70) | |
| print("COMPLETING CCNA TOPOLOGY LINKS") | |
| print("="*70) | |
| print() | |
| nodes = get_nodes(project_id) | |
| # Find switch nodes (they might have version suffixes) | |
| sw1 = next((n for name, n in nodes.items() if 'SW1' in name and 'Access' in name), None) | |
| sw2 = next((n for name, n in nodes.items() if 'SW2' in name and 'Core' in name), None) | |
| sw3 = next((n for name, n in nodes.items() if 'SW3' in name and 'Access' in name), None) | |
| # Check if switches are running | |
| sw1_running = sw1 and sw1.get('status') == 'started' | |
| sw2_running = sw2 and sw2.get('status') == 'started' | |
| sw3_running = sw3 and sw3.get('status') == 'started' | |
| if not (sw1_running and sw2_running and sw3_running): | |
| print("⚠️ Switches are not all running. Starting them now...") | |
| start_all_switches(project_id, nodes) | |
| nodes = get_nodes(project_id) # Refresh after starting | |
| else: | |
| print("✅ All switches are already running!") | |
| print("\nCreating Network Links...") | |
| links = 0 | |
| # Find nodes dynamically | |
| pc1 = nodes.get('PC1-Sales') | |
| pc2 = nodes.get('PC2-Sales') | |
| pc3 = nodes.get('PC3-Engineering') | |
| pc4 = nodes.get('PC4-Engineering') | |
| pc5 = nodes.get('PC5-Guest') | |
| pc6 = nodes.get('PC6-Guest') | |
| sw1 = next((n for name, n in nodes.items() if 'SW1' in name and 'Access' in name), None) | |
| sw2 = next((n for name, n in nodes.items() if 'SW2' in name and 'Core' in name), None) | |
| sw3 = next((n for name, n in nodes.items() if 'SW3' in name and 'Access' in name), None) | |
| # PC1 -> SW1 | |
| if pc1 and sw1: | |
| if create_link(project_id, | |
| pc1['node_id'], 0, 0, | |
| sw1['node_id'], 0, 0, | |
| "PC1-Sales → SW1 Gi0/0"): | |
| links += 1 | |
| # PC2 -> SW1 (Ethernet1 = adapter 1, port 0) | |
| if pc2 and sw1: | |
| if create_link(project_id, | |
| pc2['node_id'], 0, 0, | |
| sw1['node_id'], 1, 0, | |
| "PC2-Sales → SW1 e1"): | |
| links += 1 | |
| # SW1 -> SW2 (Trunk: SW1 Ethernet2 = adapter 2) | |
| if sw1 and sw2: | |
| if create_link(project_id, | |
| sw1['node_id'], 2, 0, | |
| sw2['node_id'], 2, 0, | |
| "SW1 e2 ↔ SW2 e2 (TRUNK)"): | |
| links += 1 | |
| # PC3 -> SW2 (Ethernet1) | |
| if pc3 and sw2: | |
| if create_link(project_id, | |
| pc3['node_id'], 0, 0, | |
| sw2['node_id'], 1, 0, | |
| "PC3-Engineering → SW2 e1"): | |
| links += 1 | |
| # PC4 -> SW2 (Ethernet3) | |
| if pc4 and sw2: | |
| if create_link(project_id, | |
| pc4['node_id'], 0, 0, | |
| sw2['node_id'], 3, 0, | |
| "PC4-Engineering → SW2 e3"): | |
| links += 1 | |
| # SW2 -> SW3 (Trunk: Ethernet4 on both) | |
| if sw2 and sw3: | |
| if create_link(project_id, | |
| sw2['node_id'], 4, 0, | |
| sw3['node_id'], 2, 0, | |
| "SW2 e4 ↔ SW3 e2 (TRUNK)"): | |
| links += 1 | |
| # PC5 -> SW3 | |
| if pc5 and sw3: | |
| if create_link(project_id, | |
| pc5['node_id'], 0, 0, | |
| sw3['node_id'], 0, 0, | |
| "PC5-Guest → SW3 Gi0/0"): | |
| links += 1 | |
| # PC6 -> SW3 (Ethernet1) | |
| if pc6 and sw3: | |
| if create_link(project_id, | |
| pc6['node_id'], 0, 0, | |
| sw3['node_id'], 1, 0, | |
| "PC6-Guest → SW3 e1"): | |
| links += 1 | |
| print("\n" + "="*70) | |
| print(f"✅ TOPOLOGY COMPLETE: {links} links created") | |
| print("="*70) | |
| print("\n🎓 Next Steps:") | |
| print(" 1. Open GNS3 GUI and verify topology") | |
| print(" 2. Console into each switch (right-click → Console)") | |
| print(" 3. Follow VLAN configuration from build script output") | |
| print(" 4. Configure PC IP addresses") | |
| print(" 5. Test connectivity!") | |
| if __name__ == "__main__": | |
| main() | |