#!/usr/bin/env python ''' Example custom dynamic inventory script for Ansible, in Python. ''' from argparse import ArgumentParser from json import dumps, JSONEncoder from os import remove from os.path import isfile from asyncio import run from risotto.machine import load from risotto.image import load_config from risotto.utils import SERVERS from tiramisu.error import PropertiesOptionError from rougail.utils import normalize_family from rougail import RougailSystemdTemplate from rougail.template.base import RougailLeader, RougailExtra TIRAMISU_CACHE = 'tiramisu_cache.py' VALUES_CACHE = 'values_cache.py' class RougailEncoder(JSONEncoder): def default(self, obj): if isinstance(obj, RougailLeader): return obj._follower if isinstance(obj, RougailExtra): return obj._suboption if isinstance(obj, PropertiesOptionError): return 'PropertiesOptionError' return JSONEncoder.default(self, obj) class RisottoInventory(object): def __init__(self): parser = ArgumentParser() parser.add_argument('--list', action='store_true') parser.add_argument('--host', action='store') self.args = parser.parse_args() async def run(self): if self.args.list: if isfile(TIRAMISU_CACHE): remove(TIRAMISU_CACHE) if isfile(VALUES_CACHE): remove(VALUES_CACHE) return await self.do_inventory() elif self.args.host: return await self.get_vars(self.args.host) raise Exception('pfff') async def do_inventory(self): module_infos = load_config(True, True, True, ) servers = [] for server_name, server in SERVERS.items(): module_name = server['module'] if module_name != 'host': continue servers.append(server_name) return dumps({ 'group': { 'hosts': servers, 'vars': { # FIXME 'ansible_ssh_host': '192.168.56.156', 'ansible_ssh_user': 'root', 'ansible_python_interpreter': '/usr/bin/python3' } } }) async def get_vars(self, host_name: str, ) -> dict: try: module_infos, rougailconfig, config = await load(TIRAMISU_CACHE, VALUES_CACHE, ) except Exception as err: # import traceback # traceback.print_exc() print(err) exit(1) ret = {} modules = set() for server_name, server in SERVERS.items(): if server['module'] == 'host' and server_name != host_name: continue modules.add(server['module']) subconfig = config.option(normalize_family(server_name)) engine = RougailSystemdTemplate(subconfig, rougailconfig) await engine.load_variables() if server['module'] != 'host' and engine.rougail_variables_dict['general']['host'] != host_name: continue ret[server_name] = engine.rougail_variables_dict ret['modules'] = {module_name: module_info['infos'].depends for module_name, module_info in module_infos.items() if module_name in modules} ret['configure_host'] = True ret['only_machine'] = None return dumps(ret, cls=RougailEncoder) # Get the inventory. async def main(): inv = RisottoInventory() values = await inv.run() print(values) run(main())