Skip to content

Instantly share code, notes, and snippets.

@platu
Last active March 19, 2024 15:38
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/1c5c5c3070da7038140007936f70fd42 to your computer and use it in GitHub Desktop.
Save platu/1c5c5c3070da7038140007936f70fd42 to your computer and use it in GitHub Desktop.
IaC Lab01 build dynamic inventory from VM launch traces
#!/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 = "vms"
VM_PATTERN = "Virtual machine filename"
ADDRESS_PATTERN = "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 machine inventory generation
Virtual machine 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_become": "true",
"ansible_become_password": "{{ vm_pass }}",
},
}
}
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["vms"]["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