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