"""CLI command generators for Cisco devices""" from typing import List, Dict, Any, Optional def generate_hostname_cli(hostname: str) -> List[str]: """Generate hostname configuration command""" return [f"hostname {hostname}"] def generate_vlan_cli(vlans: List[Dict[str, Any]]) -> List[str]: """ Generate VLAN configuration commands Args: vlans: List of dicts with keys: - id (int) - name (str) Returns: List of CLI commands """ commands = [] for vlan in vlans: vlan_id = vlan.get("id") vlan_name = vlan.get("name", f"VLAN{vlan_id}") commands.append(f"vlan {vlan_id}") commands.append(f" name {vlan_name}") commands.append("!") return commands def generate_interface_cli(interfaces: List[Dict[str, Any]]) -> List[str]: """ Generate interface configuration commands Args: interfaces: List of dicts with keys: - name (str): e.g., "GigabitEthernet0/1" - description (str) - type (str): "access" or "trunk" - vlan (int): VLAN ID for access ports - trunk_vlans (list): VLAN IDs for trunk - ip_address (str): IP address (e.g., "10.0.0.1/24") - enabled (bool) Returns: List of CLI commands """ commands = [] for iface in interfaces: iface_name = iface.get("name") description = iface.get("description") iface_type = iface.get("type", "access") enabled = iface.get("enabled", True) commands.append(f"interface {iface_name}") if description: commands.append(f" description {description}") # Switchport configuration if iface_type == "access": commands.append(" switchport mode access") vlan = iface.get("vlan") if vlan: commands.append(f" switchport access vlan {vlan}") elif iface_type == "trunk": commands.append(" switchport mode trunk") trunk_vlans = iface.get("trunk_vlans") if trunk_vlans: vlan_list = ",".join(map(str, trunk_vlans)) commands.append(f" switchport trunk allowed vlan {vlan_list}") # IP configuration ip_address = iface.get("ip_address") if ip_address: # Assume CIDR notation, convert to netmask # e.g., "10.0.0.1/24" -> "10.0.0.1 255.255.255.0" commands.append(f" ip address {ip_address.replace('/', ' ')}") # Enable/disable if not enabled: commands.append(" shutdown") else: commands.append(" no shutdown") commands.append("!") return commands def generate_routing_cli(routes: List[Dict[str, Any]]) -> List[str]: """ Generate static routing commands Args: routes: List of dicts with keys: - destination (str): CIDR notation - gateway (str): Next-hop IP - metric (int): Optional metric/distance Returns: List of CLI commands """ commands = [] for route in routes: destination = route.get("destination") gateway = route.get("gateway") metric = route.get("metric") cmd = f"ip route {destination} {gateway}" if metric: cmd += f" {metric}" commands.append(cmd) return commands def generate_nat_cli(nat_config: Dict[str, Any]) -> List[str]: """ Generate NAT (Network Address Translation) commands Args: nat_config: Dict with keys: - inside_interface (str): Inside interface name - outside_interface (str): Outside interface name - inside_addresses (list): List of inside networks in CIDR - outside_address (str): Single public IP for overload Returns: List of CLI commands """ commands = [] # Mark inside/outside interfaces inside_iface = nat_config.get("inside_interface") outside_iface = nat_config.get("outside_interface") if inside_iface: commands.append(f"interface {inside_iface}") commands.append(" ip nat inside") commands.append("!") if outside_iface: commands.append(f"interface {outside_iface}") commands.append(" ip nat outside") commands.append("!") # NAT rules inside_addresses = nat_config.get("inside_addresses", []) outside_address = nat_config.get("outside_address") for idx, inside_network in enumerate(inside_addresses, start=1): acl_id = 100 + idx commands.append(f"ip access-list standard NAT_INSIDE") commands.append(f" {idx} permit {inside_network}") commands.append("!") if outside_address: commands.append("ip nat inside source list 101 interface GigabitEthernet0/0 overload") return commands def generate_acl_cli(acls: List[Dict[str, Any]]) -> List[str]: """ Generate ACL (Access Control List) commands Args: acls: List of dicts with keys: - name (str) or acl_id (int) - type (str): "standard" or "extended" - rules (list): List of dicts: - action (str): "permit" or "deny" - protocol (str): "ip", "tcp", "udp", etc. - source (str): IP/CIDR or "any" - destination (str): IP/CIDR (extended only) - port (int): Port number (extended + protocol-specific) Returns: List of CLI commands """ commands = [] for acl in acls: acl_type = acl.get("type", "standard") acl_name = acl.get("name") acl_id = acl.get("acl_id") # ACL header if acl_type == "standard": if acl_id: acl_header = f"access-list {acl_id}" else: acl_header = f"ip access-list standard {acl_name}" else: # extended if acl_id: acl_header = f"access-list {acl_id}" else: acl_header = f"ip access-list extended {acl_name}" # If named ACL, enter config mode if acl_name: commands.append(acl_header) # ACL rules for rule_idx, rule in enumerate(acl.get("rules", []), start=1): action = rule.get("action", "permit") protocol = rule.get("protocol", "ip") source = rule.get("source", "any") if acl_type == "standard": cmd = f" {rule_idx} {action} {source}" else: # extended destination = rule.get("destination", "any") cmd = f" {rule_idx} {action} {protocol} {source} {destination}" # Add port if applicable port = rule.get("port") if port: cmd += f" eq {port}" commands.append(cmd) if acl_name: commands.append("!") return commands