Meraki - Convert response keys to snake_case from camelCase (#53891)

* Initial proposal for new parameter option for response format
- output_version parameter dictates the response key case
- new is snake_case, old is camelCase
- If new, conversion is done at the end of module execution
- This is purely a proposal and not a final draft

* Add support for ANSIBLE_MERAKI_FORMAT env var
- If env var is set to 'camelcase' it will output camelcase
- Otherwise, will default to snakecase
- Added note to documentation fragment
- As of now, all module documentation needs to be updated

* Fix pep8 errors and remove output_version args

* Restructure check in exit_json so it actually works

* Add changelog fragment

* Change output_format to a parameter with env var fallback
- ANSIBLE_MERAKI_FORMAT is the valid env var
- Added documentation

* Convert to camel_dict_to_snake_dict() which is from Ansible
- Fixed integration tests

* Fix yaml lint error

* exit_json camel_case conversion handles no data
- exit_json would fail if data wasn't provided
- Updated 3 integration tests for new naming convention

* convert_camel_to_snake() handles lists and dicts
- The native Ansible method doesn't handle first level lists
- convert_camel_to_snake() acts simply as a wrapper for the method
- There maybe a situation where nested lists are a problem, must test
- Fixed integration tests in some modules

* A few integration test fixes

* Convert response documentation to snake case
This commit is contained in:
Kevin Breit 2019-06-13 14:07:30 -05:00 committed by Nathaniel Case
parent 5243cba0b2
commit a85750dc98
16 changed files with 141 additions and 93 deletions

View file

@ -0,0 +1,2 @@
minor_changes:
- Meraki modules now return data in snake_case instead of camelCase. The ANSIBLE_MERAKI_FORMAT environment variable can be set to camelcase to revert back to camelcase until deprecation in Ansible 2.13.

View file

@ -30,7 +30,9 @@
# USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
import os import os
import re
from ansible.module_utils.basic import AnsibleModule, json, env_fallback from ansible.module_utils.basic import AnsibleModule, json, env_fallback
from ansible.module_utils.common.dict_transformations import camel_dict_to_snake_dict
from ansible.module_utils.urls import fetch_url from ansible.module_utils.urls import fetch_url
from ansible.module_utils.six.moves.urllib.parse import urlencode from ansible.module_utils.six.moves.urllib.parse import urlencode
from ansible.module_utils._text import to_native, to_bytes, to_text from ansible.module_utils._text import to_native, to_bytes, to_text
@ -42,6 +44,7 @@ def meraki_argument_spec():
use_proxy=dict(type='bool', default=False), use_proxy=dict(type='bool', default=False),
use_https=dict(type='bool', default=True), use_https=dict(type='bool', default=True),
validate_certs=dict(type='bool', default=True), validate_certs=dict(type='bool', default=True),
output_format=dict(type='str', choices=['camelcase', 'snakecase'], default='snakecase', fallback=(env_fallback, ['ANSIBLE_MERAKI_FORMAT'])),
output_level=dict(type='str', default='normal', choices=['normal', 'debug']), output_level=dict(type='str', default='normal', choices=['normal', 'debug']),
timeout=dict(type='int', default=30), timeout=dict(type='int', default=30),
org_name=dict(type='str', aliases=['organization']), org_name=dict(type='str', aliases=['organization']),
@ -62,6 +65,7 @@ class MerakiModule(object):
self.org_id = None self.org_id = None
self.net_id = None self.net_id = None
self.check_mode = module.check_mode self.check_mode = module.check_mode
self.key_map = {}
# normal output # normal output
self.existing = None self.existing = None
@ -130,16 +134,25 @@ class MerakiModule(object):
else: else:
self.params['protocol'] = 'http' self.params['protocol'] = 'http'
def sanitize(self, original, proposed): def sanitize_keys(self, data):
"""Determine which keys are unique to original""" if isinstance(data, dict):
keys = [] items = {}
for k, v in original.items(): for k, v in data.items():
try: try:
if proposed[k] and k not in self.ignored_keys: new = {self.key_map[k]: data[k]}
pass items[self.key_map[k]] = self.sanitize_keys(data[k])
except KeyError: except KeyError:
keys.append(k) snake_k = re.sub('([a-z0-9])([A-Z])', r'\1_\2', k).lower()
return keys new = {snake_k: data[k]}
items[snake_k] = self.sanitize_keys(data[k])
return items
elif isinstance(data, list):
items = []
for i in data:
items.append(self.sanitize_keys(i))
return items
elif isinstance(data, int) or isinstance(data, str) or isinstance(data, float):
return data
def is_update_required(self, original, proposed, optional_ignore=None): def is_update_required(self, original, proposed, optional_ignore=None):
''' Compare two data-structures ''' ''' Compare two data-structures '''
@ -269,6 +282,20 @@ class MerakiModule(object):
return template['id'] return template['id']
self.fail_json(msg='No configuration template named {0} found'.format(name)) self.fail_json(msg='No configuration template named {0} found'.format(name))
def convert_camel_to_snake(self, data):
"""
Converts a dictionary or list to snake case from camel case
:type data: dict or list
:return: Converted data structure, if list or dict
"""
if isinstance(data, dict):
return camel_dict_to_snake_dict(data, ignore_list=('tags', 'tag'))
elif isinstance(data, list):
return [camel_dict_to_snake_dict(item, ignore_list=('tags', 'tag')) for item in data]
else:
return data
def construct_params_list(self, keys, aliases=None): def construct_params_list(self, keys, aliases=None):
qs = {} qs = {}
for key in keys: for key in keys:
@ -344,8 +371,15 @@ class MerakiModule(object):
if self.params['output_level'] == 'debug': if self.params['output_level'] == 'debug':
self.result['method'] = self.method self.result['method'] = self.method
self.result['url'] = self.url self.result['url'] = self.url
self.result.update(**kwargs) self.result.update(**kwargs)
if self.params['output_format'] == 'camelcase':
self.module.deprecate("Update your playbooks to support snake_case format instead of camelCase format.", version=2.13)
else:
if 'data' in self.result:
try:
self.result['data'] = self.convert_camel_to_snake(self.result['data'])
except (KeyError, AttributeError):
pass
self.module.exit_json(**self.result) self.module.exit_json(**self.result)
def fail_json(self, msg, **kwargs): def fail_json(self, msg, **kwargs):

View file

@ -193,22 +193,22 @@ data:
returned: success returned: success
type: str type: str
sample: John Doe sample: John Doe
accountStatus: account_status:
description: Status of account. description: Status of account.
returned: success returned: success
type: str type: str
sample: ok sample: ok
twoFactorAuthEnabled: two_factor_auth_enabled:
description: Enabled state of two-factor authentication for administrator. description: Enabled state of two-factor authentication for administrator.
returned: success returned: success
type: bool type: bool
sample: false sample: false
hasApiKey: has_api_key:
description: Defines whether administrator has an API assigned to their account. description: Defines whether administrator has an API assigned to their account.
returned: success returned: success
type: bool type: bool
sample: false sample: false
lastActive: last_active:
description: Date and time of time the administrator was active within Dashboard. description: Date and time of time the administrator was active within Dashboard.
returned: success returned: success
type: str type: str
@ -243,7 +243,7 @@ data:
returned: when tag permissions are set returned: when tag permissions are set
type: str type: str
sample: full sample: full
orgAccess: org_access:
description: The privilege of the dashboard administrator on the organization. Options are 'full', 'read-only', or 'none'. description: The privilege of the dashboard administrator on the organization. Options are 'full', 'read-only', or 'none'.
returned: success returned: success
type: str type: str

View file

@ -154,7 +154,7 @@ data:
returned: success returned: success
type: str type: str
sample: YourNet sample: YourNet
organizationId: organization_id:
description: Organization ID which owns the network. description: Organization ID which owns the network.
returned: success returned: success
type: str type: str
@ -164,7 +164,7 @@ data:
returned: success returned: success
type: str type: str
sample: " production wireless " sample: " production wireless "
timeZone: time_zone:
description: Timezone where network resides. description: Timezone where network resides.
returned: success returned: success
type: str type: str
@ -174,7 +174,7 @@ data:
returned: success returned: success
type: str type: str
sample: switch sample: switch
disableMyMerakiCom: disable_my_meraki_com:
description: States whether U(my.meraki.com) and other device portals should be disabled. description: States whether U(my.meraki.com) and other device portals should be disabled.
returned: success returned: success
type: bool type: bool

View file

@ -117,32 +117,32 @@ data:
returned: success returned: success
type: str type: str
sample: 16100 sample: 16100
v2cEnabled: v2c_enabled:
description: Shows enabled state of SNMPv2c description: Shows enabled state of SNMPv2c
returned: success returned: success
type: bool type: bool
sample: true sample: true
v3Enabled: v3_enabled:
description: Shows enabled state of SNMPv3 description: Shows enabled state of SNMPv3
returned: success returned: success
type: bool type: bool
sample: true sample: true
v3AuthMode: v3_auth_mode:
description: The SNMP version 3 authentication mode either MD5 or SHA. description: The SNMP version 3 authentication mode either MD5 or SHA.
returned: success returned: success
type: str type: str
sample: SHA sample: SHA
v3PrivMode: v3_priv_mode:
description: The SNMP version 3 privacy mode DES or AES128. description: The SNMP version 3 privacy mode DES or AES128.
returned: success returned: success
type: str type: str
sample: AES128 sample: AES128
v2CommunityString: v2_community_string:
description: Automatically generated community string for SNMPv2c. description: Automatically generated community string for SNMPv2c.
returned: When SNMPv2c is enabled. returned: When SNMPv2c is enabled.
type: str type: str
sample: o/8zd-JaSb sample: o/8zd-JaSb
v3User: v3_user:
description: Automatically generated username for SNMPv3. description: Automatically generated username for SNMPv3.
returned: When SNMPv3c is enabled. returned: When SNMPv3c is enabled.
type: str type: str

View file

@ -294,17 +294,17 @@ data:
returned: success returned: success
type: bool type: bool
sample: true sample: true
splashPage: splash_page:
description: Splash page to show when user authenticates. description: Splash page to show when user authenticates.
returned: success returned: success
type: str type: str
sample: Click-through splash page sample: Click-through splash page
ssidAdminAccessible: ssid_admin_accessible:
description: Whether SSID is administratively accessible. description: Whether SSID is administratively accessible.
returned: success returned: success
type: bool type: bool
sample: true sample: true
authMode: auth_mode:
description: Authentication method. description: Authentication method.
returned: success returned: success
type: str type: str
@ -314,37 +314,37 @@ data:
returned: success returned: success
type: str type: str
sample: SecretWiFiPass sample: SecretWiFiPass
encryptionMode: encryption_mode:
description: Wireless traffic encryption method. description: Wireless traffic encryption method.
returned: success returned: success
type: str type: str
sample: wpa sample: wpa
wpaEncryptionMode: wpa_encryption_mode:
description: Enabled WPA versions. description: Enabled WPA versions.
returned: success returned: success
type: str type: str
sample: WPA2 only sample: WPA2 only
ipAssignmentMode: ip_assignment_mode:
description: Wireless client IP assignment method. description: Wireless client IP assignment method.
returned: success returned: success
type: str type: str
sample: NAT mode sample: NAT mode
minBitrate: min_bitrate:
description: Minimum bitrate a wireless client can connect at. description: Minimum bitrate a wireless client can connect at.
returned: success returned: success
type: int type: int
sample: 11 sample: 11
bandSelection: band_selection:
description: Wireless RF frequency wireless network will be broadcast on. description: Wireless RF frequency wireless network will be broadcast on.
returned: success returned: success
type: str type: str
sample: 5 GHz band only sample: 5 GHz band only
perClientBandwidthLimitUp: per_client_bandwidth_limit_up:
description: Maximum upload bandwidth a client can use. description: Maximum upload bandwidth a client can use.
returned: success returned: success
type: int type: int
sample: 1000 sample: 1000
perClientBandwidthLimitDown: per_client_bandwidth_limit_down:
description: Maximum download bandwidth a client can use. description: Maximum download bandwidth a client can use.
returned: success returned: success
type: int type: int

View file

@ -192,7 +192,7 @@ data:
returned: success returned: success
type: bool type: bool
sample: true sample: true
poeEnabled: poe_enabled:
description: Power Over Ethernet enabled state of port. description: Power Over Ethernet enabled state of port.
returned: success returned: success
type: bool type: bool
@ -207,32 +207,32 @@ data:
returned: success returned: success
type: int type: int
sample: 10 sample: 10
voiceVlan: voice_vlan:
description: VLAN assigned to port with voice VLAN enabled devices. description: VLAN assigned to port with voice VLAN enabled devices.
returned: success returned: success
type: int type: int
sample: 20 sample: 20
isolationEnabled: isolation_enabled:
description: Port isolation status of port. description: Port isolation status of port.
returned: success returned: success
type: bool type: bool
sample: true sample: true
rstpEnabled: rstp_enabled:
description: Enabled or disabled state of Rapid Spanning Tree Protocol (RSTP) description: Enabled or disabled state of Rapid Spanning Tree Protocol (RSTP)
returned: success returned: success
type: bool type: bool
sample: true sample: true
stpGuard: stp_guard:
description: State of STP guard description: State of STP guard
returned: success returned: success
type: str type: str
sample: "Root Guard" sample: "Root Guard"
accessPolicyNumber: access_policy_number:
description: Number of assigned access policy. Only applicable to access ports. description: Number of assigned access policy. Only applicable to access ports.
returned: success returned: success
type: int type: int
sample: 1234 sample: 1234
linkNegotiation: link_negotiation:
description: Link speed for the port. description: Link speed for the port.
returned: success returned: success
type: str type: str

View file

@ -138,7 +138,7 @@ response:
returned: success returned: success
type: complex type: complex
contains: contains:
applianceIp: appliance_ip:
description: IP address of Meraki appliance in the VLAN description: IP address of Meraki appliance in the VLAN
returned: success returned: success
type: str type: str
@ -148,7 +148,7 @@ response:
returned: success returned: success
type: str type: str
sample: upstream_dns sample: upstream_dns
fixedIpAssignments: fixed_ip_assignments:
description: List of MAC addresses which have IP addresses assigned. description: List of MAC addresses which have IP addresses assigned.
returned: success returned: success
type: complex type: complex
@ -168,7 +168,7 @@ response:
returned: success returned: success
type: str type: str
sample: fixed_ip sample: fixed_ip
reservedIpRanges: reserved_ip_ranges:
description: List of IP address ranges which are reserved for static assignment. description: List of IP address ranges which are reserved for static assignment.
returned: success returned: success
type: complex type: complex
@ -208,32 +208,32 @@ response:
returned: success returned: success
type: str type: str
sample: "192.0.1.0/24" sample: "192.0.1.0/24"
dhcpHandling: dhcp_handling:
description: Status of DHCP server on VLAN. description: Status of DHCP server on VLAN.
returned: success returned: success
type: str type: str
sample: Run a DHCP server sample: Run a DHCP server
dhcpLeaseTime: dhcp_lease_time:
description: DHCP lease time when server is active. description: DHCP lease time when server is active.
returned: success returned: success
type: str type: str
sample: 1 day sample: 1 day
dhcpBootOptionsEnabled: dhcp_boot_options_enabled:
description: Whether DHCP boot options are enabled. description: Whether DHCP boot options are enabled.
returned: success returned: success
type: bool type: bool
sample: no sample: no
dhcpBootNextServer: dhcp_boot_next_server:
description: DHCP boot option to direct boot clients to the server to load the boot file from. description: DHCP boot option to direct boot clients to the server to load the boot file from.
returned: success returned: success
type: str type: str
sample: 192.0.1.2 sample: 192.0.1.2
dhcpBootFilename: dhcp_boot_filename:
description: Filename for boot file. description: Filename for boot file.
returned: success returned: success
type: str type: str
sample: boot.txt sample: boot.txt
dhcpOptions: dhcp_options:
description: DHCP options. description: DHCP options.
returned: success returned: success
type: complex type: complex

View file

@ -10,6 +10,8 @@ class ModuleDocFragment(object):
notes: notes:
- More information about the Meraki API can be found at U(https://dashboard.meraki.com/api_docs). - More information about the Meraki API can be found at U(https://dashboard.meraki.com/api_docs).
- Some of the options are likely only used for developers within Meraki. - Some of the options are likely only used for developers within Meraki.
- As of Ansible 2.9, Meraki modules output keys as snake case. To use camel case, set the C(ANSIBLE_MERAKI_FORMAT) environment variable to C(camelcase).
- Ansible's Meraki modules will stop supporting camel case output in Ansible 2.13. Please update your playbooks.
options: options:
auth_key: auth_key:
description: description:
@ -32,6 +34,12 @@ options:
- Only useful for internal Meraki developers. - Only useful for internal Meraki developers.
type: bool type: bool
default: yes default: yes
output_format:
description:
- Instructs module whether response keys should be snake case (ex. C(net_id)) or camel case (ex. C(netId)).
type: str
choices: [snakecase, camelcase]
default: snakecase
output_level: output_level:
description: description:
- Set amount of debug output during module execution. - Set amount of debug output during module execution.

View file

@ -49,7 +49,7 @@
- assert: - assert:
that: that:
- single_allowed_check.data.allowedUrlPatterns | length == 1 - single_allowed_check.data.allowed_url_patterns | length == 1
- single_allowed_check is changed - single_allowed_check is changed
- name: Set single allowed URL pattern - name: Set single allowed URL pattern
@ -64,7 +64,7 @@
- assert: - assert:
that: that:
- single_allowed.data.allowedUrlPatterns | length == 1 - single_allowed.data.allowed_url_patterns | length == 1
- name: Set single allowed URL pattern for idempotency with check mode - name: Set single allowed URL pattern for idempotency with check mode
meraki_content_filtering: meraki_content_filtering:
@ -83,6 +83,7 @@
- assert: - assert:
that: that:
- single_allowed_idempotent_check is not changed - single_allowed_idempotent_check is not changed
- single_allowed.data.allowed_url_patterns | length == 1
- name: Set single allowed URL pattern for idempotency - name: Set single allowed URL pattern for idempotency
meraki_content_filtering: meraki_content_filtering:
@ -117,7 +118,7 @@
- assert: - assert:
that: that:
- single_blocked.data.blockedUrlPatterns | length == 1 - single_blocked.data.blocked_url_patterns | length == 1
- name: Set two allowed URL pattern - name: Set two allowed URL pattern
meraki_content_filtering: meraki_content_filtering:
@ -136,7 +137,7 @@
- assert: - assert:
that: that:
- two_allowed.changed == True - two_allowed.changed == True
- two_allowed.data.allowedUrlPatterns | length == 2 - two_allowed.data.allowed_url_patterns | length == 2
- name: Set blocked URL category - name: Set blocked URL category
meraki_content_filtering: meraki_content_filtering:
@ -155,8 +156,8 @@
- assert: - assert:
that: that:
- blocked_category.changed == True - blocked_category.changed == True
- blocked_category.data.blockedUrlCategories | length == 1 - blocked_category.data.blocked_url_categories | length == 1
- blocked_category.data.urlCategoryListSize == "fullList" - blocked_category.data.url_category_list_size == "fullList"
- name: Set blocked URL category with top sites - name: Set blocked URL category with top sites
meraki_content_filtering: meraki_content_filtering:
@ -175,8 +176,8 @@
- assert: - assert:
that: that:
- blocked_category.changed == True - blocked_category.changed == True
- blocked_category.data.blockedUrlCategories | length == 1 - blocked_category.data.blocked_url_categories | length == 1
- blocked_category.data.urlCategoryListSize == "topSites" - blocked_category.data.url_category_list_size == "topSites"
always: always:
- name: Reset policies - name: Reset policies

View file

@ -81,7 +81,7 @@
- assert: - assert:
that: that:
- create_one.data|length == 2 - create_one.data|length == 2
- create_one.data.0.destCidr == '192.0.1.1/32' - create_one.data.0.dest_cidr == '192.0.1.1/32'
- create_one.data.0.protocol == 'tcp' - create_one.data.0.protocol == 'tcp'
- create_one.data.0.policy == 'deny' - create_one.data.0.policy == 'deny'
- create_one.changed == True - create_one.changed == True
@ -165,7 +165,7 @@
- assert: - assert:
that: that:
- query.data.1.syslogEnabled == True - query.data.1.syslog_enabled == True
- default_syslog.changed == True - default_syslog.changed == True
- name: Disable syslog for default rule - name: Disable syslog for default rule
@ -207,7 +207,7 @@
- assert: - assert:
that: that:
- query.data.1.syslogEnabled == False - query.data.1.syslog_enabled == False
- disable_syslog.changed == True - disable_syslog.changed == True
always: always:

View file

@ -198,7 +198,7 @@
- assert: - assert:
that: that:
- disable_remote_status.data.disableRemoteStatusPage == False - disable_remote_status.data.disable_remote_status_page == False
- name: Disable remote status page - name: Disable remote status page
meraki_network: meraki_network:
@ -215,7 +215,7 @@
- assert: - assert:
that: that:
- enable_remote_status.data.disableRemoteStatusPage == True - enable_remote_status.data.disable_remote_status_page == True
- name: Test status pages are mutually exclusive when on - name: Test status pages are mutually exclusive when on
meraki_network: meraki_network:
@ -300,15 +300,15 @@
assert: assert:
that: that:
- create_net_combined.data.type == 'combined' - create_net_combined.data.type == 'combined'
- create_net_combined.data.disableMyMerakiCom == True - create_net_combined.data.disable_my_meraki_com == True
- enable_meraki_com.data.disableMyMerakiCom == False - enable_meraki_com.data.disable_my_meraki_com == False
- '"org_name or org_id parameters are required" in create_net_no_org.msg' - '"org_name or org_id parameters are required" in create_net_no_org.msg'
- '"IntTestNetworkAppliance" in create_net_appliance_no_tz.data.name' - '"IntTestNetworkAppliance" in create_net_appliance_no_tz.data.name'
- create_net_appliance_no_tz.changed == True - create_net_appliance_no_tz.changed == True
- '"IntTestNetworkSwitch" in create_net_switch.data.name' - '"IntTestNetworkSwitch" in create_net_switch.data.name'
- '"IntTestNetworkSwitchOrgID" in create_net_switch_org_id.data.name' - '"IntTestNetworkSwitchOrgID" in create_net_switch_org_id.data.name'
- '"IntTestNetworkWireless" in create_net_wireless.data.name' - '"IntTestNetworkWireless" in create_net_wireless.data.name'
- create_net_wireless.data.disableMyMerakiCom == True - create_net_wireless.data.disable_my_meraki_com == True
- create_net_wireless_idempotent.changed == False - create_net_wireless_idempotent.changed == False
- create_net_wireless_idempotent.data is defined - create_net_wireless_idempotent.data is defined
- '"first_tag" in create_net_tag.data.tags' - '"first_tag" in create_net_tag.data.tags'

View file

@ -33,8 +33,8 @@
- assert: - assert:
that: that:
- snmp_v2_enable.data.v2CommunityString is defined - snmp_v2_enable.data.v2_community_string is defined
- snmp_v2_enable.data.v2cEnabled == true - snmp_v2_enable.data.v2c_enabled == true
- name: Disable SNMPv2c - name: Disable SNMPv2c
meraki_snmp: meraki_snmp:
@ -47,8 +47,8 @@
- assert: - assert:
that: that:
- snmp_v2_disable.data.v2CommunityString is not defined - snmp_v2_disable.data.v2_community_string is not defined
- snmp_v2_disable.data.v2cEnabled == False - snmp_v2_disable.data.v2c_enabled == False
- name: Enable SNMPv2c with org_id - name: Enable SNMPv2c with org_id
meraki_snmp: meraki_snmp:
@ -64,8 +64,8 @@
- assert: - assert:
that: that:
- snmp_v2_enable_id.data.v2CommunityString is defined - snmp_v2_enable_id.data.v2_community_string is defined
- snmp_v2_enable_id.data.v2cEnabled == true - snmp_v2_enable_id.data.v2c_enabled == true
- name: Disable SNMPv2c with org_id - name: Disable SNMPv2c with org_id
meraki_snmp: meraki_snmp:
@ -78,8 +78,8 @@
- assert: - assert:
that: that:
- snmp_v2_disable_id.data.v2CommunityString is not defined - snmp_v2_disable_id.data.v2_community_string is not defined
- snmp_v2_disable_id.data.v2cEnabled == False - snmp_v2_disable_id.data.v2c_enabled == False
- name: Enable SNMPv3 - name: Enable SNMPv3
meraki_snmp: meraki_snmp:
@ -96,7 +96,7 @@
- assert: - assert:
that: that:
- snmp_v3_enable.data.v3Enabled == True - snmp_v3_enable.data.v3_enabled == True
- snmp_v3_enable.changed == True - snmp_v3_enable.changed == True
- name: Check for idempotency - name: Check for idempotency
@ -139,7 +139,7 @@
- assert: - assert:
that: that:
- peers.data.peerIps is defined - peers.data.peer_ips is defined
- name: Add invalid peer IPs - name: Add invalid peer IPs
meraki_snmp: meraki_snmp:

View file

@ -229,9 +229,9 @@
- assert: - assert:
that: that:
- psk.data.authMode == 'psk' - psk.data.auth_mode == 'psk'
- psk.data.encryptionMode == 'wpa' - psk.data.encryption_mode == 'wpa'
- psk.data.wpaEncryptionMode == 'WPA2 only' - psk.data.wpa_encryption_mode == 'WPA2 only'
- name: Set PSK with idempotency - name: Set PSK with idempotency
meraki_ssid: meraki_ssid:
@ -269,7 +269,7 @@
- assert: - assert:
that: that:
- splash_click.data.splashPage == 'Click-through splash page' - splash_click.data.splash_page == 'Click-through splash page'
- name: Configure RADIUS servers - name: Configure RADIUS servers
meraki_ssid: meraki_ssid:
@ -291,7 +291,7 @@
- assert: - assert:
that: that:
- set_radius_server.data.radiusServers.0.host == '192.0.1.200' - set_radius_server.data.radius_servers.0.host == '192.0.1.200'
- name: Configure RADIUS servers with idempotency - name: Configure RADIUS servers with idempotency
meraki_ssid: meraki_ssid:

View file

@ -194,7 +194,7 @@
- assert: - assert:
that: that:
- update_port_vvlan.data.voiceVlan == 11 - update_port_vvlan.data.voice_vlan == 11
- update_port_vvlan.changed == True - update_port_vvlan.changed == True
- name: Check access port for idempotenty - name: Check access port for idempotenty
@ -242,7 +242,7 @@
that: that:
- update_trunk.data.tags == 'server' - update_trunk.data.tags == 'server'
- update_trunk.data.type == 'trunk' - update_trunk.data.type == 'trunk'
- update_trunk.data.allowedVlans == 'all' - update_trunk.data.allowed_vlans == 'all'
- name: Configure trunk port with specific VLANs - name: Configure trunk port with specific VLANs
meraki_switchport: meraki_switchport:
@ -269,7 +269,7 @@
that: that:
- update_trunk.data.tags == 'server' - update_trunk.data.tags == 'server'
- update_trunk.data.type == 'trunk' - update_trunk.data.type == 'trunk'
- update_trunk.data.allowedVlans == '8,10,15,20' - update_trunk.data.allowed_vlans == '8,10,15,20'
- name: Configure trunk port with specific VLANs and native VLAN - name: Configure trunk port with specific VLANs and native VLAN
meraki_switchport: meraki_switchport:
@ -296,7 +296,7 @@
that: that:
- update_trunk.data.tags == 'server' - update_trunk.data.tags == 'server'
- update_trunk.data.type == 'trunk' - update_trunk.data.type == 'trunk'
- update_trunk.data.allowedVlans == '2,10,15,20' - update_trunk.data.allowed_vlans == '2,10,15,20'
- name: Check for idempotency on trunk port - name: Check for idempotency on trunk port
meraki_switchport: meraki_switchport:

View file

@ -20,7 +20,7 @@
register: invalid_domain register: invalid_domain
ignore_errors: yes ignore_errors: yes
- name: Disable HTTP - name: Disable HTTPS
meraki_vlan: meraki_vlan:
auth_key: '{{ auth_key }}' auth_key: '{{ auth_key }}'
use_https: false use_https: false
@ -101,6 +101,8 @@
appliance_ip: 192.168.250.1 appliance_ip: 192.168.250.1
delegate_to: localhost delegate_to: localhost
register: create_vlan register: create_vlan
environment:
ANSIBLE_MERAKI_FORMAT: camelcase
- debug: - debug:
msg: '{{create_vlan}}' msg: '{{create_vlan}}'
@ -109,6 +111,7 @@
that: that:
- create_vlan.data.id == 2 - create_vlan.data.id == 2
- create_vlan.changed == True - create_vlan.changed == True
- create_vlan.data.networkId is defined
- name: Update VLAN with check mode - name: Update VLAN with check mode
meraki_vlan: meraki_vlan:
@ -167,7 +170,7 @@
- assert: - assert:
that: that:
- update_vlan.data.applianceIp == '192.168.250.2' - update_vlan.data.appliance_ip == '192.168.250.2'
- update_vlan.changed == True - update_vlan.changed == True
- name: Update VLAN with idempotency and check mode - name: Update VLAN with idempotency and check mode
@ -264,8 +267,8 @@
- assert: - assert:
that: that:
- update_vlan_add_ip.changed == True - update_vlan_add_ip.changed == True
- update_vlan_add_ip.data.fixedIpAssignments | length == 2 - update_vlan_add_ip.data.fixed_ip_assignments | length == 2
- update_vlan_add_ip.data.reservedIpRanges | length == 2 - update_vlan_add_ip.data.reserved_ip_ranges | length == 2
- name: Remove IP assignments and reserved IP ranges - name: Remove IP assignments and reserved IP ranges
meraki_vlan: meraki_vlan:
@ -295,8 +298,8 @@
- assert: - assert:
that: that:
- update_vlan_remove_ip.changed == True - update_vlan_remove_ip.changed == True
- update_vlan_remove_ip.data.fixedIpAssignments | length == 1 - update_vlan_remove_ip.data.fixed_ip_assignments | length == 1
- update_vlan_remove_ip.data.reservedIpRanges | length == 1 - update_vlan_remove_ip.data.reserved_ip_ranges | length == 1
- name: Update VLAN with idempotency - name: Update VLAN with idempotency
meraki_vlan: meraki_vlan:
@ -355,7 +358,7 @@
- assert: - assert:
that: that:
- '"1.1.1.1" in update_vlan_dns_list.data.dnsNameservers' - '"1.1.1.1" in update_vlan_dns_list.data.dns_nameservers'
- update_vlan_dns_list.changed == True - update_vlan_dns_list.changed == True
- name: Query all VLANs in network - name: Query all VLANs in network