Cleanup: Code and refactoring

This commit is contained in:
Robin Pierre Cordier 2022-02-11 16:38:42 -05:00
parent d4964af1af
commit 911938cc36
4 changed files with 139 additions and 74 deletions

31
plugins/README.md Normal file
View File

@ -0,0 +1,31 @@
# Collections Plugins Directory
This directory can be used to ship various plugins inside an Ansible collection. Each plugin is placed in a folder that
is named after the type of plugin it is in. It can also include the `module_utils` and `modules` directory that
would contain module utils and modules respectively.
Here is an example directory of the majority of plugins currently supported by Ansible:
```
└── plugins
├── action
├── become
├── cache
├── callback
├── cliconf
├── connection
├── filter
├── httpapi
├── inventory
├── lookup
├── module_utils
├── modules
├── netconf
├── shell
├── strategy
├── terminal
├── test
└── vars
```
A full list of plugin types can be found at [Working With Plugins](https://docs.ansible.com/ansible/2.11/plugins/plugins.html).

View File

@ -85,48 +85,58 @@ class InventoryModule(BaseInventoryPlugin, Cacheable, Constructable):
config_data = self._read_config_data(path) config_data = self._read_config_data(path)
#self._consume_options(config_data) #self._consume_options(config_data)
# Get options from inventory
self.strict = self.get_option('strict') self.strict = self.get_option('strict')
self.compose = self.get_option('compose') self.compose = self.get_option('compose')
self.groups = self.get_option('groups') self.groups = self.get_option('groups')
self.keyed_groups = self.get_option('keyed_groups') self.keyed_groups = self.get_option('keyed_groups')
# self.process_scope = self.get_option('process_scope')
# self.process_results = self.get_option('process_results')
# Prepare Kheops instance
self.config_file = self.get_option('config') self.config_file = self.get_option('config')
configs = [ configs = [
self.config_file, self.config_file,
path, path,
] ]
kheops = AnsibleKheops(configs=configs, display=self.display) kheops = AnsibleKheops(configs=configs, display=self.display)
# Loop over each keys # Loop over each hosts
for host_name in inventory.hosts: for host_name in inventory.hosts:
host = self.inventory.get_host(host_name) host = self.inventory.get_host(host_name)
scope = kheops.get_scope_from_host_inventory(host.get_vars(), scope=None) ret = kheops.super_lookup(
# Fetch the results
ret = kheops.lookup(
keys=None, keys=None,
scope=scope, scope=None,
_templar=self.templar,
_variables=host.get_vars(),
#trace=True, #trace=True,
#explain=True, #explain=True,
) )
# # Create the scope
# if self.process_scope == 'vars':
# scope = kheops.get_scope_from_host_inventory(host.get_vars(), scope=None)
# elif self.process_scope == 'jinja':
# scope = kheops.get_scope_from_jinja(host.get_vars(), self.templar, scope=None)
# # Fetch the results
# ret = kheops.lookup(
# keys=None,
# scope=scope,
# #trace=True,
# #explain=True,
# )
# Inject variables into host # Inject variables into host
for key, value in ret.items(): for key, value in ret.items():
self.display.vv (f"Set {host_name} var: {key}={value}")
self.display.vv (f"Define variable for {host_name}: {key}={value}")
host.set_variable(key, value) host.set_variable(key, value)
# Call constructed inventory plugin methods # Call constructed inventory plugin methods
#hostvars = self.inventory.get_host(host_name).get_vars()
hostvars = host.get_vars() hostvars = host.get_vars()
#tutu = hostvars.get('tiger_profiles', "MISSSSINGGGG")
#print ("YOOOOO", tutu, self.keyed_groups, host_name, self.strict)
self._set_composite_vars(self.compose, hostvars, host_name, self.strict) self._set_composite_vars(self.compose, hostvars, host_name, self.strict)
self._add_host_to_composed_groups(self.groups, hostvars, host_name, self.strict) self._add_host_to_composed_groups(self.groups, hostvars, host_name, self.strict)
self._add_host_to_keyed_groups(self.keyed_groups, hostvars, host_name, self.strict) self._add_host_to_keyed_groups(self.keyed_groups, hostvars, host_name, self.strict)

View File

@ -109,30 +109,29 @@ from pprint import pprint
class LookupModule(LookupBase): class LookupModule(LookupBase):
def run(self, terms, variables=None, scope=None, **kwargs): def run(self, terms, variables=None, scope=None, **kwargs):
self.set_options(direct=kwargs) self.set_options(direct=kwargs)
#self.config_file = self.get_option('config')
self.process_scope = self.get_option('process_scope')
self.process_results = self.get_option('process_results')
# Prepare Kheops instance
self.config_file = self.get_option('config') self.config_file = self.get_option('config')
configs = [ configs = [
self.config_file, self.config_file,
kwargs,
#{ #{
# "instance_log_level": 'DEBUG', # "instance_log_level": 'DEBUG',
# } # }
] ]
kheops = AnsibleKheops(configs=configs, display=self._display) kheops = AnsibleKheops(configs=configs, display=self._display)
# Create scope
if self.process_scope == 'vars':
scope = kheops.get_scope_from_host_inventory(variables, scope=None) scope = kheops.get_scope_from_host_inventory(variables, scope=None)
elif self.process_scope == 'jinja':
scope = kheops.get_scope_from_jinja(variables, self._templar, scope=None) scope = kheops.get_scope_from_jinja(variables, self._templar, scope=None)
#assert False , f"OUTOUT: {scope2}" # Transform dict to list for lookup/queries
#for key, value in self.get_option('scope').items():
# scope[key] = variables[value]
ret = [] ret = []
for term in terms: for term in terms:
result = kheops.lookup( result = kheops.lookup(
@ -145,17 +144,6 @@ class LookupModule(LookupBase):
# if isinstance(terms, str):
# terms = terms.split(',')
# import ansible_collections.barbu_it.ansible_kheops.plugins.plugin_utils.common as kheops_utils
# AnsibleKheops = kheops_utils.AnsibleKheops
# kheops = AnsibleKheops()
# return None
# assert isinstance(terms, list), f"Expected a list, got: {terms}" # assert isinstance(terms, list), f"Expected a list, got: {terms}"
# # Parse arguments # # Parse arguments

View File

@ -124,6 +124,26 @@ DOCUMENTATION_OPTION_FRAGMENT = '''
default: Null default: Null
# Behavior configuration
# ==========================
process_scope:
description:
- This setting defines how is parsed the `scope` configuration
- Set `vars` to enable simple variable interpolation
- Set `jinja` to enable jinja string interpolation
default: 'jinja'
choices: ['vars', 'jinja']
process_results:
description:
- This setting defines how is parsed the returned results.
- Set `none` to disable jinja interpolation from result.
- Set `jinja` to enable jinja result interpolation.
- Using jinja may pose some security issues, as you need to be sure that your source of data is properly secured.
default: 'none'
choices: ['none', 'jinja']
# Uneeded # Misc # Uneeded # Misc
# Uneeded version: # Uneeded version:
# Uneeded description: # Uneeded description:
@ -163,6 +183,7 @@ from kheops.app import Kheops
from ansible.errors import AnsibleError from ansible.errors import AnsibleError
from ansible.module_utils.common.text.converters import to_native from ansible.module_utils.common.text.converters import to_native
from ansible.template import generate_ansible_template_vars, AnsibleEnvironment, USE_JINJA2_NATIVE from ansible.template import generate_ansible_template_vars, AnsibleEnvironment, USE_JINJA2_NATIVE
from ansible.utils.display import Display
from pprint import pprint from pprint import pprint
@ -190,14 +211,13 @@ class AnsibleKheops():
def __init__(self, configs=None, display=None): def __init__(self, configs=None, display=None):
self.configs = configs or [] self.configs = configs or []
self.display = display or print self.display = display or Display()
config = self.get_config() config = self.get_config()
# print ("CURRENT CONFIG vv") # print ("CURRENT CONFIG vv")
# pprint (config) # pprint (config)
# print ("CURRENT CONFIG ^^") # print ("CURRENT CONFIG ^^")
self.init_templar()
# Instanciate Kheops # Instanciate Kheops
if config["mode"] == 'instance': if config["mode"] == 'instance':
@ -224,7 +244,7 @@ class AnsibleKheops():
raise AnsibleError("Kheops client mode is not implemented") raise AnsibleError("Kheops client mode is not implemented")
self.config = config self.config = config
print ("Kheops instance is OK") self.display.v(f"Kheops instance has been created")
def get_config(self): def get_config(self):
@ -278,7 +298,7 @@ class AnsibleKheops():
combined_config.update(env_config) combined_config.update(env_config)
combined_config.update(merged_configs) combined_config.update(merged_configs)
# Debug report
# out = { # out = {
# "0_default": default_config, # "0_default": default_config,
# "1_env": env_config, # "1_env": env_config,
@ -290,7 +310,6 @@ class AnsibleKheops():
# pprint (combined_config) # pprint (combined_config)
# print ('=' * 20) # print ('=' * 20)
return combined_config return combined_config
@ -359,12 +378,9 @@ class AnsibleKheops():
return ret return ret
def init_templar(self, enable_jinja=True, jinja2_native=False):
pass
def get_scope_from_jinja(self, host_vars, templar, scope=None, jinja2_native=False): def get_scope_from_jinja(self, host_vars, templar, scope=None, jinja2_native=False):
scope = scope or self.config['scope'] scope = scope or self.config['scope']
ret = {}
if USE_JINJA2_NATIVE and not jinja2_native: if USE_JINJA2_NATIVE and not jinja2_native:
_templar = templar.copy_with_new_env(environment_class=AnsibleEnvironment) _templar = templar.copy_with_new_env(environment_class=AnsibleEnvironment)
@ -372,15 +388,25 @@ class AnsibleKheops():
_templar = templar _templar = templar
_vars = deepcopy(host_vars) _vars = deepcopy(host_vars)
ret = {}
with _templar.set_temporary_context(available_variables=_vars): with _templar.set_temporary_context(available_variables=_vars):
res = _templar.template(scope, preserve_trailing_newlines=True,
convert_data=False, escape_backslashes=False) for key, value in scope.items():
res = value
try:
res = _templar.template(value, preserve_trailing_newlines=True,
convert_data=True, escape_backslashes=False)
if USE_JINJA2_NATIVE and not jinja2_native: if USE_JINJA2_NATIVE and not jinja2_native:
# jinja2_native is true globally but off for the lookup, we need this text # jinja2_native is true globally but off for the lookup, we need this text
# not to be processed by literal_eval anywhere in Ansible # not to be processed by literal_eval anywhere in Ansible
res = NativeJinjaText(res) res = NativeJinjaText(res)
self.display.vvv(f"Transformed: {value} =====> {res}")
except Exception as err:
self.display.v(f"Got templating error for value: {value} => {err}")
return res ret[key] = res
return ret
@ -392,33 +418,43 @@ class AnsibleKheops():
keys_config = self.parse_keys(keys, namespace) keys_config = self.parse_keys(keys, namespace)
keys = [ i.show() for i in keys_config ] keys = [ i.show() for i in keys_config ]
# self.base.display.v(f"Kheops keys: {keys}") self.display.v(f"Kheops keys: {keys}")
# self.base.display.vv(f"Kheops scope: {scope}") self.display.vv(f"Kheops scope: {scope}")
print ("LOOKUP QUERY: ", keys, scope)
#try:
ret = self.kheops.lookup( ret = self.kheops.lookup(
keys=keys, keys=keys,
scope=scope, scope=scope,
#trace=True, #trace=True,
#explain=True, #explain=True,
) )
#except Exception as err:
# assert False, f"{err.__traceback__}"
# assert False, f"{dir(err)}"
# raise AnsibleError('Something happened, this was original exception: %s' % to_native(err))
# assert False, f"MY ERRRROR {err}"
# self.display.v(err)
print ("RESULT: ", ret)
# Remap output # Remap output
#for key in keys_config: for key in keys_config:
# if key.remap != key.key: if key.remap != key.key:
# ret[key.remap] = ret[key.key] ret[key.remap] = ret[key.key]
# del ret[key.key] del ret[key.key]
return ret or {} return ret or {}
def super_lookup(self, keys, namespace=None, scope=None, kwargs=None,
_templar=None,
_variables=None,
_process_scope=None,
_process_results=None,
):
_process_scope = _process_scope or self.config['process_scope']
_process_results = _process_results or self.config['process_results']
if _process_scope == 'vars':
scope = self.get_scope_from_host_inventory(_variables, scope=scope)
elif _process_scope == 'jinja':
assert _templar, f"BUG: We expected a templar object here, got: {_templar}"
scope = self.get_scope_from_jinja(_variables, _templar, scope=scope)
ret = self.lookup(keys, namespace=namespace, scope=scope)
return ret