diff --git a/awx_collection/tools/generate.yml b/awx_collection/tools/generate.yml index 20f86bbf85..a65f64b402 100644 --- a/awx_collection/tools/generate.yml +++ b/awx_collection/tools/generate.yml @@ -8,6 +8,8 @@ vars_files: - vars/generate_for.yml - vars/aliases.yml + - vars/associations.yml + - vars/resolution.yml - vars/examples.yml module_defaults: uri: diff --git a/awx_collection/tools/templates/tower_module.j2 b/awx_collection/tools/templates/tower_module.j2 index 5f728b6229..9f61e1b8fe 100644 --- a/awx_collection/tools/templates/tower_module.j2 +++ b/awx_collection/tools/templates/tower_module.j2 @@ -41,8 +41,13 @@ options: {% endif %} required: {{ item['json']['actions']['POST'][option]['required'] }} type: {{ type_map[ item['json']['actions']['POST'][option]['type'] ] }} -{% if item['json']['actions']['POST'][option].get('default', '') != '' %} - default: {{ item['json']['actions']['POST'][option]['default'] }} +{% if 'default' in item['json']['actions']['POST'][option] %} +{# for tower_job_template/extra vars, its type is dict but its default is '', so we want to make that {} #} +{% if item['json']['actions']['POST'][option]['default'] == '' and type_map[ item['json']['actions']['POST'][option]['type'] ] == 'dict' %} + default: {} +{% else %} + default: '{{ item['json']['actions']['POST'][option]['default'] }}' +{% endif %} {% endif %} {% if 'choices' in item['json']['actions']['POST'][option] %} choices: @@ -63,6 +68,13 @@ options: required: True type: str {% endif %} +{% endfor %} +{% for association in associations[item_type] | default([]) %} + {{ association['related_item'] }}: + description: + - {{ association['description'] }} + required: {{ association['required'] }} + type: list {% endfor %} state: description: @@ -106,7 +118,11 @@ def main(): {{ option_data.append('choices=[{}]'.format(all_choices | join(', '))) -}} {% endif %} {% if item['json']['actions']['POST'][option].get('default', '') != '' %} -{{ option_data.append("default='{}'".format(item['json']['actions']['POST'][option]['default'])) -}} +{% set default_value = item['json']['actions']['POST'][option]['default'] %} +{% if item['json']['actions']['POST'][option]['default'] == '' and type_map[ item['json']['actions']['POST'][option]['type'] ] == 'dict' %} +{% set default_value = '{}' %} +{% endif %} +{{ option_data.append("default='{}'".format(default_value)) -}} {% endif %} {% if aliases[item_type][option] | default(False) %} {% set alias_list = [] %} @@ -119,6 +135,9 @@ def main(): {% if option == name_option %} new_{{ name_option }}=dict(required=False, type='str'), {% endif %} +{% endfor %} +{% for association_option in associations[item_type] | default([]) %} + {{ association_option['related_item'] }}=dict(required={{ association_option['required'] }}, type="list", default=None), {% endfor %} state=dict(choices=['present', 'absent'], default='present'), ) @@ -132,6 +151,9 @@ def main(): {% if option == name_option %} new_{{ name_option }} = module.params.get("new_{{ name_option }}") {% endif %} +{% endfor %} +{% for association_option in associations[item_type] | default([]) %} + {{ association_option['related_item'] }} = module.params.get('{{ association_option['related_item'] }}') {% endfor %} state = module.params.get('state') @@ -141,10 +163,17 @@ def main(): {% if item['json']['actions']['POST'][option]['type'] == 'id' %} {{ option }}_id = None if {{ option }}: - {{ option }}_id = module.resolve_name_to_id('{{ option }}', {{ option }}) + {{ option }}_id = module.resolve_name_to_id('{{ name_to_id_endpoint_resolution[option] }}', {{ option }}) {% endif %} {% endfor %} {% endif %} +{% for association in associations[item_type] | default([]) %} + {{ association['related_item'] }}_ids = None + if {{ association['related_item'] }} is not None: + {{ association['related_item'] }}_ids = [] + for item in {{ association['related_item'] }}: + {{ association['related_item'] }}_ids.append( module.resolve_name_to_id('{{ association['related_item'] }}', item) ) +{% endfor %} # Attempt to look up an existing item based on the provided data existing_item = module.get_one('{{ item_type }}', **{ @@ -165,7 +194,7 @@ def main(): {% if option == name_option %} new_fields['{{ name_option }}'] = new_{{ name_option }} if new_{{ name_option }} else {{ name_option }} {% else %} - if {{ option }}: + if {{ option }} is not None: {% if item['json']['actions']['POST'][option]['type'] == 'id' %} new_fields['{{ option }}'] = {{ option }}_id {% else %} @@ -174,12 +203,20 @@ def main(): {% endif %} {% endfor %} - if state == 'absent': + if state is 'absent': # If the state was absent we can let the module delete it if needed, the module will handle exiting from this module.delete_if_needed(existing_item) - elif state == 'present': + elif state is 'present': # If the state was present and we can let the module build or update the existing item, this will return on its own - module.create_or_update_if_needed(existing_item, new_fields, endpoint='{{ item_type }}', item_type='{{ singular_item_type }}') + module.create_or_update_if_needed( + existing_item, new_fields, + endpoint='{{ item_type }}', item_type='{{ singular_item_type }}', + associations={ +{% for association in associations[item_type] | default([]) %} + '{{ association['endpoint'] }}': {{ association['related_item'] }}_ids, +{% endfor %} + } + ) if __name__ == '__main__': diff --git a/awx_collection/tools/vars/associations.yml b/awx_collection/tools/vars/associations.yml new file mode 100644 index 0000000000..9d95bd666e --- /dev/null +++ b/awx_collection/tools/vars/associations.yml @@ -0,0 +1,13 @@ +--- +associations: + job_templates: + - related_item: credentials + endpoint: credentials + description: "The credentials used by this job template" + groups: + - related_item: hosts + endpoint: hosts + description: "The hosts associated with this group" + - related_item: groups + endpoint: children + description: "The hosts associated with this group" diff --git a/awx_collection/tools/vars/resolution.yml b/awx_collection/tools/vars/resolution.yml new file mode 100644 index 0000000000..fd6ec096cb --- /dev/null +++ b/awx_collection/tools/vars/resolution.yml @@ -0,0 +1,6 @@ +--- +name_to_id_endpoint_resolution: + webhook_credential: credentials + project: projects + inventory: inventories + organization: organizations