Created
March 24, 2024 15:01
-
-
Save platu/8ebef8c169d7f7eab5f678236cefc7fd to your computer and use it in GitHub Desktop.
IaC Lab 3 Dynamic inventory build python script
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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