diff --git a/awx/main/models/inventory.py b/awx/main/models/inventory.py index 7bc3c80b5e..06fbd071e7 100644 --- a/awx/main/models/inventory.py +++ b/awx/main/models/inventory.py @@ -4,6 +4,7 @@ # Python import datetime import time +import json import logging import re import copy @@ -2578,11 +2579,26 @@ class satellite6(PluginFileInjector): def inventory_as_dict(self, inventory_update, private_data_dir): ret = super(satellite6, self).inventory_as_dict(inventory_update, private_data_dir) + group_patterns = '[]' + group_prefix = 'foreman_' + want_hostcollections = False want_ansible_ssh_host = False + want_facts = True + foreman_opts = inventory_update.source_vars_dict.copy() for k, v in foreman_opts.items(): - if k == 'satellite6_want_ansible_ssh_host' and isinstance(v, bool): + if k == 'satellite6_group_patterns' and isinstance(v, str): + group_patterns = v + elif k == 'satellite6_group_prefix' and isinstance(v, str): + group_prefix = v + elif k == 'satellite6_want_hostcollections' and isinstance(v, bool): + want_hostcollections = v + elif k == 'satellite6_want_ansible_ssh_host' and isinstance(v, bool): want_ansible_ssh_host = v + elif k == 'satellite6_want_facts' and isinstance(v, bool): + want_facts = v + else: + ret[k] = str(v) # Compatibility content group_by_hostvar = { @@ -2605,13 +2621,61 @@ class satellite6(PluginFileInjector): "key": "foreman['content_facet_attributes']['content_view_name'] | " "lower | regex_replace(' ', '') | regex_replace('[^A-Za-z0-9\_]', '_')"} } - ret['keyed_groups'] = [group_by_hostvar[grouping_name] for grouping_name in group_by_hostvar] - ret['legacy_hostvars'] = True - ret['want_facts'] = True + + ret['legacy_hostvars'] = True # convert hostvar structure to the form used by the script ret['want_params'] = True + ret['group_prefix'] = group_prefix + ret['want_hostcollections'] = want_hostcollections + ret['want_facts'] = want_facts if want_ansible_ssh_host: ret['compose'] = {'ansible_ssh_host': "foreman['ip6'] | default(foreman['ip'], true)"} + ret['keyed_groups'] = [group_by_hostvar[grouping_name] for grouping_name in group_by_hostvar] + + def form_keyed_group(group_pattern): + """ + Converts foreman group_pattern to + inventory plugin keyed_group + + e.g. {app_param}-{tier_param}-{dc_param} + becomes + "%s-%s-%s" | format(app_param, tier_param, dc_param) + """ + if type(group_pattern) is not str: + return None + params = re.findall('{[^}]*}', group_pattern) + if len(params) == 0: + return None + + param_names = [] + for p in params: + param_names.append(p[1:-1].strip()) # strip braces and space + + # form keyed_group key by + # replacing curly braces with '%s' + # (for use with jinja's format filter) + key = group_pattern + for p in params: + key = key.replace(p, '%s', 1) + + # apply jinja filter to key + key = '"{}" | format({})'.format(key, ', '.join(param_names)) + + keyed_group = {'key': key, + 'separator': ''} + return keyed_group + + try: + group_patterns = json.loads(group_patterns) + + if type(group_patterns) is list: + for group_pattern in group_patterns: + keyed_group = form_keyed_group(group_pattern) + if keyed_group: + ret['keyed_groups'].append(keyed_group) + except json.JSONDecodeError: + logger.warning('Could not parse group_patterns. Expected JSON-formatted string, found: {}' + .format(group_patterns)) return ret diff --git a/awx/main/tests/data/inventory/plugins/satellite6/files/foreman.yml b/awx/main/tests/data/inventory/plugins/satellite6/files/foreman.yml index 6d4faee619..a63520c2f0 100644 --- a/awx/main/tests/data/inventory/plugins/satellite6/files/foreman.yml +++ b/awx/main/tests/data/inventory/plugins/satellite6/files/foreman.yml @@ -1,5 +1,7 @@ +base_source_var: value_of_var compose: ansible_ssh_host: foreman['ip6'] | default(foreman['ip'], true) +group_prefix: foo_group_prefix keyed_groups: - key: foreman['environment_name'] | lower | regex_replace(' ', '') | regex_replace('[^A-Za-z0-9\_]', '_') | regex_replace('none', '') prefix: foreman_environment_ @@ -16,7 +18,12 @@ keyed_groups: - key: foreman['content_facet_attributes']['content_view_name'] | lower | regex_replace(' ', '') | regex_replace('[^A-Za-z0-9\_]', '_') prefix: foreman_content_view_ separator: '' +- key: '"%s-%s-%s" | format(app, tier, color)' + separator: '' +- key: '"%s-%s" | format(app, color)' + separator: '' legacy_hostvars: true plugin: theforeman.foreman.foreman want_facts: true +want_hostcollections: true want_params: true diff --git a/awx/main/tests/data/inventory/scripts/satellite6/files/file_reference b/awx/main/tests/data/inventory/scripts/satellite6/files/file_reference index efb66e492a..0e2a33d0d7 100644 --- a/awx/main/tests/data/inventory/scripts/satellite6/files/file_reference +++ b/awx/main/tests/data/inventory/scripts/satellite6/files/file_reference @@ -6,12 +6,12 @@ user = fooo password = fooo [ansible] -group_patterns = foo_group_patterns +group_patterns = ["{app}-{tier}-{color}", "{app}-{color}"] want_facts = True want_hostcollections = True group_prefix = foo_group_prefix want_ansible_ssh_host = True -rich_params = True +rich_params = False [cache] path = /tmp diff --git a/awx/main/tests/functional/test_inventory_source_injectors.py b/awx/main/tests/functional/test_inventory_source_injectors.py index c3c70d0c4a..29b798cfd7 100644 --- a/awx/main/tests/functional/test_inventory_source_injectors.py +++ b/awx/main/tests/functional/test_inventory_source_injectors.py @@ -64,11 +64,10 @@ INI_TEST_VARS = { 'tags': 'Creator:jmarshall, peanutbutter:jelly' }, 'satellite6': { - 'satellite6_group_patterns': 'foo_group_patterns', + 'satellite6_group_patterns': '["{app}-{tier}-{color}", "{app}-{color}"]', 'satellite6_group_prefix': 'foo_group_prefix', 'satellite6_want_hostcollections': True, 'satellite6_want_ansible_ssh_host': True, - 'satellite6_rich_params': True, 'satellite6_want_facts': True },