Skip to content

Instantly share code, notes, and snippets.

@platu
Created March 24, 2024 15:01
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save platu/8ebef8c169d7f7eab5f678236cefc7fd to your computer and use it in GitHub Desktop.
Save platu/8ebef8c169d7f7eab5f678236cefc7fd to your computer and use it in GitHub Desktop.
IaC Lab 3 Dynamic inventory build python script
#!/usr/bin/env python3
import os
import re
import sys
import yaml
"""
VM launch trace file
. The .txt file is generated by ovs-startup.sh script with color ANSI code
. The .save file is text only
"""
basename = "launch_output"
traceFile = "trace/" + basename + ".txt"
clean_traceFile = "trace/" + basename + ".save"
GROUPNAME = "routers"
VM_PATTERN = "Router name"
ADDRESS_PATTERN = "mgmt G1 IPv6 LL address"
if not os.path.isfile(traceFile):
print("Virtual machines launch trace file does not exist.", file=sys.stderr)
print("Are the virtual machines running ?", file=sys.stderr)
sys.exit(1)
if os.path.isfile(clean_traceFile):
os.remove(clean_traceFile)
print("Generate trace file with no ANSI codes.")
ansi_escape = re.compile(r"\x9B|\x1B[)[0-?]*[ -/]*[@-~]")
with open(traceFile, "r") as src:
with open(clean_traceFile, "w") as dst:
for line in src:
ansi_escape.sub("", line)
dst.write(ansi_escape.sub("", line))
"""
Virtual IOS-XE router inventory generation
Virtual router name and IPv6 link local addresses are extracted from trace file
"""
data = {
GROUPNAME: {
"hosts": {},
"vars": {
"ansible_ssh_user": "{{ vm_user }}",
"ansible_ssh_pass": "{{ vm_pass }}",
"ansible_connection": "network_cli",
"ansible_network_os": "ios",
},
}
}
with open(clean_traceFile, "r") as src:
lines = src.readlines() # List all the lines of trace file
vm_name_found = False # Router name has not been found yet
vm_address_found = False # Router address has not been found yet
for line in lines:
if not vm_name_found:
vm_name = ""
if not vm_address_found:
vm_address = ""
line = line.strip() # Remove leading/trailing white spaces
if re.search(VM_PATTERN, line) and not vm_name_found:
line = line.split(":")[1] # Get all characters after ':'
line = line.strip()
line = line.split(".")[0] # Strip file extension
vm_name = line
vm_name_found = True
elif (
re.search(ADDRESS_PATTERN, line) and vm_name_found and not vm_address_found
):
line = line.split(" :")[1] # Get all characters after ':'
line = line.strip()
line = line.split("%")[0] # Strip interface name from address
vm_address = f'{line + "%enp0s1"}' # Add new interface name
vm_address_found = True
if vm_name_found and vm_address_found: # New inventory entry
vm_data = {vm_name: {"ansible_host": vm_address, "ansible_port": 2222}}
data[GROUPNAME]["hosts"].update(vm_data) # Add new entry to inventory
vm_name_found = False # Get ready to look for another virtual machine
vm_address_found = False
# yaml_output = yaml.dump(data, sort_keys=False)
# print(yaml_output) # New inventory
"""
Write results to inventory file
"""
inventoryFile = "inventory/lab.yml"
with open(inventoryFile, "w") as dst:
yaml.dump(data, dst, sort_keys=False)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment