Sure. The function deploy_evpn is called from a separate script and use the task create_evpn to deploy a config.
def create_evpn(task, ecx_vpn, ccon_data, basedir):
# function to create and EVPN instance; meant to run on role "evpn_pe" and platform "iosxr"
# Transform data to configuration via a template file
r = task.run(task=text.template_file,
name="Create EVPN config from template file",
template="create-evpn.j2",
path=f"{basedir}/jinja-templates/{task.host.platform}",
ccd=ccon_data,
ecx_vpn = ecx_vpn)
# Save compiled configuration into a host variable
task.host["evpn_config"] = r.result
# Deploy the configuration to the device using NAPALM
task.run(task=networking.napalm_configure,
name="Loading Configuration on the device",
replace=False,
configuration=task.host["evpn_config"])
def deploy_evpn(basedir, ecx_vpn, ccon_data, my_dry_run):
logging.info("deploy_evpn dry_run [{}]".format(my_dry_run))
nr = InitNornir(
core={"num_workers": 20},
inventory={
"plugin": "nornir.plugins.inventory.simple.SimpleInventory",
"options": {
"host_file": "{}/nornir-inventory/hosts.yaml".format(basedir),
"group_file": "{}/nornir-inventory/groups.yaml".format(basedir),
"defaults_file": "{}/nornir-inventory/defaults.yaml".format(basedir)
}
},
logging={"enabled": False},
dry_run=my_dry_run
)
evpn_pe_hosts = nr.filter(F(groups__any=ecx_vpn['locations']) & F(role="evpn_pe") & F(platform="iosxr"))
if ccon_data['action'] == 'create':
logging.info("Playbook to create a new EVPN instance")
task_result = evpn_pe_hosts.run(task=create_evpn, ecx_vpn=ecx_vpn, ccon_data=ccon_data, basedir=basedir)
my_print_result(task_result)
if task_result.failed is True:
logging.error("Something went wrong. Reset Nornir state, wait 30 seconds and try again")
evpn_pe_hosts.data.reset_failed_hosts()
time.sleep(30)
logging.info("Now we can continue...")
task_result2 = evpn_pe_hosts.run(task=create_evpn, ecx_vpn=ecx_vpn, ccon_data=ccon_data, basedir = basedir)
my_print_result(task_result2)
if task_result2.failed is True:
raise RuntimeError("EVPN configuration failed. Failed hosts [{}], processed hosts [{}]".format(", ".join(task_result2.failed_hosts.keys()), ", ".join(task_result2.keys())))
# Inventory
---
router-1:
hostname: 172.16.1.1
port: 22
platform: iosxr
connection_options:
napalm:
extras:
optional_args:
global_delay_factor: 2
groups:
- group_x
data:
site: site-1
role: evpn_pe
type: router
loopback_ip: 172.16.1.1
locations:
location_x:
- some_info
router-2:
hostname: 172.16.1.2
port: 22
platform: iosxr
connection_options:
napalm:
extras:
optional_args:
global_delay_factor: 2
groups:
- group_x
data:
site: site-2
role: evpn_pe
type: router
loopback_ip: 172.16.1.2
locations:
location_x:
- some_info
...
I already implemented a workaround. If the deployment fails the first time it will wait 30 seconds and try again.