meraki_config_template - Enable check mode (#54502)

* Add support for check mode

* Check mode returns proper changed status
- Added is_template_valid()
- Restructured check_mode so it will always return data
- Check mode should show proper changed status
- Code is untested and integration tests need to be expanded

* Fix deleting networks
- Add integration tests for deleting networks
- Refine tests based on changed/unchanged

* Remove one task from integration test
This commit is contained in:
Kevin Breit 2019-05-29 15:30:26 -05:00 committed by Nathaniel Case
parent 4df53f869e
commit 5008e1d479
4 changed files with 113 additions and 24 deletions

View file

@ -0,0 +1,3 @@
---
minor_changes:
- "meraki_config_template - Enable check mode."

View file

@ -61,6 +61,7 @@ class MerakiModule(object):
self.nets = None self.nets = None
self.org_id = None self.org_id = None
self.net_id = None self.net_id = None
self.check_mode = module.check_mode
# normal output # normal output
self.existing = None self.existing = None

View file

@ -133,6 +133,13 @@ def get_template_id(meraki, name, data):
meraki.fail_json(msg='No configuration template named {0} found'.format(name)) meraki.fail_json(msg='No configuration template named {0} found'.format(name))
def is_template_valid(meraki, nets, template_id):
for net in nets:
if net['id'] == template_id:
return True
return False
def is_network_bound(meraki, nets, net_id, template_id): def is_network_bound(meraki, nets, net_id, template_id):
for net in nets: for net in nets:
if net['id'] == net_id: if net['id'] == net_id:
@ -149,7 +156,7 @@ def delete_template(meraki, org_id, name, data):
path = meraki.construct_path('delete', org_id=org_id) path = meraki.construct_path('delete', org_id=org_id)
path = path + '/' + template_id path = path + '/' + template_id
response = meraki.request(path, 'DELETE') response = meraki.request(path, 'DELETE')
if meraki.status != 200: if meraki.status != 204:
meraki.fail_json(msg='Unable to remove configuration template') meraki.fail_json(msg='Unable to remove configuration template')
return response return response
@ -217,9 +224,6 @@ def main():
# if the user is working with this module in only check mode we do not # 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 # want to make any changes to the environment, just return the current
# state with no modifications # 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 # execute checks for argument completeness
@ -245,7 +249,11 @@ def main():
get_config_templates(meraki, org_id)) get_config_templates(meraki, org_id))
if nets is None: if nets is None:
nets = meraki.get_nets(org_id=org_id) nets = meraki.get_nets(org_id=org_id)
if is_network_bound(meraki, nets, net_id, template_id) is False: if is_network_bound(meraki, nets, net_id, template_id) is False: # Bind template
if meraki.check_mode is True:
meraki.result['data'] = {}
meraki.result['changed'] = True
meraki.exit_json(**meraki.result)
template_bind = bind(meraki, template_bind = bind(meraki,
net_id, net_id,
template_id) template_id)
@ -253,31 +261,64 @@ def main():
meraki.fail_json(msg='Unable to bind configuration template to network') meraki.fail_json(msg='Unable to bind configuration template to network')
meraki.result['changed'] = True meraki.result['changed'] = True
meraki.result['data'] = template_bind meraki.result['data'] = template_bind
else: else: # Network is already bound, being explicit
if meraki.check_mode is True: # Include to be explicit
meraki.result['data'] = {} meraki.result['data'] = {}
meraki.result['changed'] = False
meraki.exit_json(**meraki.result)
meraki.result['data'] = {}
meraki.result['changed'] = False
meraki.exit_json(**meraki.result)
elif meraki.params['state'] == 'absent': elif meraki.params['state'] == 'absent':
if not meraki.params['net_name'] and not meraki.params['net_id']: template_id = get_template_id(meraki,
meraki.params['config_template'],
get_config_templates(meraki, org_id))
if not meraki.params['net_name'] and not meraki.params['net_id']: # Delete template
if is_template_valid(meraki, nets, template_id) is True:
if meraki.check_mode is True:
meraki.result['data'] = {}
meraki.result['changed'] = True
meraki.exit_json(**meraki.result)
meraki.result['data'] = delete_template(meraki, meraki.result['data'] = delete_template(meraki,
org_id, org_id,
meraki.params['config_template'], meraki.params['config_template'],
get_config_templates(meraki, org_id)) get_config_templates(meraki, org_id))
if meraki.status == 200: if meraki.status == 204:
meraki.result['data'] = {}
meraki.result['changed'] = True meraki.result['changed'] = True
else: else:
meraki.fail_json(msg="No template named {0} found.".format(meraki.params['config_template']))
else: # Unbind template
if meraki.check_mode is True:
meraki.result['data'] = {}
if is_template_valid(meraki, nets, template_id) is True:
meraki.result['changed'] = True
else:
meraki.result['changed'] = False
meraki.exit_json(**meraki.result)
template_id = get_template_id(meraki, template_id = get_template_id(meraki,
meraki.params['config_template'], meraki.params['config_template'],
get_config_templates(meraki, org_id)) get_config_templates(meraki, org_id))
if nets is None: if nets is None:
nets = meraki.get_nets(org_id=org_id) nets = meraki.get_nets(org_id=org_id)
if is_network_bound(meraki, nets, net_id, template_id) is True: if is_network_bound(meraki, nets, net_id, template_id) is True:
if meraki.check_mode is True:
meraki.result['data'] = {}
meraki.result['changed'] = True
meraki.exit_json(**meraki.result)
config_unbind = unbind(meraki, config_unbind = unbind(meraki,
net_id) net_id)
if meraki.status != 200: if meraki.status != 200:
meraki.fail_json(msg='Unable to unbind configuration template from network') meraki.fail_json(msg='Unable to unbind configuration template from network')
meraki.result['changed'] = True meraki.result['changed'] = True
meraki.result['data'] = config_unbind meraki.result['data'] = config_unbind
else: else: # No network is bound, nothing to do
if meraki.check_mode is True: # Include to be explicit
meraki.result['data'] = {} meraki.result['data'] = {}
meraki.result['changed'] = False
meraki.exit_json(**meraki.result)
meraki.result['data'] = {}
meraki.result['changed'] = False
# in the event of a successful module execution, you will want to # in the event of a successful module execution, you will want to
# simple AnsibleModule.exit_json(), passing the key/value results # simple AnsibleModule.exit_json(), passing the key/value results

