playbooks/playbook.py

94 lines
2.6 KiB
Python
Raw Permalink Normal View History

#!/usr/bin/env python
import yaml
import subprocess
import json
from getpass import getpass
import argparse
def parse_arguments():
parser = argparse.ArgumentParser(
description="Ansible-playbook wrapper for dynamic password input."
)
parser.add_argument("playbook", help="The path to the Ansible playbook.")
parser.add_argument(
"-i",
"--inventory",
default="inventory.yml",
help="The path to the inventory file.",
)
parser.add_argument(
"-k",
"--ask-pass",
action="store_true",
help="Use become password as SSH password",
)
return parser.parse_args()
def load_playbook_targets(playbook_path):
# Load the playbook YAML and extract the hosts
with open(playbook_path, "r") as f:
playbook_data = yaml.safe_load(f)
return playbook_data[0].get("hosts", [])
def fetch_inventory(inventory_path):
inventory_json = subprocess.check_output(
["ansible-inventory", "-i", inventory_path, "--list"]
)
return json.loads(inventory_json)
def main():
args = parse_arguments()
playbook_targets = load_playbook_targets(args.playbook)
inventory = fetch_inventory(args.inventory)
# Determine targeted hosts
targeted_hosts = set()
if isinstance(playbook_targets, str):
if playbook_targets in inventory:
targeted_hosts.update(inventory[playbook_targets]["hosts"])
elif playbook_targets == "all":
targeted_hosts.update(inventory["_meta"]["hostvars"].keys())
elif isinstance(playbook_targets, list):
targeted_hosts.update(playbook_targets)
# Validate targeted hosts against inventory
valid_hosts = set(inventory["_meta"]["hostvars"].keys())
targeted_hosts.intersection_update(valid_hosts)
# Process each targeted host
for host in targeted_hosts:
print(f"Processing host: {host}")
become_pass = getpass(f"Enter become password for {host}: ")
# Use JSON to safely pass the become password as an extra var
raw_vars = {"ansible_become_pass": become_pass}
if args.ask_pass:
raw_vars["ansible_ssh_pass"] = become_pass
extra_vars = json.dumps(raw_vars)
# Execute Ansible playbook for each host
subprocess.run(
[
"ansible-playbook",
"-i",
args.inventory,
"--limit",
host,
args.playbook,
"--extra-vars",
extra_vars,
]
)
if __name__ == "__main__":
main()