From 87169c4aa41afc42c94cf41fdf50d3119b80666e Mon Sep 17 00:00:00 2001 From: Kevin Breit Date: Wed, 12 Jun 2019 09:43:02 -0500 Subject: [PATCH] meraki_vlan - Enable check mode (#54627) * Add support for check mode * Add diff support - diff support is based on "have" and "want" data structures. - Review needs to be done on the diffs for accuracy and usefulness. - Changed change mode changed responses to be accurate. * Remove config template based integration tests --- .../53597-meraki_vlan_check_mode.yml | 3 + .../modules/network/meraki/meraki_vlan.py | 38 ++++--- .../targets/meraki_vlan/tasks/main.yml | 101 +++++++++++++++--- 3 files changed, 113 insertions(+), 29 deletions(-) create mode 100644 changelogs/fragments/53597-meraki_vlan_check_mode.yml diff --git a/changelogs/fragments/53597-meraki_vlan_check_mode.yml b/changelogs/fragments/53597-meraki_vlan_check_mode.yml new file mode 100644 index 00000000000..4cdd0f41c48 --- /dev/null +++ b/changelogs/fragments/53597-meraki_vlan_check_mode.yml @@ -0,0 +1,3 @@ +--- +minor_changes: + - "meraki_vlan - Add support for check mode." diff --git a/lib/ansible/modules/network/meraki/meraki_vlan.py b/lib/ansible/modules/network/meraki/meraki_vlan.py index cb9ae077bbf..1c88392de9e 100644 --- a/lib/ansible/modules/network/meraki/meraki_vlan.py +++ b/lib/ansible/modules/network/meraki/meraki_vlan.py @@ -259,9 +259,9 @@ response: sample: 192.0.1.2 ''' -import os from ansible.module_utils.basic import AnsibleModule, json, env_fallback from ansible.module_utils._text import to_native +from ansible.module_utils.common.dict_transformations import recursive_diff from ansible.module_utils.network.meraki.meraki import MerakiModule, meraki_argument_spec @@ -372,12 +372,16 @@ def main(): 'subnet': meraki.params['subnet'], 'applianceIp': meraki.params['appliance_ip'], } - if is_vlan_valid(meraki, net_id, meraki.params['vlan_id']) is False: + if is_vlan_valid(meraki, net_id, meraki.params['vlan_id']) is False: # Create new VLAN + if meraki.module.check_mode is True: + meraki.result['data'] = payload + meraki.result['changed'] = True + meraki.exit_json(**meraki.result) path = meraki.construct_path('create', net_id=net_id) response = meraki.request(path, method='POST', payload=json.dumps(payload)) meraki.result['changed'] = True meraki.result['data'] = response - else: + else: # Update existing VLAN path = meraki.construct_path('get_one', net_id=net_id, custom={'vlan_id': meraki.params['vlan_id']}) original = meraki.request(path, method='GET') if meraki.params['dns_nameservers']: @@ -393,31 +397,35 @@ def main(): payload['vpnNatSubnet'] = meraki.params['vpn_nat_subnet'] ignored = ['networkId'] if meraki.is_update_required(original, payload, optional_ignore=ignored): + meraki.result['diff'] = dict() + diff = recursive_diff(original, payload) + meraki.result['diff']['before'] = diff[0] + meraki.result['diff']['after'] = diff[1] + if meraki.module.check_mode is True: + original.update(payload) + meraki.result['changed'] = True + meraki.result['data'] = original + meraki.exit_json(**meraki.result) path = meraki.construct_path('update', net_id=net_id) + str(meraki.params['vlan_id']) response = meraki.request(path, method='PUT', payload=json.dumps(payload)) meraki.result['changed'] = True meraki.result['data'] = response else: + if meraki.module.check_mode is True: + meraki.result['data'] = original + meraki.exit_json(**meraki.result) meraki.result['data'] = original elif meraki.params['state'] == 'absent': if is_vlan_valid(meraki, net_id, meraki.params['vlan_id']): + if meraki.module.check_mode is True: + meraki.result['data'] = {} + meraki.result['changed'] = True + meraki.exit_json(**meraki.result) path = meraki.construct_path('delete', net_id=net_id) + str(meraki.params['vlan_id']) response = meraki.request(path, 'DELETE') meraki.result['changed'] = True meraki.result['data'] = response - # 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) - # in the event of a successful module execution, you will want to # simple AnsibleModule.exit_json(), passing the key/value results meraki.exit_json(**meraki.result) diff --git a/test/integration/targets/meraki_vlan/tasks/main.yml b/test/integration/targets/meraki_vlan/tasks/main.yml index ff0de078e57..6a155e7ff24 100644 --- a/test/integration/targets/meraki_vlan/tasks/main.yml +++ b/test/integration/targets/meraki_vlan/tasks/main.yml @@ -68,6 +68,27 @@ enable_vlans: yes delegate_to: localhost + - name: Create VLAN in check mode + meraki_vlan: + auth_key: '{{auth_key}}' + state: present + org_name: '{{test_org_name}}' + net_name: '{{test_net_name}}' + vlan_id: 2 + name: TestVLAN + subnet: 192.168.250.0/24 + appliance_ip: 192.168.250.1 + delegate_to: localhost + register: create_vlan_check + check_mode: yes + + - debug: + var: create_vlan_check + + - assert: + that: + - create_vlan_check is changed + - name: Create VLAN meraki_vlan: auth_key: '{{auth_key}}' @@ -89,23 +110,35 @@ - create_vlan.data.id == 2 - create_vlan.changed == True - - name: Create VLAN in template configuration + - name: Update VLAN with check mode meraki_vlan: auth_key: '{{auth_key}}' state: present org_name: '{{test_org_name}}' - net_name: '{{test_template_name}}' + net_name: '{{test_net_name}}' vlan_id: 2 name: TestVLAN subnet: 192.168.250.0/24 - appliance_ip: 192.168.250.1 + appliance_ip: 192.168.250.2 + fixed_ip_assignments: + - mac: "13:37:de:ad:be:ef" + ip: 192.168.250.10 + name: fixed_ip + reserved_ip_range: + - start: 192.168.250.10 + end: 192.168.250.20 + comment: reserved_range + dns_nameservers: opendns delegate_to: localhost - register: create_vlan_template + register: update_vlan_check + check_mode: yes + + - debug: + var: update_vlan_check - assert: that: - - create_vlan_template.data.id == 2 - - create_vlan_template.changed == True + - update_vlan_check is changed - name: Update VLAN meraki_vlan: @@ -137,6 +170,36 @@ - update_vlan.data.applianceIp == '192.168.250.2' - update_vlan.changed == True + - name: Update VLAN with idempotency and check mode + meraki_vlan: + auth_key: '{{auth_key}}' + state: present + org_name: '{{test_org_name}}' + net_name: '{{test_net_name}}' + vlan_id: 2 + name: TestVLAN + subnet: 192.168.250.0/24 + appliance_ip: 192.168.250.2 + fixed_ip_assignments: + - mac: "13:37:de:ad:be:ef" + ip: 192.168.250.10 + name: fixed_ip + reserved_ip_range: + - start: 192.168.250.10 + end: 192.168.250.20 + comment: reserved_range + dns_nameservers: opendns + delegate_to: localhost + register: update_vlan_idempotent_check + check_mode: yes + + - debug: + var: update_vlan_idempotent_check + + - assert: + that: + - update_vlan_idempotent_check is not changed + - name: Update VLAN with idempotency meraki_vlan: auth_key: '{{auth_key}}' @@ -336,6 +399,21 @@ ############################################################################# # Tear down starts here ############################################################################# + - name: Delete VLAN with check mode + meraki_vlan: + auth_key: '{{auth_key}}' + state: absent + org_name: '{{test_org_name}}' + net_name: '{{test_net_name}}' + vlan_id: 2 + delegate_to: localhost + register: delete_vlan_check + check_mode: yes + + - assert: + that: + delete_vlan_check is changed + - name: Delete VLAN meraki_vlan: auth_key: '{{auth_key}}' @@ -349,15 +427,10 @@ - debug: msg: '{{delete_vlan}}' - - name: Delete VLAN using template ID - meraki_vlan: + - name: Delete test network + meraki_network: auth_key: '{{auth_key}}' state: absent org_name: '{{test_org_name}}' - net_id: '{{test_template_id}}' - vlan_id: 2 + net_name: '{{test_net_name}}' delegate_to: localhost - register: delete_vlan_template - - - debug: - msg: '{{delete_vlan_template}}'