overgrowth / mcp-server /build_ccna_topology.py
Graham Paasch
Fix: Use environment variables for GNS3 server URL
c7576e1
#!/usr/bin/env python3
"""
Create a CCNA-level topology in the overgrowth GNS3 project
Classic topology: 2 routers + 2 switches + 2 PCs
"""
import requests
import json
import time
import sys
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):
"""Get project ID by 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):
"""Delete all existing nodes"""
resp = requests.get(f"{GNS3_API}/projects/{project_id}/nodes")
nodes = resp.json()
print(f"Deleting {len(nodes)} existing nodes...")
for node in nodes:
requests.delete(f"{GNS3_API}/projects/{project_id}/nodes/{node['node_id']}")
print(f" Deleted {node['name']}")
time.sleep(1)
def get_templates():
"""Get available templates"""
resp = requests.get(f"{GNS3_API}/templates")
return resp.json()
def find_template(templates, keywords):
"""Find template matching keywords"""
for t in templates:
name = t.get('name', '').lower()
for kw in keywords:
if kw.lower() in name:
return t
return None
def create_node(project_id, name, x, y, template=None, node_type=None):
"""Create a node"""
data = {
"name": name,
"compute_id": "local",
"x": x,
"y": y
}
if template:
data["node_type"] = template.get('template_type', 'qemu')
data["template_id"] = template['template_id']
elif node_type:
data["node_type"] = node_type
try:
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
except Exception as e:
print(f" Error creating {name}: {e}")
return None
def create_link(project_id, node1_id, adapter1, port1, node2_id, adapter2, port2):
"""Create a link between two nodes"""
data = {
"nodes": [
{
"node_id": node1_id,
"adapter_number": adapter1,
"port_number": port1
},
{
"node_id": node2_id,
"adapter_number": adapter2,
"port_number": port2
}
]
}
try:
resp = requests.post(
f"{GNS3_API}/projects/{project_id}/links",
json=data
)
return resp.json() if resp.status_code in [200, 201] else None
except Exception as e:
print(f" Link error: {e}")
return None
def main():
# Get project
project_id = get_project_id(PROJECT_NAME)
if not project_id:
print(f"Project '{PROJECT_NAME}' not found!")
return
print(f"Working with project: {PROJECT_NAME} ({project_id})")
# Clean up existing nodes
delete_all_nodes(project_id)
# Get templates
print("\nFetching templates...")
templates = get_templates()
# Look for IOSv router template
router_template = find_template(templates, ['IOSv', 'cisco ios', 'c7200'])
if router_template:
print(f" Found router: {router_template['name']}")
# Look for IOSvL2 switch template
switch_template = find_template(templates, ['IOSvL2', 'iosvl2', 'l2-ios'])
if switch_template:
print(f" Found switch: {switch_template['name']}")
# VPCS for PCs
vpcs_template = find_template(templates, ['VPCS', 'vpcs'])
if vpcs_template:
print(f" Found PC: {vpcs_template['name']}")
print("\n" + "="*60)
print("Creating CCNA Topology")
print("="*60)
print("""
Topology Design:
PC1 PC2
| |
[Switch1]---[Router1]---[Router2]---[Switch2]
| |
PC3 PC4
- 2 Routers (R1, R2) connected via serial/ethernet
- 2 Switches (SW1, SW2) one per router
- 4 PCs (PC1-4) for testing connectivity
""")
print("="*60 + "\n")
nodes = {}
# Create Router 1 (left side)
if router_template:
print("Creating Router1...")
nodes['R1'] = create_node(project_id, "R1", -200, -50, template=router_template)
if nodes['R1']:
print(f" βœ“ Created {nodes['R1']['name']}")
time.sleep(1)
# Create Router 2 (right side)
if router_template:
print("Creating Router2...")
nodes['R2'] = create_node(project_id, "R2", 200, -50, template=router_template)
if nodes['R2']:
print(f" βœ“ Created {nodes['R2']['name']}")
time.sleep(1)
# Create Switch 1 (left)
if switch_template:
print("Creating Switch1...")
nodes['SW1'] = create_node(project_id, "SW1", -200, 100, template=switch_template)
if nodes['SW1']:
print(f" βœ“ Created {nodes['SW1']['name']}")
time.sleep(1)
else:
# Fallback to ethernet switch
print("Creating Switch1 (ethernet switch)...")
nodes['SW1'] = create_node(project_id, "SW1", -200, 100, node_type="ethernet_switch")
if nodes['SW1']:
print(f" βœ“ Created {nodes['SW1']['name']}")
time.sleep(1)
# Create Switch 2 (right)
if switch_template:
print("Creating Switch2...")
nodes['SW2'] = create_node(project_id, "SW2", 200, 100, template=switch_template)
if nodes['SW2']:
print(f" βœ“ Created {nodes['SW2']['name']}")
time.sleep(1)
else:
print("Creating Switch2 (ethernet switch)...")
nodes['SW2'] = create_node(project_id, "SW2", 200, 100, node_type="ethernet_switch")
if nodes['SW2']:
print(f" βœ“ Created {nodes['SW2']['name']}")
time.sleep(1)
# Create PCs using VPCS
if vpcs_template:
print("Creating PC1...")
nodes['PC1'] = create_node(project_id, "PC1", -300, 100, template=vpcs_template)
if nodes['PC1']:
print(f" βœ“ Created {nodes['PC1']['name']}")
time.sleep(0.5)
print("Creating PC2...")
nodes['PC2'] = create_node(project_id, "PC2", 300, 100, template=vpcs_template)
if nodes['PC2']:
print(f" βœ“ Created {nodes['PC2']['name']}")
time.sleep(0.5)
print("Creating PC3...")
nodes['PC3'] = create_node(project_id, "PC3", -300, 200, template=vpcs_template)
if nodes['PC3']:
print(f" βœ“ Created {nodes['PC3']['name']}")
time.sleep(0.5)
print("Creating PC4...")
nodes['PC4'] = create_node(project_id, "PC4", 300, 200, template=vpcs_template)
if nodes['PC4']:
print(f" βœ“ Created {nodes['PC4']['name']}")
time.sleep(0.5)
# Create links
print("\n" + "="*60)
print("Creating Links")
print("="*60 + "\n")
links_created = 0
# R1 <-> R2 (core link)
if nodes.get('R1') and nodes.get('R2'):
print("Linking R1 <-> R2 (Gi0/0 <-> Gi0/0)...")
link = create_link(project_id,
nodes['R1']['node_id'], 0, 0,
nodes['R2']['node_id'], 0, 0)
if link:
print(f" βœ“ Connected")
links_created += 1
# R1 <-> SW1
if nodes.get('R1') and nodes.get('SW1'):
print("Linking R1 <-> SW1 (Gi0/1 <-> port 0)...")
link = create_link(project_id,
nodes['R1']['node_id'], 1, 0,
nodes['SW1']['node_id'], 0, 0)
if link:
print(f" βœ“ Connected")
links_created += 1
# R2 <-> SW2
if nodes.get('R2') and nodes.get('SW2'):
print("Linking R2 <-> SW2 (Gi0/1 <-> port 0)...")
link = create_link(project_id,
nodes['R2']['node_id'], 1, 0,
nodes['SW2']['node_id'], 0, 0)
if link:
print(f" βœ“ Connected")
links_created += 1
# PC1 <-> SW1
if nodes.get('PC1') and nodes.get('SW1'):
print("Linking PC1 <-> SW1...")
link = create_link(project_id,
nodes['PC1']['node_id'], 0, 0,
nodes['SW1']['node_id'], 1, 0)
if link:
print(f" βœ“ Connected")
links_created += 1
# PC3 <-> SW1
if nodes.get('PC3') and nodes.get('SW1'):
print("Linking PC3 <-> SW1...")
link = create_link(project_id,
nodes['PC3']['node_id'], 0, 0,
nodes['SW1']['node_id'], 2, 0)
if link:
print(f" βœ“ Connected")
links_created += 1
# PC2 <-> SW2
if nodes.get('PC2') and nodes.get('SW2'):
print("Linking PC2 <-> SW2...")
link = create_link(project_id,
nodes['PC2']['node_id'], 0, 0,
nodes['SW2']['node_id'], 1, 0)
if link:
print(f" βœ“ Connected")
links_created += 1
# PC4 <-> SW2
if nodes.get('PC4') and nodes.get('SW2'):
print("Linking PC4 <-> SW2...")
link = create_link(project_id,
nodes['PC4']['node_id'], 0, 0,
nodes['SW2']['node_id'], 2, 0)
if link:
print(f" βœ“ Connected")
links_created += 1
# Summary
print("\n" + "="*60)
print("Topology Created!")
print("="*60)
print(f"\nNodes created: {len([n for n in nodes.values() if n])}")
print(f"Links created: {links_created}")
print("\nCCNA Lab Scenarios Ready:")
print(" β€’ Static routing between R1 and R2")
print(" β€’ OSPF/EIGRP dynamic routing")
print(" β€’ Inter-VLAN routing on switches")
print(" β€’ Access lists and security")
print(" β€’ NAT/PAT configuration")
print(" β€’ Basic switch configuration (VLANs, trunking)")
print("\nInitial IP Plan Suggestion:")
print(" Network 1 (Left): 10.1.1.0/24")
print(" - R1 Gi0/1: 10.1.1.1")
print(" - PC1: 10.1.1.10")
print(" - PC3: 10.1.1.11")
print(" Network 2 (Right): 10.1.2.0/24")
print(" - R2 Gi0/1: 10.1.2.1")
print(" - PC2: 10.1.2.10")
print(" - PC4: 10.1.2.11")
print(" WAN Link: 10.1.100.0/30")
print(" - R1 Gi0/0: 10.1.100.1")
print(" - R2 Gi0/0: 10.1.100.2")
print("\nβœ“ Open project in GNS3 GUI to start devices and configure!")
if __name__ == "__main__":
main()