Spaces:
Running
Running
| #!/usr/bin/env python3 | |
| """ | |
| Create a CCNA-ready topology using built-in GNS3 devices | |
| Uses: Ethernet switches, VPCS for PCs, and Cloud for WAN simulation | |
| """ | |
| 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): | |
| 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_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_switch(project_id, name, x, y, ports=8): | |
| """Create an Ethernet switch""" | |
| data = { | |
| "name": name, | |
| "node_type": "ethernet_switch", | |
| "compute_id": "local", | |
| "x": x, | |
| "y": y, | |
| "properties": { | |
| "ports_mapping": [ | |
| {"name": f"Ethernet{i}", "port_number": i, "type": "access", "vlan": 1} | |
| for i in range(ports) | |
| ] | |
| } | |
| } | |
| 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_cloud(project_id, name, x, y): | |
| """Create a Cloud node (simulates WAN/Internet)""" | |
| data = { | |
| "name": name, | |
| "node_type": "cloud", | |
| "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): | |
| 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) | |
| return resp.json() if resp.status_code in [200, 201] else None | |
| def main(): | |
| project_id = get_project_id(PROJECT_NAME) | |
| if not project_id: | |
| print(f"Project '{PROJECT_NAME}' not found!") | |
| return | |
| print(f"Building CCNA Topology in: {PROJECT_NAME}\n") | |
| delete_all_nodes(project_id) | |
| print("="*70) | |
| print("CCNA LAB TOPOLOGY - Network Fundamentals Practice") | |
| print("="*70) | |
| print(""" | |
| Network Design: | |
| VLAN 10 (Sales) VLAN 20 (Engineering) VLAN 30 (Guest) | |
| PC1 PC3 PC5 | |
| | | | | |
| ββββββ΄βββββ ββββββ΄βββββ ββββββ΄βββββ | |
| β SW1 βββββββββββββββ SW2 ββββββββββββββββββββ SW3 β | |
| β Access β Trunk β Core β Trunk β Access β | |
| ββββββ¬βββββ ββββββ¬βββββ ββββββ¬βββββ | |
| | | | | |
| PC2 PC4 PC6 | |
| VLAN 10 VLAN 20 VLAN 30 | |
| Internet Cloud (optional WAN simulation) | |
| CCNA Skills Practiced: | |
| - VLAN configuration and trunking | |
| - Layer 2 switching concepts | |
| - Inter-VLAN routing (when routers added) | |
| - Basic connectivity testing | |
| - Network troubleshooting | |
| """) | |
| print("="*70 + "\n") | |
| nodes = {} | |
| # Create switches | |
| print("Creating Switches...") | |
| nodes['SW1'] = create_switch(project_id, "SW1-Access", -300, 0, ports=8) | |
| if nodes['SW1']: print(f" β SW1-Access (VLAN 10 - Sales)") | |
| time.sleep(0.5) | |
| nodes['SW2'] = create_switch(project_id, "SW2-Core", 0, 0, ports=16) | |
| if nodes['SW2']: print(f" β SW2-Core (Trunk/Core)") | |
| time.sleep(0.5) | |
| nodes['SW3'] = create_switch(project_id, "SW3-Access", 300, 0, ports=8) | |
| if nodes['SW3']: print(f" β SW3-Access (VLAN 20 - Engineering)") | |
| time.sleep(0.5) | |
| # Create PCs | |
| print("\nCreating Virtual PCs (VPCS)...") | |
| nodes['PC1'] = create_vpcs(project_id, "PC1-Sales", -400, -100) | |
| if nodes['PC1']: print(f" β PC1-Sales (VLAN 10)") | |
| time.sleep(0.3) | |
| nodes['PC2'] = create_vpcs(project_id, "PC2-Sales", -400, 100) | |
| if nodes['PC2']: print(f" β PC2-Sales (VLAN 10)") | |
| time.sleep(0.3) | |
| nodes['PC3'] = create_vpcs(project_id, "PC3-Engineering", -100, -100) | |
| if nodes['PC3']: print(f" β PC3-Engineering (VLAN 20)") | |
| time.sleep(0.3) | |
| nodes['PC4'] = create_vpcs(project_id, "PC4-Engineering", 100, -100) | |
| if nodes['PC4']: print(f" β PC4-Engineering (VLAN 20)") | |
| time.sleep(0.3) | |
| nodes['PC5'] = create_vpcs(project_id, "PC5-Guest", 400, -100) | |
| if nodes['PC5']: print(f" β PC5-Guest (VLAN 30)") | |
| time.sleep(0.3) | |
| nodes['PC6'] = create_vpcs(project_id, "PC6-Guest", 400, 100) | |
| if nodes['PC6']: print(f" β PC6-Guest (VLAN 30)") | |
| time.sleep(0.3) | |
| # Create Cloud for Internet/WAN simulation | |
| print("\nCreating WAN Simulation...") | |
| nodes['Internet'] = create_cloud(project_id, "Internet", 0, 150) | |
| if nodes['Internet']: print(f" β Internet Cloud (WAN)") | |
| time.sleep(0.5) | |
| # Create links | |
| 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): | |
| print(f" β PC1-Sales <-> SW1 (Port 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'], 1, 0): | |
| print(f" β PC2-Sales <-> SW1 (Port 1)") | |
| links += 1 | |
| # SW1 -> SW2 (Trunk) | |
| if nodes.get('SW1') and nodes.get('SW2'): | |
| if create_link(project_id, nodes['SW1']['node_id'], 7, 0, nodes['SW2']['node_id'], 0, 0): | |
| print(f" β SW1 <-> SW2 (Trunk)") | |
| links += 1 | |
| # PC3 -> SW2 (could be connected directly for mixed topology) | |
| if nodes.get('PC3') and nodes.get('SW2'): | |
| if create_link(project_id, nodes['PC3']['node_id'], 0, 0, nodes['SW2']['node_id'], 1, 0): | |
| print(f" β PC3-Engineering <-> SW2 (Port 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'], 2, 0): | |
| print(f" β PC4-Engineering <-> SW2 (Port 2)") | |
| links += 1 | |
| # SW2 -> SW3 (Trunk) | |
| if nodes.get('SW2') and nodes.get('SW3'): | |
| if create_link(project_id, nodes['SW2']['node_id'], 7, 0, nodes['SW3']['node_id'], 7, 0): | |
| print(f" β SW2 <-> SW3 (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): | |
| print(f" β PC5-Guest <-> SW3 (Port 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'], 1, 0): | |
| print(f" β PC6-Guest <-> SW3 (Port 1)") | |
| links += 1 | |
| # Internet -> SW2 (for future router uplink) | |
| if nodes.get('Internet') and nodes.get('SW2'): | |
| if create_link(project_id, nodes['Internet']['node_id'], 0, 0, nodes['SW2']['node_id'], 15, 0): | |
| print(f" β Internet Cloud <-> SW2 (Port 15)") | |
| links += 1 | |
| # Summary | |
| print("\n" + "="*70) | |
| print("β CCNA LAB TOPOLOGY CREATED!") | |
| print("="*70) | |
| print(f"\nDevices: {len([n for n in nodes.values() if n])} nodes") | |
| print(f"Links: {links} connections") | |
| print("\nπ CCNA LAB EXERCISES:") | |
| print("\n Basic Configuration:") | |
| print(" β’ Configure VLANs 10, 20, 30 on all switches") | |
| print(" β’ Set trunk ports between SW1-SW2 and SW2-SW3") | |
| print(" β’ Assign access ports to appropriate VLANs") | |
| print(" β’ Configure PC IP addresses in respective subnets") | |
| print("\n IP Addressing Scheme:") | |
| print(" VLAN 10 (Sales): 10.1.10.0/24") | |
| print(" - PC1: 10.1.10.10") | |
| print(" - PC2: 10.1.10.11") | |
| print(" VLAN 20 (Engineering): 10.1.20.0/24") | |
| print(" - PC3: 10.1.20.10") | |
| print(" - PC4: 10.1.20.11") | |
| print(" VLAN 30 (Guest): 10.1.30.0/24") | |
| print(" - PC5: 10.1.30.10") | |
| print(" - PC6: 10.1.30.11") | |
| print("\n VPCS Configuration Commands:") | |
| print(" On PC1: ip 10.1.10.10/24 10.1.10.1") | |
| print(" On PC2: ip 10.1.10.11/24 10.1.10.1") | |
| print(" On PC3: ip 10.1.20.10/24 10.1.20.1") | |
| print(" On PC4: ip 10.1.20.11/24 10.1.20.1") | |
| print(" On PC5: ip 10.1.30.10/24 10.1.30.1") | |
| print(" On PC6: ip 10.1.30.11/24 10.1.30.1") | |
| print("\n Testing:") | |
| print(" β’ Ping between PCs in same VLAN (should work)") | |
| print(" β’ Ping between PCs in different VLANs (will fail without router)") | |
| print(" β’ Use 'show vlan' to verify VLAN configuration") | |
| print(" β’ Use 'show interfaces trunk' to verify trunk links") | |
| print("\n Next Steps (When adding routers):") | |
| print(" β’ Add router for inter-VLAN routing") | |
| print(" β’ Configure router-on-a-stick (802.1Q)") | |
| print(" β’ Setup DHCP server on router") | |
| print(" β’ Configure NAT/PAT for Internet access") | |
| print("\nπ Ready to start! Open GNS3 GUI to begin configuration.") | |
| print("="*70) | |
| if __name__ == "__main__": | |
| main() | |