diff --git a/awx_collection/plugins/modules/tower_inventory_source.py b/awx_collection/plugins/modules/tower_inventory_source.py index 7c7c506826..0145671933 100644 --- a/awx_collection/plugins/modules/tower_inventory_source.py +++ b/awx_collection/plugins/modules/tower_inventory_source.py @@ -131,7 +131,6 @@ options: organization: description: - Name of the inventory source's inventory's organization. - required: True type: str extends_documentation_fragment: awx.awx.auth ''' @@ -174,7 +173,7 @@ def main(): enabled_value=dict(), host_filter=dict(), credential=dict(), - organization=dict(required=True), + organization=dict(), overwrite=dict(type='bool'), overwrite_vars=dict(type='bool'), custom_virtualenv=dict(), @@ -203,14 +202,10 @@ def main(): source_project = module.params.get('source_project') state = module.params.get('state') - # Attempt to look up inventory source based on the provided name and inventory ID - org_id = module.resolve_name_to_id('organizations', organization) - inventory_object = module.get_one('inventories', **{ - 'data': { - 'name': inventory, - 'organization': org_id, - } - }) + lookup_data = {'name': inventory} + if organization: + lookup_data['organization'] = module.resolve_name_to_id('organizations', organization) + inventory_object = module.get_one('inventories', data=lookup_data) if not inventory_object: module.fail_json(msg='The specified inventory was not found.') diff --git a/awx_collection/plugins/modules/tower_inventory_source_update.py b/awx_collection/plugins/modules/tower_inventory_source_update.py index 8579126dd3..abb55d1941 100644 --- a/awx_collection/plugins/modules/tower_inventory_source_update.py +++ b/awx_collection/plugins/modules/tower_inventory_source_update.py @@ -36,7 +36,6 @@ options: description: - Name of the inventory source's inventory's organization. type: str - required: True wait: description: - Wait for the job to complete. @@ -91,7 +90,7 @@ def main(): argument_spec = dict( inventory=dict(required=True), inventory_source=dict(required=True), - organization=dict(required=True), + organization=dict(), wait=dict(default=False, type='bool'), interval=dict(default=1.0, type='float'), timeout=dict(default=None, type='int'), @@ -108,13 +107,10 @@ def main(): interval = module.params.get('interval') timeout = module.params.get('timeout') - org_id = module.resolve_name_to_id('organizations', organization) - inventory_object = module.get_one('inventories', **{ - 'data': { - 'name': inventory, - 'organization': org_id, - } - }) + lookup_data = {'name': inventory} + if organization: + lookup_data['organization'] = module.resolve_name_to_id('organizations', organization) + inventory_object = module.get_one('inventories', data=lookup_data) if not inventory_object: module.fail_json(msg='The specified inventory was not found.') diff --git a/awx_collection/test/awx/test_inventory_source.py b/awx_collection/test/awx/test_inventory_source.py index b1b362efad..9f52574670 100644 --- a/awx_collection/test/awx/test_inventory_source.py +++ b/awx_collection/test/awx/test_inventory_source.py @@ -24,12 +24,11 @@ def project(base_inventory): @pytest.mark.django_db -def test_inventory_source_create(run_module, admin_user, base_inventory, project, organization): +def test_inventory_source_create(run_module, admin_user, base_inventory, project): source_path = '/var/lib/awx/example_source_path/' result = run_module('tower_inventory_source', dict( name='foo', inventory=base_inventory.name, - organization='test-org', state='present', source='scm', source_path=source_path, @@ -46,6 +45,30 @@ def test_inventory_source_create(run_module, admin_user, base_inventory, project } +@pytest.mark.django_db +def test_create_inventory_source_implied_org(run_module, admin_user): + org = Organization.objects.create(name='test-org') + inv = Inventory.objects.create(name='test-inv', organization=org) + + # Credential is not required for ec2 source, because of IAM roles + result = run_module('tower_inventory_source', dict( + name='Test Inventory Source', + inventory='test-inv', + source='ec2', + state='present' + ), admin_user) + assert result.pop('changed', None), result + + inv_src = InventorySource.objects.get(name='Test Inventory Source') + assert inv_src.inventory == inv + + result.pop('invocation') + assert result == { + "name": "Test Inventory Source", + "id": inv_src.id, + } + + @pytest.mark.django_db def test_create_inventory_source_multiple_orgs(run_module, admin_user): org = Organization.objects.create(name='test-org') @@ -82,7 +105,6 @@ def test_create_inventory_source_with_venv(run_module, admin_user, base_inventor result = run_module('tower_inventory_source', dict( name='foo', inventory=base_inventory.name, - organization='test-org', state='present', source='scm', source_project=project.name, @@ -99,7 +121,7 @@ def test_create_inventory_source_with_venv(run_module, admin_user, base_inventor @pytest.mark.django_db -def test_custom_venv_no_op(run_module, admin_user, base_inventory, mocker, project, organization): +def test_custom_venv_no_op(run_module, admin_user, base_inventory, mocker, project): """If the inventory source is modified, then it should not blank fields unrelated to the params that the user passed. This enforces assumptions about the behavior of the AnsibleModule @@ -119,7 +141,6 @@ def test_custom_venv_no_op(run_module, admin_user, base_inventory, mocker, proje name='foo', description='this is the changed description', inventory=base_inventory.name, - organization='test-org', source='scm', # is required, but behavior is arguable state='present', source_project=project.name, @@ -136,7 +157,6 @@ def test_falsy_value(run_module, admin_user, base_inventory): result = run_module('tower_inventory_source', dict( name='falsy-test', inventory=base_inventory.name, - organization='test-org', source='ec2', update_on_launch=True ), admin_user) @@ -149,7 +169,6 @@ def test_falsy_value(run_module, admin_user, base_inventory): result = run_module('tower_inventory_source', dict( name='falsy-test', inventory=base_inventory.name, - organization='test-org', # source='ec2', update_on_launch=False ), admin_user) @@ -185,7 +204,6 @@ def test_missing_required_credential(run_module, admin_user, base_inventory): result = run_module('tower_inventory_source', dict( name='Test Azure Source', inventory=base_inventory.name, - organization='test-org', source='azure_rm', state='present' ), admin_user) @@ -199,7 +217,6 @@ def test_source_project_not_for_cloud(run_module, admin_user, base_inventory, pr result = run_module('tower_inventory_source', dict( name='Test ec2 Inventory Source', inventory=base_inventory.name, - organization='test-org', source='ec2', state='present', source_project=project.name @@ -214,7 +231,6 @@ def test_source_path_not_for_cloud(run_module, admin_user, base_inventory): result = run_module('tower_inventory_source', dict( name='Test ec2 Inventory Source', inventory=base_inventory.name, - organization='test-org', source='ec2', state='present', source_path='where/am/I' @@ -228,7 +244,6 @@ def test_source_path_not_for_cloud(run_module, admin_user, base_inventory): def test_scm_source_needs_project(run_module, admin_user, base_inventory): result = run_module('tower_inventory_source', dict( name='SCM inventory without project', - organization='test-org', inventory=base_inventory.name, state='present', source='scm', diff --git a/awx_collection/tests/integration/targets/tower_inventory_source/tasks/main.yml b/awx_collection/tests/integration/targets/tower_inventory_source/tasks/main.yml index 738d432711..fb5f33c3ca 100644 --- a/awx_collection/tests/integration/targets/tower_inventory_source/tasks/main.yml +++ b/awx_collection/tests/integration/targets/tower_inventory_source/tasks/main.yml @@ -31,7 +31,6 @@ credential: "{{ openstack_cred }}" overwrite: true update_on_launch: true - organization: Default source_vars: private: false source: openstack @@ -48,7 +47,6 @@ credential: "Does Not Exit" source_project: "Does Not Exist" source_script: "Does Not Exist" - organization: Default state: absent - assert: diff --git a/awx_collection/tests/integration/targets/tower_inventory_source_update/tasks/main.yml b/awx_collection/tests/integration/targets/tower_inventory_source_update/tasks/main.yml index b151db90ba..36a4e4b058 100644 --- a/awx_collection/tests/integration/targets/tower_inventory_source_update/tasks/main.yml +++ b/awx_collection/tests/integration/targets/tower_inventory_source_update/tasks/main.yml @@ -34,14 +34,14 @@ organization: "{{ org_name }}" state: present - - name: Create another inventory w/ same name + - name: Create another inventory w/ same name, different org tower_inventory: name: "{{ inv_name }}" organization: Default state: present register: created_inventory - - name: Create an Inventory Source + - name: Create an Inventory Source (specifically connected to the randomly generated org) tower_inventory_source: name: "{{ inv_source1 }}" source: scm @@ -51,7 +51,7 @@ organization: "{{ created_org.id }}" inventory: "{{ inv_name }}" - - name: Create Another Inventory Source (for testing org-based lookup) + - name: Create Another Inventory Source tower_inventory_source: name: "{{ inv_source2 }}" source: scm @@ -61,7 +61,7 @@ organization: Default inventory: "{{ inv_name }}" - - name: Create Yet Another Inventory Source (one more to make lookup plugin find multiple inventory sources) + - name: Create Yet Another Inventory Source (to make lookup plugin find multiple inv sources) tower_inventory_source: name: "{{ inv_source3 }}" source: scm diff --git a/awx_collection/tools/roles/template_galaxy/templates/README.md.j2 b/awx_collection/tools/roles/template_galaxy/templates/README.md.j2 index e1de06ec97..8a5743d34f 100644 --- a/awx_collection/tools/roles/template_galaxy/templates/README.md.j2 +++ b/awx_collection/tools/roles/template_galaxy/templates/README.md.j2 @@ -104,7 +104,6 @@ The following notes are changes that may require changes to playbooks: - The `notification_configuration` parameter of `tower_notification_template` has changed from a string to a dict. Please use the `lookup` plugin to read an existing file into a dict. - `tower_credential` no longer supports passing a file name to ssh_key_data. - The HipChat `notification_type` has been removed and can no longer be created using the `tower_notification_template` module. - - The `tower_inventory_source` module now requires the `organization` parameter in order to specify the inventory source's inventory's organization. {% if collection_package | lower() == "awx" %} ## Running Unit Tests