View file

@ -53,18 +53,21 @@
net_name: '{{ test_net_name }}' net_name: '{{ test_net_name }}'
type: appliance type: appliance
delegate_to: localhost delegate_to: localhost
- name: Get network id
meraki_network:
auth_key: '{{auth_key}}'
state: query
org_name: '{{test_org_name}}'
net_name: '{{test_net_name}}'
register: net_info register: net_info
- set_fact: - set_fact:
net_id: '{{net_info.data.id}}' net_id: '{{net_info.data.id}}'
- name: Bind a template to a network with check mode
meraki_config_template:
auth_key: '{{auth_key}}'
state: present
org_name: '{{ test_org_name }}'
net_name: '{{ test_net_name }}'
config_template: '{{test_template_name}}'
check_mode: yes
register: bind_check
- name: Bind a template to a network - name: Bind a template to a network
meraki_config_template: meraki_config_template:
auth_key: '{{auth_key}}' auth_key: '{{auth_key}}'
@ -78,6 +81,10 @@
that: that:
bind.changed == True bind.changed == True
- assert:
that:
bind_check is changed
- name: Bind a template to a network when it's already bound - name: Bind a template to a network when it's already bound
meraki_config_template: meraki_config_template:
auth_key: '{{auth_key}}' auth_key: '{{auth_key}}'
@ -145,7 +152,21 @@
- bind_id_idempotent.changed == False - bind_id_idempotent.changed == False
- bind_id_idempotent.data is defined - bind_id_idempotent.data is defined
- name: Unbind a template to a network via id - name: Unbind a template from a network via id with check mode
meraki_config_template:
auth_key: '{{auth_key}}'
state: absent
org_name: '{{test_org_name}}'
net_id: '{{net_id}}'
config_template: '{{test_template_name}}'
check_mode: yes
register: unbind_id_check
- assert:
that:
unbind_id_check is changed
- name: Unbind a template from a network via id
meraki_config_template: meraki_config_template:
auth_key: '{{auth_key}}' auth_key: '{{auth_key}}'
state: absent state: absent
@ -158,6 +179,29 @@
that: that:
unbind_id.changed == True unbind_id.changed == True
# This is disabled by default since they can't be created via API
- name: Delete sacrificial template with check mode
meraki_config_template:
auth_key: '{{auth_key}}'
state: absent
org_name: '{{test_org_name}}'
config_template: sacrificial_template
check_mode: yes
register: delete_template_check
# This is disabled by default since they can't be created via API
- name: Delete sacrificial template
meraki_config_template:
auth_key: '{{auth_key}}'
state: absent
org_name: '{{test_org_name}}'
config_template: sacrificial_template
output_level: debug
register: delete_template
- debug:
var: delete_template
always: always:
- name: Delete network - name: Delete network
meraki_network: meraki_network: