diff --git a/awx_collection/plugins/modules/export.py b/awx_collection/plugins/modules/export.py index 09c75cd923..8e737b14b9 100644 --- a/awx_collection/plugins/modules/export.py +++ b/awx_collection/plugins/modules/export.py @@ -28,52 +28,64 @@ options: default: 'False' organizations: description: - - organization name to export - type: str + - organization names to export + type: list + elements: str users: description: - - user name to export - type: str + - user names to export + type: list + elements: str teams: description: - - team name to export - type: str + - team names to export + type: list + elements: str credential_types: description: - - credential type name to export - type: str + - credential type names to export + type: list + elements: str credentials: description: - - credential name to export - type: str + - credential names to export + type: list + elements: str execution_environments: description: - - execution environment name to export - type: str + - execution environment names to export + type: list + elements: str notification_templates: description: - - notification template name to export - type: str + - notification template names to export + type: list + elements: str inventory_sources: description: - - inventory soruce to export - type: str + - inventory soruces to export + type: list + elements: str inventory: description: - - inventory name to export - type: str + - inventory names to export + type: list + elements: str projects: description: - - project name to export - type: str + - project names to export + type: list + elements: str job_templates: description: - - job template name to export - type: str + - job template names to export + type: list + elements: str workflow_job_templates: description: - - workflow name to export - type: str + - workflow names to export + type: list + elements: str requirements: - "awxkit >= 9.3.0" notes: @@ -94,6 +106,10 @@ EXAMPLES = ''' export: job_templates: "My Template" credential: 'all' + +- name: Export a list of inventories + export: + inventory: ['My Inventory 1', 'My Inventory 2'] ''' import logging @@ -111,24 +127,12 @@ except ImportError: def main(): argument_spec = dict( all=dict(type='bool', default=False), - credential_types=dict(type='str'), - credentials=dict(type='str'), - execution_environments=dict(type='str'), - inventory=dict(type='str'), - inventory_sources=dict(type='str'), - job_templates=dict(type='str'), - notification_templates=dict(type='str'), - organizations=dict(type='str'), - projects=dict(type='str'), - teams=dict(type='str'), - users=dict(type='str'), - workflow_job_templates=dict(type='str'), ) # We are not going to raise an error here because the __init__ method of ControllerAWXKitModule will do that for us if HAS_EXPORTABLE_RESOURCES: for resource in EXPORTABLE_RESOURCES: - argument_spec[resource] = dict(type='str') + argument_spec[resource] = dict(type='list', elements='str') module = ControllerAWXKitModule(argument_spec=argument_spec) diff --git a/awx_collection/tests/integration/targets/export/tasks/main.yml b/awx_collection/tests/integration/targets/export/tasks/main.yml index d051b3ee68..baa78ce64a 100644 --- a/awx_collection/tests/integration/targets/export/tasks/main.yml +++ b/awx_collection/tests/integration/targets/export/tasks/main.yml @@ -61,6 +61,40 @@ - mixed_export['assets']['organizations'] | length() == 1 - "'workflow_job_templates' not in mixed_export['assets']" + - name: Export list of organizations + export: + organizations: "{{[org_name1, org_name2]}}" + register: list_asserts + + - assert: + that: + - list_asserts is not changed + - list_asserts is successful + - list_asserts['assets']['organizations'] | length() >= 2 + + - name: Export list with one organization + export: + organizations: "{{[org_name1]}}" + register: list_asserts + + - assert: + that: + - list_asserts is not changed + - list_asserts is successful + - list_asserts['assets']['organizations'] | length() >= 1 + - "org_name1 in (list_asserts['assets']['organizations'] | map(attribute='name') )" + + - name: Export one organization as string + export: + organizations: "{{org_name2}}" + register: string_asserts + + - assert: + that: + - string_asserts is not changed + - string_asserts is successful + - string_asserts['assets']['organizations'] | length() >= 1 + - "org_name2 in (string_asserts['assets']['organizations'] | map(attribute='name') )" always: - name: Remove our inventory inventory: diff --git a/awxkit/awxkit/api/pages/api.py b/awxkit/awxkit/api/pages/api.py index 2fcc62648a..21ea8afbb7 100644 --- a/awxkit/awxkit/api/pages/api.py +++ b/awxkit/awxkit/api/pages/api.py @@ -213,11 +213,23 @@ class ApiV2(base.Base): assets = (self._export(asset, post_fields) for asset in endpoint.results) return [asset for asset in assets if asset is not None] + def _check_for_int(self, value): + return isinstance(value, int) or (isinstance(value, str) and value.isdecimal()) + def _filtered_list(self, endpoint, value): - if isinstance(value, int) or value.isdecimal(): + if isinstance(value, list) and len(value) == 1: + value = value[0] + if self._check_for_int(value): return endpoint.get(id=int(value)) + options = self._cache.get_options(endpoint) identifier = next(field for field in options['search_fields'] if field in ('name', 'username', 'hostname')) + if isinstance(value, list): + if all(self._check_for_int(item) for item in value): + identifier = 'or__id' + else: + identifier = 'or__' + identifier + return endpoint.get(**{identifier: value}, all_pages=True) def export_assets(self, **kwargs): diff --git a/awxkit/awxkit/cli/resource.py b/awxkit/awxkit/cli/resource.py index eb605b146b..05e8163059 100644 --- a/awxkit/awxkit/cli/resource.py +++ b/awxkit/awxkit/cli/resource.py @@ -161,7 +161,7 @@ class Export(CustomCommand): # 1) the resource flag is not used at all, which will result in the attr being None # 2) the resource flag is used with no argument, which will result in the attr being '' # 3) the resource flag is used with an argument, and the attr will be that argument's value - resources.add_argument('--{}'.format(resource), nargs='?', const='') + resources.add_argument('--{}'.format(resource), nargs='*') def handle(self, client, parser): self.extend_parser(parser)