From 516b39b79a4bb66da113f6496e6c3c7555f8bbec Mon Sep 17 00:00:00 2001 From: Kevin Breit Date: Wed, 31 Jul 2019 10:29:42 -0500 Subject: [PATCH] meraki_organization - Add deletion support (#59415) * Add support for deleting organizations - Still working on integration tests * Update documentation and verify check mode works --- .../network/meraki/meraki_organization.py | 46 ++++--- .../meraki_organization/tasks/main.yml | 124 +---------------- .../meraki_organization/tasks/tests.yml | 127 ++++++++++++++++++ 3 files changed, 159 insertions(+), 138 deletions(-) create mode 100644 test/integration/targets/meraki_organization/tasks/tests.yml diff --git a/lib/ansible/modules/network/meraki/meraki_organization.py b/lib/ansible/modules/network/meraki/meraki_organization.py index 95ccef02c40..fcc7af0e396 100644 --- a/lib/ansible/modules/network/meraki/meraki_organization.py +++ b/lib/ansible/modules/network/meraki/meraki_organization.py @@ -24,7 +24,8 @@ options: state: description: - Create or modify an organization. - choices: ['present', 'query'] + - C(org_id) must be specified if multiple organizations of the same name exist. + choices: ['absent', 'present', 'query'] default: present clone: description: @@ -52,6 +53,13 @@ EXAMPLES = r''' state: present delegate_to: localhost +- name: Delete an organization named YourOrg + meraki_organization: + auth_key: abc12345 + org_name: YourOrg + state: absent + delegate_to: localhost + - name: Query information about all organizations associated to the user meraki_organization: auth_key: abc12345 @@ -123,7 +131,7 @@ def main(): # the module argument_spec = meraki_argument_spec() argument_spec.update(clone=dict(type='str'), - state=dict(type='str', choices=['present', 'query'], default='present'), + state=dict(type='str', choices=['absent', 'present', 'query'], default='present'), org_name=dict(type='str', aliases=['name', 'organization']), org_id=dict(type='str', aliases=['id']), ) @@ -147,28 +155,18 @@ def main(): meraki.params['follow_redirects'] = 'all' - create_urls = {'organizations': '/organizations', - } - update_urls = {'organizations': '/organizations/{org_id}', - } - clone_urls = {'organizations': '/organizations/{org_id}/clone', - } + create_urls = {'organizations': '/organizations'} + update_urls = {'organizations': '/organizations/{org_id}'} + delete_urls = {'organizations': '/organizations/{org_id}'} + clone_urls = {'organizations': '/organizations/{org_id}/clone'} meraki.url_catalog['create'] = create_urls meraki.url_catalog['update'] = update_urls meraki.url_catalog['clone'] = clone_urls + meraki.url_catalog['delete'] = delete_urls payload = None - # if the user is working with this module in only check mode we do not - # want to make any changes to the environment, just return the current - # state with no modifications - # FIXME: Work with Meraki so they can implement a check mode - if module.check_mode: - meraki.exit_json(**meraki.result) - - # execute checks for argument completeness - # manipulate or modify the state as needed (this is going to be the # part where your module will do what it needs to do) orgs = meraki.get_orgs() @@ -221,6 +219,20 @@ def main(): meraki.result['changed'] = True else: meraki.result['data'] = original + elif meraki.params['state'] == 'absent': + if meraki.params['org_name'] is not None: + org_id = meraki.get_org_id(meraki.params['org_name']) + elif meraki.params['org_id'] is not None: + org_id = meraki.params['org_id'] + if meraki.check_mode is True: + meraki.result['data'] = {} + meraki.result['changed'] = True + meraki.exit_json(**meraki.result) + path = meraki.construct_path('delete', org_id=org_id) + response = meraki.request(path, method='DELETE') + if meraki.status == 204: + meraki.result['data'] = {} + meraki.result['changed'] = True # in the event of a successful module execution, you will want to # simple AnsibleModule.exit_json(), passing the key/value results diff --git a/test/integration/targets/meraki_organization/tasks/main.yml b/test/integration/targets/meraki_organization/tasks/main.yml index a4a12990b7d..e7ad65b8115 100644 --- a/test/integration/targets/meraki_organization/tasks/main.yml +++ b/test/integration/targets/meraki_organization/tasks/main.yml @@ -3,124 +3,6 @@ # GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) --- -- name: Test an API key is provided - fail: - msg: Please define an API key - when: auth_key is not defined - -- name: Use an invalid domain - meraki_organization: - auth_key: '{{ auth_key }}' - host: marrrraki.com - state: present - org_name: IntTestOrg - output_level: debug - delegate_to: localhost - register: invalid_domain - ignore_errors: yes - -- name: Disable HTTP - meraki_organization: - auth_key: '{{ auth_key }}' - use_https: false - state: query - output_level: debug - delegate_to: localhost - register: http - ignore_errors: yes - -- name: Connection assertions - assert: - that: - - '"Failed to connect to" in invalid_domain.msg' - - '"http" in http.url' - -- name: Create a new organization named IntTestOrg - meraki_organization: - auth_key: '{{ auth_key }}' - org_name: IntTestOrg - state: present - output_level: debug - delegate_to: localhost - register: new_org - -- debug: - msg: '{{new_org}}' - -- name: Clone IntTestOrg - meraki_organization: - auth_key: '{{ auth_key }}' - clone: IntTestOrg - org_name: IntTestOrgCloned - state: present - delegate_to: localhost - register: cloned_org - -- debug: - msg: '{{cloned_org}}' - -- name: Rename IntTestOrg - meraki_organization: - auth_key: '{{ auth_key }}' - org_name: IntTestOrgRenamed - org_id: '{{ new_org.data.id }}' - state: present - delegate_to: localhost - register: modify_org - -- debug: - msg: '{{ modify_org }}' - -- name: Rename IntTestOrg idempotent - meraki_organization: - auth_key: '{{ auth_key }}' - org_name: IntTestOrgRenamed - org_id: '{{ new_org.data.id }}' - state: present - delegate_to: localhost - register: modify_org_idempotent - -- name: Present assertions - assert: - that: - - '"https" in new_org.url' - - new_org.changed == True - - new_org.data.id is defined - - cloned_org.changed == True - - cloned_org.data.id is defined - - modify_org.changed == True - - 'modify_org.data.name == "IntTestOrgRenamed"' - - modify_org_idempotent.changed == False - - modify_org_idempotent.data is defined - -- name: List all organizations - meraki_organization: - auth_key: '{{ auth_key }}' - state: query - delegate_to: localhost - register: query_all - -- name: Query information about a single organization named IntTestOrg - meraki_organization: - auth_key: '{{ auth_key }}' - org_name: IntTestOrgRenamed - state: query - delegate_to: localhost - register: query_org - -- name: Query information about IntTestOrg by organization ID - meraki_organization: - auth_key: '{{ auth_key }}' - org_id: '{{ query_org.data.id }}' - state: query - delegate_to: localhost - register: query_org_id - -- name: Query assertions - assert: - that: - - query_org.data.id is defined - - query_all.changed == False - - query_all.data | length >= 1 - - 'query_org.data.name == "IntTestOrgRenamed"' - - 'query_org_id.data.id == query_org.data.id' \ No newline at end of file +- name: Run test cases + include: tests.yml ansible_connection=local + \ No newline at end of file diff --git a/test/integration/targets/meraki_organization/tasks/tests.yml b/test/integration/targets/meraki_organization/tasks/tests.yml new file mode 100644 index 00000000000..75ba93c6b91 --- /dev/null +++ b/test/integration/targets/meraki_organization/tasks/tests.yml @@ -0,0 +1,127 @@ +# Test code for the Meraki Organization module +# Copyright: (c) 2018, Kevin Breit (@kbreit) + +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) +--- +- block: + - name: Test an API key is provided + fail: + msg: Please define an API key + when: auth_key is not defined + + - name: Create a new organization named IntTestOrg + meraki_organization: + auth_key: '{{ auth_key }}' + org_name: IntTestOrg + state: present + output_level: debug + register: new_org + + - debug: + msg: '{{new_org}}' + + - name: Clone IntTestOrg + meraki_organization: + auth_key: '{{ auth_key }}' + clone: IntTestOrg + org_name: IntTestOrgCloned + state: present + register: cloned_org + + - debug: + msg: '{{cloned_org}}' + + - name: Rename IntTestOrg + meraki_organization: + auth_key: '{{ auth_key }}' + org_name: IntTestOrgRenamed + org_id: '{{ new_org.data.id }}' + state: present + register: modify_org + + - debug: + msg: '{{ modify_org }}' + + - set_fact: + renamed_org_id: '{{modify_org.data.id}}' + + - name: Rename IntTestOrg idempotent + meraki_organization: + auth_key: '{{ auth_key }}' + org_name: IntTestOrgRenamed + org_id: '{{ new_org.data.id }}' + state: present + register: modify_org_idempotent + + - name: Present assertions + assert: + that: + - '"https" in new_org.url' + - new_org.changed == True + - new_org.data.id is defined + - cloned_org.changed == True + - cloned_org.data.id is defined + - modify_org.changed == True + - 'modify_org.data.name == "IntTestOrgRenamed"' + - modify_org_idempotent.changed == False + - modify_org_idempotent.data is defined + + - name: List all organizations + meraki_organization: + auth_key: '{{ auth_key }}' + state: query + register: query_all + + - name: Query information about a single organization named IntTestOrg + meraki_organization: + auth_key: '{{ auth_key }}' + org_name: IntTestOrgRenamed + state: query + register: query_org + + - name: Query information about IntTestOrg by organization ID + meraki_organization: + auth_key: '{{ auth_key }}' + org_id: '{{ query_org.data.id }}' + state: query + register: query_org_id + + - name: Query assertions + assert: + that: + - query_org.data.id is defined + - query_all.changed == False + - query_all.data | length >= 1 + - 'query_org.data.name == "IntTestOrgRenamed"' + - 'query_org_id.data.id == query_org.data.id' + + always: + - name: Delete cloned organizations with check mode + meraki_organization: + auth_key: '{{ auth_key }}' + state: absent + org_name: IntTestOrgCloned + register: deleted_org_check + check_mode: yes + + - assert: + that: + - deleted_org_check is changed + + - name: Delete cloned organizations + meraki_organization: + auth_key: '{{ auth_key }}' + state: absent + org_name: IntTestOrgCloned + register: deleted_org + + - name: Delete renamed organization by id + meraki_organization: + auth_key: '{{ auth_key }}' + state: absent + org_id: '{{renamed_org_id}}' + register: deleted_org_id + + - assert: + that: + - deleted_org_id is changed