risotto/ansible/inventory.py
2022-10-01 22:33:11 +02:00

114 lines
3.7 KiB
Python
Executable file

#!/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())