- Add config/sit and other environment-specific config directories - Refactor deploy.py to support CONFIG_PATH environment variable - Enable automatic merging of config/*/*.yaml files - Enhance run.sh with Pulumi/Ansible/Terraform initialization checks - Add inventory.py to dynamically generate Ansible hosts - Improve ec2_instance.py with modular instance creation - Organize base.yaml, vpc.yaml and related config files"
74 lines
2.1 KiB
Python
74 lines
2.1 KiB
Python
#!/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()
|