#!/usr/bin/env python3 """ MCP Tool: Auto-configure GreenLeaf Coffee network switches (HQ + dynamic stores) Uses telnet to send initial configuration to all switches """ import telnetlib import time import requests import re 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_actual_console_ports(): """Extract real console ports from QEMU processes""" import subprocess result = subprocess.run(['ps', 'aux'], capture_output=True, text=True) ports = {} for line in result.stdout.split('\n'): if 'qemu-system-x86_64' not in line: continue name = None if 'SW-HQ-Core' in line: name = 'SW-HQ-Core' else: m = re.search(r'SW-Store-(\d+)', line) if m: name = f"SW-Store-{m.group(1)}" if not name: continue match = re.search(r'-serial telnet:127\.0\.0\.1:(\d+)', line) if match: ports[name] = int(match.group(1)) return ports def configure_switch(host, port, switch_name, config_commands): """Send configuration to switch via telnet""" print(f"\n{'='*60}") print(f"Configuring {switch_name} on port {port}...") print('='*60) try: tn = telnetlib.Telnet(host, port, timeout=10) # Wake up console tn.write(b"\r\n") time.sleep(1) # Read initial output output = tn.read_very_eager().decode('utf-8', errors='ignore') # Check if we need to press RETURN to start if "Press RETURN to get started" in output or output.strip() == "": print(" → Pressing RETURN to start...") tn.write(b"\r\n") time.sleep(2) output = tn.read_very_eager().decode('utf-8', errors='ignore') # Enter enable mode if at user prompt if ">" in output: print(" → Entering enable mode...") tn.write(b"enable\r\n") time.sleep(1) tn.read_very_eager() # Send each config command for cmd in config_commands: print(f" → {cmd}") tn.write(cmd.encode('utf-8') + b"\r\n") time.sleep(0.5) response = tn.read_very_eager().decode('utf-8', errors='ignore') # Check for errors if "Invalid" in response or "Error" in response: print(f" ⚠️ Warning: {response[:100]}") # Exit config mode tn.write(b"end\r\n") time.sleep(0.5) # Save config print(" → Saving configuration...") tn.write(b"write memory\r\n") time.sleep(2) response = tn.read_very_eager().decode('utf-8', errors='ignore') if "OK" in response or "[OK]" in response: print(" ✅ Configuration saved successfully!") tn.close() return True except Exception as e: print(f" ❌ Error: {e}") return False def main(): print("="*70) print("🌿 GREENLEAF COFFEE - AUTOMATED NETWORK CONFIGURATION") print("="*70) print("\nUsing MCP automation to configure all switches...\n") # Get actual console ports print("🔍 Discovering switch console ports...") ports = get_actual_console_ports() if not ports: print("❌ No switches found! Make sure they're running.") return print(f"✅ Found {len(ports)} switches:") for name, port in ports.items(): print(f" • {name:20} → telnet://localhost:{port}") def hq_config(): return [ "configure terminal", "hostname SW-HQ-Core", "!", "! VLAN Configuration", "vlan 10", " name Sales", "vlan 20", " name Engineering", "vlan 99", " name Management", "exit", "!", "! Management interface", "interface vlan 99", " ip address 10.99.0.1 255.255.255.0", " no shutdown", "exit", "!", "! WAN uplink", "interface ethernet 15", " description WAN to Internet/MPLS", " switchport trunk encapsulation dot1q", " switchport mode trunk", " no shutdown", "!", "! Server port", "interface ethernet 0", " description Server-DB", " switchport mode access", " switchport access vlan 99", " spanning-tree portfast", " no shutdown", "!", "! Office PC port", "interface ethernet 1", " description Office-Manager", " switchport mode access", " switchport access vlan 99", " spanning-tree portfast", " no shutdown", "!", "! Enable SSH", "ip domain-name greenleaf.local", "crypto key generate rsa modulus 2048", "!", "username admin privilege 15 secret overgrowth123", "line vty 0 4", " login local", " transport input ssh", "!", "! Banner", "banner motd # GreenLeaf Coffee HQ - Authorized Access Only #", ] def store_switch_config(name: str, idx: int) -> list: mgmt_octet = 10 + idx if idx > 0 else 10 return [ "configure terminal", f"hostname {name}", "!", "! VLAN Configuration", "vlan 10", " name Sales", "vlan 99", " name Management", "exit", "!", "! Management interface", "interface vlan 99", f" ip address 10.99.0.{mgmt_octet} 255.255.255.0", " no shutdown", "exit", "!", "! Trunk to WAN", "interface ethernet 15", " description WAN to Internet/MPLS", " switchport trunk encapsulation dot1q", " switchport mode trunk", " no shutdown", "!", "! POS Terminal", "interface ethernet 0", f" description POS-{name}", " switchport mode access", " switchport access vlan 10", " spanning-tree portfast", " no shutdown", "!", "! WiFi Access Point", "interface ethernet 1", f" description WiFi-{name}", " switchport mode access", " switchport access vlan 10", " spanning-tree portfast", " no shutdown", "!", "! Enable SSH", "ip domain-name greenleaf.local", "crypto key generate rsa modulus 2048", "username admin privilege 15 secret overgrowth123", "line vty 0 4", " login local", " transport input ssh", "!", f"banner motd # GreenLeaf Coffee {name} - Authorized Access Only #", ] # Configure each switch results = {} for switch_name, port in ports.items(): if switch_name == 'SW-HQ-Core': commands = hq_config() elif switch_name.startswith('SW-Store-'): idx_match = re.search(r'SW-Store-(\d+)', switch_name) idx = int(idx_match.group(1)) if idx_match else 0 commands = store_switch_config(switch_name, idx) else: continue success = configure_switch('localhost', port, switch_name, commands) results[switch_name] = success # Summary print("\n" + "="*70) print("CONFIGURATION SUMMARY") print("="*70) for switch, success in results.items(): status = "✅ SUCCESS" if success else "❌ FAILED" print(f" {switch:20} {status}") if results: if all(results.values()): print("\n🎉 ALL SWITCHES CONFIGURED!") else: print("\n⚠️ Some switches failed to configure") print(" Check console output for errors") else: print("\n⚠️ No switches were configured") if results: print("\n📋 Network Details:") print(" • HQ Management IP: 10.99.0.1") for name in sorted(results.keys()): if name.startswith("SW-Store-"): m = re.search(r"SW-Store-(\d+)", name) idx = int(m.group(1)) if m else 0 mgmt_ip = f"10.99.0.{10 + idx if idx > 0 else 10}" print(f" • {name:18} Mgmt IP: {mgmt_ip}") print("\n🔐 SSH Credentials:") print(" • Username: admin") print(" • Password: overgrowth123") print("\n✨ Next: SSH into switches for remote management!") print(" ssh admin@10.99.0.1") print("="*70) if __name__ == "__main__": main()