templating is now done by ansible

This commit is contained in:
egarette@silique.fr 2023-06-22 15:49:09 +02:00
parent bfa697f457
commit 44eb0031de

View file

@ -1,10 +1,16 @@
#!/usr/bin/python3 #!/usr/bin/python3
from asyncio import run
from os import readlink, walk, chdir, getcwd, makedirs from os import readlink, walk, chdir, getcwd, makedirs
from os.path import join, islink, isdir from os.path import join, islink, isdir
from risotto.machine import build_files, INSTALL_DIR, INSTALL_CONFIG_DIR, INSTALL_TMPL_DIR, INSTALL_IMAGES_DIR, INSTALL_TESTS_DIR from typing import Dict, Any
from shutil import rmtree from shutil import rmtree, copy2
import tarfile import tarfile
from ansible.module_utils._text import to_text
from ansible import constants
from rougail.template import base
from rougail.error import TemplateError
from risotto.machine import build_files, INSTALL_DIR, INSTALL_CONFIG_DIR, INSTALL_TMPL_DIR, INSTALL_IMAGES_DIR, INSTALL_TESTS_DIR
from risotto.utils import custom_filters
try: try:
@ -13,6 +19,7 @@ try:
class FakeModule(AnsibleModule): class FakeModule(AnsibleModule):
def __init__(self): def __init__(self):
pass pass
from ansible.plugins.action.template import ActionModule as TmplActionModule
except: except:
class ActionBase(): class ActionBase():
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
@ -64,15 +71,24 @@ class ActionModule(ActionBase):
only_machine = module_args.pop('only_machine') only_machine = module_args.pop('only_machine')
configure_host = module_args.pop('configure_host') configure_host = module_args.pop('configure_host')
copy_tests = module_args.pop('copy_tests') copy_tests = module_args.pop('copy_tests')
# define ansible engine
base.ENGINES['ansible'] = Tmpl(task_vars,
self._task,
self._connection,
self._play_context,
self._loader,
self._templar,
self._shared_loader_obj,
)
if 'copy_templates' in module_args: if 'copy_templates' in module_args:
copy_templates = module_args.pop('copy_templates') copy_templates = module_args.pop('copy_templates')
else: else:
copy_templates = False copy_templates = False
directories, certificates = run(build_files(hostname, directories, certificates = build_files(hostname,
only_machine, only_machine,
False, False,
copy_tests, copy_tests,
)) )
module_args['directories'] = list(directories.values()) module_args['directories'] = list(directories.values())
module_args['directories'].append('/var/lib/risotto/images_files') module_args['directories'].append('/var/lib/risotto/images_files')
remote = self._execute_module(module_name='compare', remote = self._execute_module(module_name='compare',
@ -86,17 +102,14 @@ class ActionModule(ActionBase):
msg = remote['msg'] msg = remote['msg']
raise Exception(f'error in remote action: {msg}') raise Exception(f'error in remote action: {msg}')
if copy_templates: if copy_templates:
run(build_files(hostname, build_files(hostname,
only_machine, only_machine,
True, True,
copy_tests, copy_tests,
)) )
machines_changed = [] machines_changed = []
tls_machine = None
for machine, directory in directories.items(): for machine, directory in directories.items():
if machine.startswith('tls.'):
tls_machine = machine
if directory not in remote['directories']: if directory not in remote['directories']:
machines_changed.append(machine) machines_changed.append(machine)
continue continue
@ -150,6 +163,12 @@ class ActionModule(ActionBase):
tar_filename = f'{ARCHIVES_DIR}/{INSTALL_IMAGES_DIR}.tar' tar_filename = f'{ARCHIVES_DIR}/{INSTALL_IMAGES_DIR}.tar'
with tarfile.open(tar_filename, 'w') as archive: with tarfile.open(tar_filename, 'w') as archive:
archive.add('.') archive.add('.')
self._execute_module(module_name='file',
module_args={'path': '/tmp/new_configurations',
'state': 'directory',
},
task_vars=task_vars,
)
self._transfer_file(tar_filename, tar_filename) self._transfer_file(tar_filename, tar_filename)
# tests # tests
self._execute_module(module_name='file', self._execute_module(module_name='file',
@ -190,5 +209,72 @@ class ActionModule(ActionBase):
changed=changed, changed=changed,
machines_changed=machines, machines_changed=machines,
host_changed=self._task.args['hostname'] in machines_changed, host_changed=self._task.args['hostname'] in machines_changed,
tls_machine=tls_machine,
) )
class FakeCopy:
def __init__(self, task):
self.task = task
def run(self, *args, **kwargs):
copy2(self.task.args['src'], self.task.args['dest'])
return {}
class FakeGet:
def __init__(self, klass):
self.klass = klass
def fake_get(self, action, *args, task, **kwargs):
if action == 'ansible.legacy.copy':
return FakeCopy(task)
return self.klass.ori_get(action, *args, task=task, **kwargs)
class Tmpl(TmplActionModule):
def __init__(self, task_vars, *args):
super().__init__(*args)
self.task_vars = task_vars
def _early_needs_tmp_path(self):
# do not create tmp remotely
return False
def process(self,
filename: str,
source: str,
true_destfilename: str,
destfilename: str,
destdir: str,
variable: Any,
index: int,
rougail_variables_dict: Dict,
eosfunc: Dict,
extra_variables: Any=None,
):
if source is not None: # pragma: no cover
raise TemplateError(_('source is not supported for ansible'))
task_vars = rougail_variables_dict | self.task_vars
if variable is not None:
task_vars['rougail_variable'] = variable
if index is not None:
task_vars['rougail_index'] = index
if extra_variables:
task_vars['extra_variables'] = extra_variables
task_vars['rougail_filename'] = true_destfilename
task_vars['rougail_destination_dir'] = destdir
self._task.args['src'] = filename
self._task.args['dest'] = destfilename
# add custom filter
custom_filters.update(eosfunc)
# do not copy file in host but stay it locally
self._shared_loader_obj.action_loader.ori_get = self._shared_loader_obj.action_loader.get
self._shared_loader_obj.action_loader.get = FakeGet(self._shared_loader_obj.action_loader).fake_get
# template
ret = self.run(task_vars=task_vars)
# restore get function
self._shared_loader_obj.action_loader.get = self._shared_loader_obj.action_loader.ori_get
# remove custom filter
custom_filters.clear()
if ret.get('failed'):
raise TemplateError(f'error while templating "{filename}": {ret["msg"]}')