iac_modules/scripts/inventory.py

74 lines
2.1 KiB
Python
Raw Normal View History

#!/usr/bin/env python3
import json
import subprocess
import os
import yaml
from collections import defaultdict
def get_pulumi_outputs():
output = subprocess.check_output(["pulumi", "stack", "output", "--json"])
return json.loads(output)
def merge_instance_config(config_dir="config"):
merged = {}
for fname in os.listdir(config_dir):
if fname.endswith(".yaml"):
with open(os.path.join(config_dir, fname)) as f:
data = yaml.safe_load(f)
if isinstance(data, dict):
merged.update(data)
return merged.get("instances", [])
def build_inventory(pulumi_outputs, instance_cfgs):
inventory = {"_meta": {"hostvars": {}}}
groups = defaultdict(list)
for inst in instance_cfgs:
name = inst["name"]
public_ip = pulumi_outputs.get(f"{name}_ip")
if not public_ip:
continue # skip not created instances
# 默认分组all
groups["all"].append(name)
# 根据 subnet 或 lifecycle 添加分组
if "subnet" in inst:
groups[inst["subnet"]].append(name)
if "lifecycle" in inst:
groups[inst["lifecycle"]].append(name)
# hostvars
inventory["_meta"]["hostvars"][name] = {
"ansible_host": public_ip,
"ansible_user": "ubuntu",
"instance_type": inst.get("type"),
"ttl": inst.get("ttl", "none"),
"lifecycle": inst.get("lifecycle", "ondemand"),
}
# 将分组注入 inventory
for group, hosts in groups.items():
inventory[group] = {"hosts": hosts}
return inventory
def main():
import argparse
parser = argparse.ArgumentParser()
parser.add_argument('--list', action='store_true')
args = parser.parse_args()
if args.list:
pulumi_data = get_pulumi_outputs()
instance_cfgs = merge_instance_config()
inventory = build_inventory(pulumi_data, instance_cfgs)
print(json.dumps(inventory, indent=2))
else:
print(json.dumps({}))
if __name__ == "__main__":
main()