overgrowth / mcp-server /build_real_ccna_lab.py
Graham Paasch
Fix: Use environment variables for GNS3 server URL
c7576e1
raw
history blame
10.5 kB
#!/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()