#!/usr/bin/env python3 """ Rebuild CCNA topology with REAL Cisco IOSvL2 switches Full IOS CLI, VLAN support, trunking - the complete CCNA experience! """ 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") IOSVL2_TEMPLATE_ID = "25dd7340-2e92-4e45-83de-f88077a24ceb" 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 delete_all_nodes(project_id): resp = requests.get(f"{GNS3_API}/projects/{project_id}/nodes") nodes = resp.json() print(f"Cleaning up {len(nodes)} existing nodes...") for node in nodes: requests.delete(f"{GNS3_API}/projects/{project_id}/nodes/{node['node_id']}") time.sleep(1) def create_iosvl2_switch(project_id, name, x, y): """Create a Cisco IOSvL2 switch""" data = { "name": name, "node_type": "qemu", "compute_id": "local", "template_id": IOSVL2_TEMPLATE_ID, "properties": { "qemu_path": "/usr/bin/qemu-system-x86_64", "platform": "x86_64", "adapters": 16, # CRITICAL: 16 Gigabit Ethernet ports! "ram": 1024, "hda_disk_image": "vios_l2-adventerprisek9-m.03.2017.qcow2" }, "x": x, "y": y } resp = requests.post(f"{GNS3_API}/projects/{project_id}/nodes", json=data) if resp.status_code in [200, 201]: return resp.json() else: print(f" Error creating {name}: {resp.status_code} - {resp.text}") return None def create_vpcs(project_id, name, x, y): """Create a VPCS (Virtual PC)""" data = { "name": name, "node_type": "vpcs", "compute_id": "local", "x": x, "y": y } resp = requests.post(f"{GNS3_API}/projects/{project_id}/nodes", json=data) return resp.json() if resp.status_code in [200, 201] else None 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}") 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("REBUILDING CCNA TOPOLOGY WITH CISCO IOSvL2 SWITCHES") print("="*70) print() delete_all_nodes(project_id) print("Creating Cisco IOSvL2 Switches (this may take a moment)...") nodes = {} # Create 3 Cisco IOSvL2 switches nodes['SW1'] = create_iosvl2_switch(project_id, "SW1-Access", -300, 0) if nodes['SW1']: print(f" ✓ SW1-Access (Cisco IOSvL2) - VLAN 10") time.sleep(2) nodes['SW2'] = create_iosvl2_switch(project_id, "SW2-Core", 0, 0) if nodes['SW2']: print(f" ✓ SW2-Core (Cisco IOSvL2) - Trunk/Core") time.sleep(2) nodes['SW3'] = create_iosvl2_switch(project_id, "SW3-Access", 300, 0) if nodes['SW3']: print(f" ✓ SW3-Access (Cisco IOSvL2) - VLAN 20") time.sleep(2) print("\nCreating Virtual PCs (VPCS)...") nodes['PC1'] = create_vpcs(project_id, "PC1-Sales", -400, -100) if nodes['PC1']: print(f" ✓ PC1-Sales") time.sleep(0.3) nodes['PC2'] = create_vpcs(project_id, "PC2-Sales", -400, 100) if nodes['PC2']: print(f" ✓ PC2-Sales") time.sleep(0.3) nodes['PC3'] = create_vpcs(project_id, "PC3-Engineering", -100, -100) if nodes['PC3']: print(f" ✓ PC3-Engineering") time.sleep(0.3) nodes['PC4'] = create_vpcs(project_id, "PC4-Engineering", 100, -100) if nodes['PC4']: print(f" ✓ PC4-Engineering") time.sleep(0.3) nodes['PC5'] = create_vpcs(project_id, "PC5-Guest", 400, -100) if nodes['PC5']: print(f" ✓ PC5-Guest") time.sleep(0.3) nodes['PC6'] = create_vpcs(project_id, "PC6-Guest", 400, 100) if nodes['PC6']: print(f" ✓ PC6-Guest") time.sleep(0.3) # Re-fetch all node IDs to ensure we have fresh data print("\nRefreshing node IDs...") resp = requests.get(f"{GNS3_API}/projects/{project_id}/nodes") all_nodes = resp.json() node_map = {n['name']: n for n in all_nodes} # Update nodes dict with refreshed IDs for name in nodes.keys(): if name in node_map: nodes[name] = node_map[name] print("\nCreating Network Links...") links = 0 # PC1 -> SW1 if nodes.get('PC1') and nodes.get('SW1'): if create_link(project_id, nodes['PC1']['node_id'], 0, 0, nodes['SW1']['node_id'], 0, 0, "PC1-Sales → SW1 Gi0/0"): links += 1 # PC2 -> SW1 if nodes.get('PC2') and nodes.get('SW1'): if create_link(project_id, nodes['PC2']['node_id'], 0, 0, nodes['SW1']['node_id'], 0, 1, "PC2-Sales → SW1 Gi0/1"): links += 1 # SW1 -> SW2 (Trunk) if nodes.get('SW1') and nodes.get('SW2'): if create_link(project_id, nodes['SW1']['node_id'], 1, 0, nodes['SW2']['node_id'], 1, 0, "SW1 Gi1/0 ↔ SW2 Gi1/0 (TRUNK)"): links += 1 # PC3 -> SW2 if nodes.get('PC3') and nodes.get('SW2'): if create_link(project_id, nodes['PC3']['node_id'], 0, 0, nodes['SW2']['node_id'], 0, 1, "PC3-Engineering → SW2 Gi0/1"): links += 1 # PC4 -> SW2 if nodes.get('PC4') and nodes.get('SW2'): if create_link(project_id, nodes['PC4']['node_id'], 0, 0, nodes['SW2']['node_id'], 0, 2, "PC4-Engineering → SW2 Gi0/2"): links += 1 # SW2 -> SW3 (Trunk) if nodes.get('SW2') and nodes.get('SW3'): if create_link(project_id, nodes['SW2']['node_id'], 1, 1, nodes['SW3']['node_id'], 1, 0, "SW2 Gi1/1 ↔ SW3 Gi1/0 (TRUNK)"): links += 1 # PC5 -> SW3 if nodes.get('PC5') and nodes.get('SW3'): if create_link(project_id, nodes['PC5']['node_id'], 0, 0, nodes['SW3']['node_id'], 0, 0, "PC5-Guest → SW3 Gi0/0"): links += 1 # PC6 -> SW3 if nodes.get('PC6') and nodes.get('SW3'): if create_link(project_id, nodes['PC6']['node_id'], 0, 0, nodes['SW3']['node_id'], 0, 1, "PC6-Guest → SW3 Gi0/1"): links += 1 print("\n" + "="*70) print("✅ CCNA TOPOLOGY CREATED WITH REAL CISCO SWITCHES!") print("="*70) print(f"\nDevices: {len([n for n in nodes.values() if n])}") print(f" - 3x Cisco IOSvL2 switches (full IOS CLI)") print(f" - 6x VPCS (virtual PCs)") print(f"Links: {links} connections") print("\n" + "="*70) print("🎓 CCNA LAB CONFIGURATION GUIDE") print("="*70) print("\n📋 Step 1: Start all devices in GNS3 GUI") print(" (Switches will take 1-2 minutes to boot)") print("\n📋 Step 2: Configure VLANs on each switch") print("\nOn SW1-Access (console):") print("```") print("enable") print("configure terminal") print("vlan 10") print(" name Sales") print(" exit") print("interface range GigabitEthernet0/0 - 1") print(" switchport mode access") print(" switchport access vlan 10") print(" no shutdown") print(" exit") print("interface GigabitEthernet1/0") print(" switchport trunk encapsulation dot1q") print(" switchport mode trunk") print(" no shutdown") print(" exit") print("end") print("write memory") print("```") print("\nOn SW2-Core (console):") print("```") print("enable") print("configure terminal") print("vlan 10") print(" name Sales") print("vlan 20") print(" name Engineering") print(" exit") print("interface range GigabitEthernet0/1 - 2") print(" switchport mode access") print(" switchport access vlan 20") print(" no shutdown") print(" exit") print("interface range GigabitEthernet1/0 - 1") print(" switchport trunk encapsulation dot1q") print(" switchport mode trunk") print(" no shutdown") print(" exit") print("end") print("write memory") print("```") print("\nOn SW3-Access (console):") print("```") print("enable") print("configure terminal") print("vlan 20") print(" name Engineering") print(" exit") print("interface range GigabitEthernet0/0 - 1") print(" switchport mode access") print(" switchport access vlan 20") print(" no shutdown") print(" exit") print("interface GigabitEthernet1/0") print(" switchport trunk encapsulation dot1q") print(" switchport mode trunk") print(" no shutdown") print(" exit") print("end") print("write memory") print("```") print("\n📋 Step 3: Configure PC IP addresses") print("\nPC1: ip 10.1.10.10/24 10.1.10.1") print("PC2: ip 10.1.10.11/24 10.1.10.1") print("PC3: ip 10.1.20.10/24 10.1.20.1") print("PC4: ip 10.1.20.11/24 10.1.20.1") print("PC5: ip 10.1.30.10/24 10.1.30.1") print("PC6: ip 10.1.30.11/24 10.1.30.1") print("\n📋 Step 4: Verify VLAN configuration") print("\nOn any switch:") print(" show vlan brief") print(" show interfaces trunk") print(" show mac address-table") print("\n📋 Step 5: Test connectivity") print(" PC1 ping PC2 (same VLAN - should work!)") print(" PC3 ping PC4 (same VLAN - should work!)") print(" PC1 ping PC3 (different VLANs - will fail without router)") print("\n✨ Now you have a REAL CCNA switching lab!") print(" Full IOS CLI, VLANs, trunking, and all CCNA features!") print("="*70) if __name__ == "__main__": main()