Spaces:
Running
Running
| #!/usr/bin/env python3 | |
| """ | |
| MCP Tool: Auto-configure GreenLeaf Coffee network switches | |
| 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' in line and ('SW-HQ' in line or 'SW-West' in line or 'SW-East' in line): | |
| # Extract switch name | |
| if 'SW-HQ-Core' in line: | |
| name = 'SW-HQ-Core' | |
| elif 'SW-West' in line: | |
| name = 'SW-West' | |
| elif 'SW-East' in line: | |
| name = 'SW-East' | |
| else: | |
| continue | |
| # Extract serial telnet port | |
| 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}") | |
| # Define configurations for each switch | |
| configs = { | |
| 'SW-HQ-Core': [ | |
| "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", | |
| "!", | |
| "! Trunk ports to stores (WAN simulation)", | |
| "interface ethernet 10", | |
| " description WAN to SW-West", | |
| " switchport trunk encapsulation dot1q", | |
| " switchport mode trunk", | |
| " no shutdown", | |
| "interface ethernet 11", | |
| " description WAN to SW-East", | |
| " 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 #", | |
| ], | |
| 'SW-West': [ | |
| "configure terminal", | |
| "hostname SW-West", | |
| "!", | |
| "! VLAN Configuration", | |
| "vlan 10", | |
| " name Sales", | |
| "vlan 99", | |
| " name Management", | |
| "exit", | |
| "!", | |
| "! Management interface", | |
| "interface vlan 99", | |
| " ip address 10.99.0.10 255.255.255.0", | |
| " no shutdown", | |
| "exit", | |
| "!", | |
| "! Trunk to HQ", | |
| "interface ethernet 13", | |
| " description WAN to HQ", | |
| " switchport trunk encapsulation dot1q", | |
| " switchport mode trunk", | |
| " no shutdown", | |
| "!", | |
| "! POS Terminal", | |
| "interface ethernet 0", | |
| " description POS-West", | |
| " switchport mode access", | |
| " switchport access vlan 10", | |
| " spanning-tree portfast", | |
| " no shutdown", | |
| "!", | |
| "! WiFi Access Point", | |
| "interface ethernet 1", | |
| " description WiFi-West", | |
| " 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", | |
| "!", | |
| "banner motd # GreenLeaf Coffee Store-West - Authorized Access Only #", | |
| ], | |
| 'SW-East': [ | |
| "configure terminal", | |
| "hostname SW-East", | |
| "!", | |
| "! VLAN Configuration", | |
| "vlan 20", | |
| " name Engineering", | |
| "vlan 99", | |
| " name Management", | |
| "exit", | |
| "!", | |
| "! Management interface", | |
| "interface vlan 99", | |
| " ip address 10.99.0.20 255.255.255.0", | |
| " no shutdown", | |
| "exit", | |
| "!", | |
| "! Trunk to HQ", | |
| "interface ethernet 13", | |
| " description WAN to HQ", | |
| " switchport trunk encapsulation dot1q", | |
| " switchport mode trunk", | |
| " no shutdown", | |
| "!", | |
| "! POS Terminal", | |
| "interface ethernet 0", | |
| " description POS-East", | |
| " switchport mode access", | |
| " switchport access vlan 20", | |
| " spanning-tree portfast", | |
| " no shutdown", | |
| "!", | |
| "! WiFi Access Point", | |
| "interface ethernet 1", | |
| " description WiFi-East", | |
| " switchport mode access", | |
| " switchport access vlan 20", | |
| " 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 motd # GreenLeaf Coffee Store-East - Authorized Access Only #", | |
| ], | |
| } | |
| # Configure each switch | |
| results = {} | |
| for switch_name in ['SW-HQ-Core', 'SW-West', 'SW-East']: | |
| if switch_name in ports: | |
| port = ports[switch_name] | |
| commands = configs.get(switch_name, []) | |
| success = configure_switch('localhost', port, switch_name, commands) | |
| results[switch_name] = success | |
| else: | |
| print(f"\n⚠️ {switch_name} not found in running processes") | |
| results[switch_name] = False | |
| # 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 all(results.values()): | |
| print("\n🎉 ALL SWITCHES CONFIGURED!") | |
| print("\n📋 Network Details:") | |
| print(" • HQ Management IP: 10.99.0.1") | |
| print(" • Store-West Mgmt IP: 10.99.0.10") | |
| print(" • Store-East Mgmt IP: 10.99.0.20") | |
| print("\n🔐 SSH Credentials:") | |
| print(" • Username: admin") | |
| print(" • Password: overgrowth123") | |
| print("\n✨ Next: SSH into switches for remote management!") | |
| print(" ssh [email protected]") | |
| else: | |
| print("\n⚠️ Some switches failed to configure") | |
| print(" Check console output for errors") | |
| print("="*70) | |
| if __name__ == "__main__": | |
| main() | |