forked from stove/risotto
templating is now done by ansible
This commit is contained in:
parent
bfa697f457
commit
44eb0031de
1 changed files with 103 additions and 17 deletions
|
@ -1,10 +1,16 @@
|
|||
#!/usr/bin/python3
|
||||
from asyncio import run
|
||||
from os import readlink, walk, chdir, getcwd, makedirs
|
||||
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 shutil import rmtree
|
||||
from typing import Dict, Any
|
||||
from shutil import rmtree, copy2
|
||||
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:
|
||||
|
@ -13,6 +19,7 @@ try:
|
|||
class FakeModule(AnsibleModule):
|
||||
def __init__(self):
|
||||
pass
|
||||
from ansible.plugins.action.template import ActionModule as TmplActionModule
|
||||
except:
|
||||
class ActionBase():
|
||||
def __init__(self, *args, **kwargs):
|
||||
|
@ -64,15 +71,24 @@ class ActionModule(ActionBase):
|
|||
only_machine = module_args.pop('only_machine')
|
||||
configure_host = module_args.pop('configure_host')
|
||||
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:
|
||||
copy_templates = module_args.pop('copy_templates')
|
||||
else:
|
||||
copy_templates = False
|
||||
directories, certificates = run(build_files(hostname,
|
||||
only_machine,
|
||||
False,
|
||||
copy_tests,
|
||||
))
|
||||
directories, certificates = build_files(hostname,
|
||||
only_machine,
|
||||
False,
|
||||
copy_tests,
|
||||
)
|
||||
module_args['directories'] = list(directories.values())
|
||||
module_args['directories'].append('/var/lib/risotto/images_files')
|
||||
remote = self._execute_module(module_name='compare',
|
||||
|
@ -86,17 +102,14 @@ class ActionModule(ActionBase):
|
|||
msg = remote['msg']
|
||||
raise Exception(f'error in remote action: {msg}')
|
||||
if copy_templates:
|
||||
run(build_files(hostname,
|
||||
only_machine,
|
||||
True,
|
||||
copy_tests,
|
||||
))
|
||||
build_files(hostname,
|
||||
only_machine,
|
||||
True,
|
||||
copy_tests,
|
||||
)
|
||||
|
||||
machines_changed = []
|
||||
tls_machine = None
|
||||
for machine, directory in directories.items():
|
||||
if machine.startswith('tls.'):
|
||||
tls_machine = machine
|
||||
if directory not in remote['directories']:
|
||||
machines_changed.append(machine)
|
||||
continue
|
||||
|
@ -150,6 +163,12 @@ class ActionModule(ActionBase):
|
|||
tar_filename = f'{ARCHIVES_DIR}/{INSTALL_IMAGES_DIR}.tar'
|
||||
with tarfile.open(tar_filename, 'w') as archive:
|
||||
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)
|
||||
# tests
|
||||
self._execute_module(module_name='file',
|
||||
|
@ -190,5 +209,72 @@ class ActionModule(ActionBase):
|
|||
changed=changed,
|
||||
machines_changed=machines,
|
||||
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"]}')
|
||||
|
|
Loading…
Reference in a new issue