forked from stove/risotto
115 lines
3.7 KiB
Python
115 lines
3.7 KiB
Python
|
#!/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())
|