overgrowth / mcp-server /rebuild_clean_ccna.py
Graham Paasch
Fix: Use environment variables for GNS3 server URL
c7576e1
raw
history blame
7.65 kB
#!/usr/bin/env python3
"""
Rebuild CCNA topology with:
- Proper switch icons
- Single trunk links (no redundancy)
- Clean hierarchical layout
- Simple access-core-access design
"""
import requests
import json
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']}")
def create_switch(project_id, name, x, y):
"""Create Cisco IOSvL2 switch with PROPER ICON"""
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,
"ram": 1024,
"hda_disk_image": "vios_l2-adventerprisek9-m.03.2017.qcow2"
},
"symbol": ":/symbols/multilayer_switch.svg", # PROPER SWITCH ICON!
"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_pc(project_id, name, x, y):
"""Create VPCS with proper computer icon"""
data = {
"name": name,
"node_type": "vpcs",
"compute_id": "local",
"symbol": ":/symbols/vpcs_guest.svg", # Better PC icon
"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 CLEAN CCNA TOPOLOGY")
print("="*70)
print()
delete_all_nodes(project_id)
print("πŸ“ Creating topology with hierarchical layout...\n")
# Clean hierarchical layout:
# Top row: SW2-Core (center, top)
# Middle row: SW1-Access (left) and SW3-Access (right)
# Bottom rows: PCs under each switch
nodes = {}
# CORE SWITCH (top center)
print("Creating Core Switch...")
nodes['SW2'] = create_switch(project_id, "SW2-Core", 0, -150)
if nodes['SW2']: print(" βœ“ SW2-Core (Distribution/Core)")
# ACCESS SWITCHES (middle tier)
print("\nCreating Access Switches...")
nodes['SW1'] = create_switch(project_id, "SW1-Sales", -350, 0)
if nodes['SW1']: print(" βœ“ SW1-Sales (Access, VLAN 10)")
nodes['SW3'] = create_switch(project_id, "SW3-Eng", 350, 0)
if nodes['SW3']: print(" βœ“ SW3-Eng (Access, VLAN 20)")
# PCs (bottom tier, under their access switches)
print("\nCreating Virtual PCs...")
nodes['PC1'] = create_pc(project_id, "PC1-Sales", -450, 150)
if nodes['PC1']: print(" βœ“ PC1-Sales (10.1.10.10)")
nodes['PC2'] = create_pc(project_id, "PC2-Sales", -250, 150)
if nodes['PC2']: print(" βœ“ PC2-Sales (10.1.10.11)")
nodes['PC3'] = create_pc(project_id, "PC3-Eng", 250, 150)
if nodes['PC3']: print(" βœ“ PC3-Eng (10.1.20.10)")
nodes['PC4'] = create_pc(project_id, "PC4-Eng", 450, 150)
if nodes['PC4']: print(" βœ“ PC4-Eng (10.1.20.11)")
# Wait for nodes to be ready
import time
print("\n⏱️ Waiting 2 seconds for nodes to initialize...")
time.sleep(2)
# Refresh node data
resp = requests.get(f"{GNS3_API}/projects/{project_id}/nodes")
all_nodes = {n['name']: n for n in resp.json()}
for name in nodes.keys():
if name in ['SW1', 'SW2', 'SW3']:
node_name = nodes[name]['name']
else:
node_name = nodes[name]['name']
if node_name in all_nodes:
nodes[name] = all_nodes[node_name]
print("\nπŸ”— Creating 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-Sales e0"):
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,
"PC2-Sales β†’ SW1-Sales e1"):
links += 1
# SW1 β†’ SW2 (SINGLE trunk - access to core)
if nodes.get('SW1') and nodes.get('SW2'):
if create_link(project_id, nodes['SW1']['node_id'], 15, 0,
nodes['SW2']['node_id'], 0, 0,
"SW1-Sales e15 ↔ SW2-Core e0 (TRUNK)"):
links += 1
# SW3 β†’ SW2 (SINGLE trunk - access to core)
if nodes.get('SW3') and nodes.get('SW2'):
if create_link(project_id, nodes['SW3']['node_id'], 15, 0,
nodes['SW2']['node_id'], 1, 0,
"SW3-Eng e15 ↔ SW2-Core e1 (TRUNK)"):
links += 1
# PC3 β†’ SW3
if nodes.get('PC3') and nodes.get('SW3'):
if create_link(project_id, nodes['PC3']['node_id'], 0, 0,
nodes['SW3']['node_id'], 0, 0,
"PC3-Eng β†’ SW3-Eng e0"):
links += 1
# PC4 β†’ SW3
if nodes.get('PC4') and nodes.get('SW3'):
if create_link(project_id, nodes['PC4']['node_id'], 0, 0,
nodes['SW3']['node_id'], 1, 0,
"PC4-Eng β†’ SW3-Eng e1"):
links += 1
print("\n" + "="*70)
print("βœ… CLEAN CCNA TOPOLOGY COMPLETE!")
print("="*70)
print(f"\nπŸ“Š Devices: {len([n for n in nodes.values() if n])}")
print(f" - 3x Cisco IOSvL2 switches (with proper icons! 🎯)")
print(f" - 4x VPCS (Virtual PCs)")
print(f"πŸ”— Links: {links} (NO redundant port-channels)")
print("\nπŸ“ Topology Design:")
print("```")
print(" SW2-Core")
print(" / \\")
print(" SW1-Sales SW3-Eng")
print(" / \\ / \\")
print(" PC1 PC2 PC3 PC4")
print(" (Sales) (Engineering)")
print("```")
print("\nπŸŽ“ VLAN Design:")
print(" β€’ SW1-Sales: VLAN 10 (10.1.10.0/24)")
print(" β€’ SW3-Eng: VLAN 20 (10.1.20.0/24)")
print(" β€’ Trunk ports: e15 on access, e0/e1 on core")
print("\n✨ Open GNS3 GUI to see the clean topology with proper icons!")
print("="*70)
if __name__ == "__main__":
main()