import requests from requests.auth import HTTPBasicAuth import urllib3 DEVICES = [ {"name": "R1", "ip": "10.0.0.103"}, {"name": "R2", "ip": "10.0.0.104"}, {"name": "R3", "ip": "10.0.0.105"}, ] USERNAME = "cisco" PASSWORD = "cisco" HEADERS = { "Accept": "application/yang-data+json", "Content-Type": "application/yang-data+json", } urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning) def get_hostname(ip): url = f"https://{ip}/restconf/data/Cisco-IOS-XE-native:native/hostname" try: resp = requests.get( url, headers=HEADERS, auth=HTTPBasicAuth(USERNAME, PASSWORD), timeout=10, verify=False ) if resp.status_code == 200: data = resp.json() return data.get("Cisco-IOS-XE-native:hostname", "unknown") elif resp.status_code == 401: raise "Authentication failed" else: raise f"HTTP error {resp.status_code}" except requests.exceptions.RequestException as e: raise f"Error reading hostname: {e}" def main(): print("Reading device hostnames via RESTCONF...") for d in DEVICES: hostname = get_hostname(d["ip"]) print(f"{d['name']} ({d['ip']}): {hostname}") if __name__ == "__main__": main() DEVICES = [ {"name": "R1", "ip": "10.0.0.103", "subif_ip": "10.1.1.1"}, {"name": "R2", "ip": "10.0.0.104", "subif_ip": "10.2.2.2"}, {"name": "R3", "ip": "10.0.0.105", "subif_ip": "10.3.3.3"} ] VLAN_ID = 50 IF_ID = 2 def configure_interface(ip, subif_ip): url = f"https://{ip}/restconf/data/Cisco-IOS-XE-native:native/interface/GigabitEthernet" subif_name = f"{IF_ID}.{VLAN_ID}" payload = { "Cisco-IOS-XE-native:GigabitEthernet": [ { "name": subif_name, "encapsulation": {"dot1Q": {"vlan-id": VLAN_ID}}, "ip": { "address": { "primary": {"address": subif_ip, "mask": "255.255.255.0"} } } } ] } try: resp = requests.patch( url, headers=HEADERS, auth=HTTPBasicAuth(USERNAME, PASSWORD), json=payload, timeout=10, verify=False ) resp.raise_for_status() except requests.exceptions.RequestException as e: raise RuntimeError(f"{ip}: failed to configure subinterface - {e}") def enable_interface(ip, if_name): url = f"https://{ip}/restconf/data/Cisco-IOS-XE-native:native/interface/GigabitEthernet={if_name}/shutdown" try: resp = requests.delete( url, headers=HEADERS, auth=HTTPBasicAuth(USERNAME, PASSWORD), timeout=10, verify=False ) if resp.status_code not in (200, 204, 404): resp.raise_for_status() except requests.exceptions.RequestException as e: raise RuntimeError(f"{ip}: failed to enable interface {if_name} - {e}") def main(): print("\nConfiguring VLAN 50 subinterfaces with IP addresses via RESTCONF") for d in DEVICES: try: subif_name = f"{IF_ID}.{VLAN_ID}" configure_interface(d['ip'], d['subif_ip']) enable_interface(d['ip'], IF_ID) enable_interface(d['ip'], subif_name) print(f"{d['name']}: configured") except Exception as e: print(f"{d['name']}: configuration failed - {e}")