Cisco IOS-XE - ZTP

Example #1
#
# ZTP Day0 Python Script for Cisco IOS-XE
#
 
# Importing the correct cli module for IOS-XE
import cli
 
print("\n*** Sample ZTP Day0 Python Script for IOS-XE ***\n")
 
# Use the correct syntax for cli.configurep, passing a list of strings
try:
    print("Configuring hostname, interfaces, and user accounts...")
    cli.configurep(["hostname myrouter1"])
    cli.configurep(["interface vlan 1", "ip address 10.5.123.27 255.255.255.0", "no shutdown"])
    cli.configurep(["username admin privilege 15 secret 0 MyPassword!"])
    cli.configurep(["enable secret 0 MyPassword!"])
    cli.configurep(["aaa new-model", "aaa authentication login default local", "end"])
    cli.configurep(["aaa authorization exec default local", "aaa session-id common", "end"])
    cli.configurep(["netconf-yang", "end"])
 
    print("Setting license boot level...")
    # The license boot command is a configuration command
    cli.configurep(["license boot level network-advantage addon dna-advantage"])
    print("License boot level configured. Writing memory to save.")
 
    print("Writing memory...")
    # 'write mem' is a privileged EXEC command
    cli.executep("write mem")
 
    print("Configuration applied and save successfully.\n")
 
    print("\n\n*** Executing show ip interface brief ***\n\n")
    # cli.executep returns the output as a string, which can be printed
    output = cli.executep("sh ip int brief")
    print(output)
 
 
    print("\n\n*** ZTP Day0 Python Script Execution Complete. Rebooting in 10 seconds. ***\n\n")
    time.sleep(10) # Wait 10 seconds before rebooting
 
    # 'reload' is a privileged EXEC command and will exit the script
    cli.executep("reload")
 
except Exception as e:
    print(f"Error during ZTP script execution: {e}")
 
print("\n\n*** ZTP Day0 Python Script Execution Complete ***\n\n")
Example #2
#
# ZTP Day0 Python Script for Cisco IOS-XE
#
 
#!/usr/bin/env python
# ZTP Day0 for IOS XE C8000v — applies provided running-config, saves, verifies, reloads
import cli
import time
 
def push_config_lines(lines, chunk=90, pause=0.2):
    """Send config in batches to avoid parser/VTY limits."""
    for i in range(0, len(lines), chunk):
        cli.configure(lines[i:i+chunk])
        time.sleep(pause)
 
print("\n*** Applying Day0 Configuration ***\n")
 
CFG = [
    # ----- Global / platform -----
 
    # ----- VRFs -----
 
    # ----- AAA per your config -----
    "no aaa new-model",
 
    # ----- DNS / domain -----
    "ip name-server vrf mgmt 1.1.1.1 8.8.8.8",
    "ip domain name example.com",
 
    # ----- Logging/telemetry basics -----
 
    # ----- Trustpoints (cert bodies omitted by design; ask to include) -----
 
    # ----- Licensing / UDI -----
 
    # ----- Local creds -----
    "enable secret 0 MyPassword!",
    "username admin privilege 15 secret 0 MyPassword!
 
    # ----- Interfaces -----
    "interface Loopback0",
    " no ip address",
    " shutdown",
    "exit",
    "interface Loopback1234",
	" no ip address",
    " shutdown",
    "exit",
 
    "interface GigabitEthernet1",
    " vrf forwarding vrf1",
    "exit",
 
    "interface GigabitEthernet2",
    " no ip address",
    " negotiation auto",
    "exit",
 
    "interface GigabitEthernet3",
    " vrf forwarding mgmt",
    " ip address 192.168.1.164 255.255.255.0",
    " negotiation auto",
    "exit",
 
    # ----- HTTP/SSH/Routes -----
 
    # ----- Prefix-lists / route-maps -----
 
 
    # ----- Control-plane placeholder -----
 
    # ----- MGCP defaults -----
 
 
    # ----- Aliases -----
 
    # ----- Lines / access -----
    "line con 0",
    " activation-character 13",
    " stopbits 1",
    "exit",
    "line aux 0",
    " activation-character 13",
    "exit",
    "line vty 0 4",
    " activation-character 13",
    " login local",
    " transport input ssh",
    "exit",
    "line vty 5 97",
    " activation-character 13",
    " login",
    " transport input ssh",
    "exit",
 
    # ----- NTP -----
    "ntp peer vrf mgmt 192.168.1.155",
 
    # ----- NETCONF + Guestshell + Telemetry -----
    "netconf-yang",
    "app-hosting appid guestshell",
    " app-vnic management guest-interface 0",
    "exit",
    "telemetry ietf subscription 1",
    " encoding encode-kvgpb",
    " filter xpath /memory-ios-xe-oper:memory-statistics/memory-statistic",
    " stream yang-push",
    " update-policy periodic 6000",
    " receiver ip address 192.168.2.111 10004 protocol grpc-tcp",
    "exit",
]
 
try:
    push_config_lines(CFG)
 
    print("Setting license boot level...")
    # The license boot command is a configuration command
    cli.configurep(["license boot level network-advantage addon dna-advantage"])
    print("License boot level configured. Writing memory to save.") 
 
    print("\nWriting memory...")
    cli.execute("write memory")
 
    print("Configuration applied and save successfully.\n") 
 
    # quick checks
    print("\n*** Quick checks ***\n")
    for cmd in [
        "show vrf",
        "show ip interface brief",
    ]:
        print(f"\n> {cmd}")
        try:
            print(cli.execute(cmd))
        except Exception as e:
            print(f"[exec error] {cmd}: {e}")
 
    print("\n*** Rebooting in 10 seconds... ***\n")
    time.sleep(10)
    cli.execute("reload")
 
except Exception as e:
    print(f"Error during ZTP script execution: {e}")
 
print("\n*** ZTP Day0 Python Script Execution Complete ***\n")
Get full config based on router serial
import re
import time
import cli
 
def get_serial():
    """Extract the router serial number"""
    output = cli.execute("show version | include Processor board ID")
 
    match = re.search(r'(\w+)$', output)
 
    if match:
        board_id = match.group(1)
        return board_id
    else:
        return "UNKNOWN"
 
print(f"Getting serial number...")
serial = get_serial()
print(f"Device serial number: {serial}")
 
print(f"Applying license...")
cli.configurep(["license boot level network-advantage addon dna-advantage"])
 
print(f"Retrieving full configuration...")
cli.executep("copy http://192.168.30.5/{serial}.txt running-config")
 
print(f"Saving configuration...")
cli.executep("write mem")
 
print(f"Reloading...")
time.sleep(10)
cli.executep("reload")