mirror of
https://github.com/ansible-collections/community.general.git
synced 2024-09-14 20:13:21 +02:00
New module - meraki_ssid (#42329)
* Initial commit of meraki_ssid module - CRUD functionality for Meraki wireless SSIDs - Much more testing is needed - Module is not currently idempotent * Improve integration tests - Original integration tests didn't have any assertions in it - Single bug fix in module found via integration test * Added idempotency support - Changes are only made when needed. - Added integration test to check for idempotency. - Relies on a forthcoming PR to make idempotency check a single pass. * Improved documentation
This commit is contained in:
parent
132943cac5
commit
9cd2388d1a
3 changed files with 723 additions and 0 deletions
440
lib/ansible/modules/network/meraki/meraki_ssid.py
Normal file
440
lib/ansible/modules/network/meraki/meraki_ssid.py
Normal file
|
@ -0,0 +1,440 @@
|
||||||
|
#!/usr/bin/python
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
# Copyright: (c) 2018, Kevin Breit (@kbreit) <kevin.breit@kevinbreit.net>
|
||||||
|
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||||
|
|
||||||
|
from __future__ import absolute_import, division, print_function
|
||||||
|
__metaclass__ = type
|
||||||
|
|
||||||
|
ANSIBLE_METADATA = {
|
||||||
|
'metadata_version': '1.1',
|
||||||
|
'status': ['preview'],
|
||||||
|
'supported_by': 'community'
|
||||||
|
}
|
||||||
|
|
||||||
|
DOCUMENTATION = r'''
|
||||||
|
---
|
||||||
|
module: meraki_ssid
|
||||||
|
short_description: Manage wireless SSIDs in the Meraki cloud
|
||||||
|
version_added: "2.7"
|
||||||
|
description:
|
||||||
|
- Allows for management of SSIDs in a Meraki wireless environment.
|
||||||
|
notes:
|
||||||
|
- Deleting an SSID does not delete RADIUS servers.
|
||||||
|
options:
|
||||||
|
state:
|
||||||
|
description:
|
||||||
|
- Specifies whether SNMP information should be queried or modified.
|
||||||
|
choices: ['absent', 'query', 'present']
|
||||||
|
default: present
|
||||||
|
number:
|
||||||
|
description:
|
||||||
|
- SSID number within network.
|
||||||
|
aliases: [ssid_number]
|
||||||
|
name:
|
||||||
|
description:
|
||||||
|
- Name of SSID.
|
||||||
|
org_name:
|
||||||
|
description:
|
||||||
|
- Name of organization.
|
||||||
|
org_id:
|
||||||
|
description:
|
||||||
|
- ID of organization.
|
||||||
|
net_name:
|
||||||
|
description:
|
||||||
|
- Name of network.
|
||||||
|
net_id:
|
||||||
|
description:
|
||||||
|
- ID of network.
|
||||||
|
enabled:
|
||||||
|
description:
|
||||||
|
- Enable or disable SSID network.
|
||||||
|
type: bool
|
||||||
|
auth_mode:
|
||||||
|
description:
|
||||||
|
- Set authentication mode of network.
|
||||||
|
choices: [open, psk, open-with-radius, 8021x-meraki, 8021x-radius]
|
||||||
|
encryption_mode:
|
||||||
|
description:
|
||||||
|
- Set encryption mode of network.
|
||||||
|
choices: [wpa, eap, wpa-eap]
|
||||||
|
psk:
|
||||||
|
description:
|
||||||
|
- Password for wireless network.
|
||||||
|
- Requires auth_mode to be set to psk.
|
||||||
|
wpa_encryption_mode:
|
||||||
|
description:
|
||||||
|
- Encryption mode within WPA2 specification.
|
||||||
|
choices: [WPA1 and WPA2, WPA2 only]
|
||||||
|
splash_page:
|
||||||
|
description:
|
||||||
|
- Set to enable splash page and specify type of splash.
|
||||||
|
choices: ['None',
|
||||||
|
'Click-through splash page',
|
||||||
|
'Billing',
|
||||||
|
'Password-protected with Meraki RADIUS',
|
||||||
|
'Password-protected with custom RADIUS',
|
||||||
|
'Password-protected with Active Directory',
|
||||||
|
'Password-protected with LDAP',
|
||||||
|
'SMS authentication',
|
||||||
|
'Systems Manager Sentry',
|
||||||
|
'Facebook Wi-Fi',
|
||||||
|
'Google OAuth',
|
||||||
|
'Sponsored guest']
|
||||||
|
radius_servers:
|
||||||
|
description:
|
||||||
|
- List of RADIUS servers.
|
||||||
|
suboptions:
|
||||||
|
host:
|
||||||
|
description:
|
||||||
|
- IP addres or hostname of RADIUS server.
|
||||||
|
port:
|
||||||
|
description:
|
||||||
|
- Port number RADIUS server is listening to.
|
||||||
|
secret:
|
||||||
|
description:
|
||||||
|
- RADIUS password.
|
||||||
|
radius_coa_enabled:
|
||||||
|
description:
|
||||||
|
- Enable or disable RADIUS CoA (Change of Authorization) on SSID.
|
||||||
|
type: bool
|
||||||
|
radius_failover_policy:
|
||||||
|
description:
|
||||||
|
- Set client access policy in case RADIUS servers aren't available.
|
||||||
|
choices: [Deny access, Allow access]
|
||||||
|
radius_load_balancing_policy:
|
||||||
|
description:
|
||||||
|
- Set load balancing policy when multiple RADIUS servers are specified.
|
||||||
|
choices: [Strict priority order, Round robin]
|
||||||
|
radius_accounting_enabled:
|
||||||
|
description:
|
||||||
|
- Enable or disable RADIUS accounting.
|
||||||
|
type: bool
|
||||||
|
radius_accounting_servers:
|
||||||
|
description:
|
||||||
|
- List of RADIUS servers for RADIUS accounting.
|
||||||
|
suboptions:
|
||||||
|
host:
|
||||||
|
description:
|
||||||
|
- IP addres or hostname of RADIUS server.
|
||||||
|
port:
|
||||||
|
description:
|
||||||
|
- Port number RADIUS server is listening to.
|
||||||
|
secret:
|
||||||
|
description:
|
||||||
|
- RADIUS password.
|
||||||
|
ip_assignment_mode:
|
||||||
|
description:
|
||||||
|
- Method of which SSID uses to assign IP addresses.
|
||||||
|
choices: ['NAT mode',
|
||||||
|
'Bridge mode',
|
||||||
|
'Layer 3 roaming',
|
||||||
|
'Layer 3 roaming with a concentrator',
|
||||||
|
'VPN']
|
||||||
|
use_vlan_tagging:
|
||||||
|
description:
|
||||||
|
- Set whether to use VLAN tagging.
|
||||||
|
type: bool
|
||||||
|
default_vlan_id:
|
||||||
|
description:
|
||||||
|
- Default VLAN ID.
|
||||||
|
vlan_id:
|
||||||
|
description:
|
||||||
|
- ID number of VLAN on SSID.
|
||||||
|
ap_tags_vlan_ids:
|
||||||
|
description:
|
||||||
|
- List of VLAN tags.
|
||||||
|
suboptions:
|
||||||
|
tags:
|
||||||
|
description:
|
||||||
|
- List of AP tags.
|
||||||
|
vlan_id:
|
||||||
|
description:
|
||||||
|
- Numerical identifier that is assigned to the VLAN.
|
||||||
|
walled_garden_enabled:
|
||||||
|
description:
|
||||||
|
- Enable or disable walled garden functionality.
|
||||||
|
type: bool
|
||||||
|
walled_garden_ranges:
|
||||||
|
description:
|
||||||
|
- List of walled garden ranges.
|
||||||
|
min_bitrate:
|
||||||
|
description:
|
||||||
|
- Minimum bitrate (Mbps) allowed on SSID.
|
||||||
|
choices: [1, 2, 5.5, 6, 9, 11, 12, 18, 24, 36, 48, 54]
|
||||||
|
band_selection:
|
||||||
|
description:
|
||||||
|
- Set band selection mode.
|
||||||
|
choices: ['Dual band operation', '5 GHz band only', 'Dual band operation with Band Steering']
|
||||||
|
per_client_bandwidth_limit_up:
|
||||||
|
description:
|
||||||
|
- Maximum bandwidth in Mbps devices on SSID can upload.
|
||||||
|
per_client_bandwidth_limit_down:
|
||||||
|
description:
|
||||||
|
- Maximum bandwidth in Mbps devices on SSID can download.
|
||||||
|
concentrator_network_id:
|
||||||
|
description:
|
||||||
|
- The concentrator to use for 'Layer 3 roaming with a concentrator' or 'VPN'.
|
||||||
|
author:
|
||||||
|
- Kevin Breit (@kbreit)
|
||||||
|
extends_documentation_fragment: meraki
|
||||||
|
'''
|
||||||
|
|
||||||
|
EXAMPLES = r'''
|
||||||
|
'''
|
||||||
|
|
||||||
|
RETURN = r'''
|
||||||
|
data:
|
||||||
|
description: Information about queried or updated object.
|
||||||
|
type: list
|
||||||
|
returned: info
|
||||||
|
sample:
|
||||||
|
"data": {
|
||||||
|
|
||||||
|
}
|
||||||
|
'''
|
||||||
|
|
||||||
|
import os
|
||||||
|
from ansible.module_utils.basic import AnsibleModule, json, env_fallback
|
||||||
|
from ansible.module_utils.urls import fetch_url
|
||||||
|
from ansible.module_utils._text import to_native
|
||||||
|
from ansible.module_utils.network.meraki.meraki import MerakiModule, meraki_argument_spec
|
||||||
|
|
||||||
|
|
||||||
|
def get_available_number(data):
|
||||||
|
for item in data:
|
||||||
|
if 'Unconfigured SSID' in item['name']:
|
||||||
|
return item['number']
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
def get_ssid_number(name, data):
|
||||||
|
for ssid in data:
|
||||||
|
if name == ssid['name']:
|
||||||
|
return ssid['number']
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
def get_ssids(meraki, net_id):
|
||||||
|
path = meraki.construct_path('get_all', net_id=net_id)
|
||||||
|
return meraki.request(path, method='GET')
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
|
||||||
|
param_map = {'name': 'name',
|
||||||
|
'enabled': 'enabled',
|
||||||
|
'authMode': 'auth_mode',
|
||||||
|
'encryptionMode': 'encryption_mode',
|
||||||
|
'psk': 'psk',
|
||||||
|
'wpaEncryptionMode': 'wpa_encryption_mode',
|
||||||
|
'splashPage': 'splash_page',
|
||||||
|
'radiusServers': 'radius_servers',
|
||||||
|
'radiusCoaEnabled': 'radius_coa_enabled',
|
||||||
|
'radiusFailoverPolicy': 'radius_failover_policy',
|
||||||
|
'radiusLoadBalancingPolicy': 'radius_load_balancing_policy',
|
||||||
|
'radiusAccountingEnabled': 'radius_accounting_enabled',
|
||||||
|
'radiusAccountingServers': 'radius_accounting_servers',
|
||||||
|
'ipAssignmentMode': 'ip_assignment_mode',
|
||||||
|
'useVlanTagging': 'use_vlan_tagging',
|
||||||
|
'concentratorNetworkId': 'concentrator_network_id',
|
||||||
|
'vlanId': 'vlan_id',
|
||||||
|
'defaultVlanId': 'default_vlan_id',
|
||||||
|
'apTagsAndVlanIds': 'ap_tags_vlan_ids',
|
||||||
|
'walledGardenEnabled': 'walled_garden_enabled',
|
||||||
|
'walledGardenRanges': 'walled_garden_ranges',
|
||||||
|
'minBitrate': 'min_bitrate',
|
||||||
|
'bandSelection': 'band_selection',
|
||||||
|
'perClientBandwidthLimitUp': 'per_client_bandwidth_limit_up',
|
||||||
|
'perClientBandwidthLimitDown': 'per_client_bandwidth_limit_down',
|
||||||
|
}
|
||||||
|
|
||||||
|
default_payload = {'name': 'Unconfigured SSID',
|
||||||
|
'auth_mode': 'open',
|
||||||
|
'splashPage': 'None',
|
||||||
|
'perClientBandwidthLimitUp': 0,
|
||||||
|
'perClientBandwidthLimitDown': 0,
|
||||||
|
'ipAssignmentMode': 'NAT mode',
|
||||||
|
'enabled': False,
|
||||||
|
'bandSelection': 'Dual band operation',
|
||||||
|
'minBitrate': 11,
|
||||||
|
}
|
||||||
|
|
||||||
|
# define the available arguments/parameters that a user can pass to
|
||||||
|
# the module
|
||||||
|
radius_arg_spec = dict(host=dict(type='str', required=True),
|
||||||
|
port=dict(type='int'),
|
||||||
|
secret=dict(type='str', no_log=True),
|
||||||
|
)
|
||||||
|
vlan_arg_spec = dict(tags=dict(type='list'),
|
||||||
|
vlan_id=dict(type='int'),
|
||||||
|
)
|
||||||
|
|
||||||
|
argument_spec = meraki_argument_spec()
|
||||||
|
argument_spec.update(state=dict(type='str', choices=['absent', 'present', 'query'], default='present'),
|
||||||
|
number=dict(type='int', aliases=['ssid_number']),
|
||||||
|
name=dict(type='str'),
|
||||||
|
org_name=dict(type='str', aliases=['organization']),
|
||||||
|
org_id=dict(type='int'),
|
||||||
|
net_name=dict(type='str'),
|
||||||
|
net_id=dict(type='str'),
|
||||||
|
enabled=dict(type='bool'),
|
||||||
|
auth_mode=dict(type='str', choices=['open', 'psk', 'open-with-radius', '8021x-meraki', '8021x-radius']),
|
||||||
|
encryption_mode=dict(type='str', choices=['wpa', 'eap', 'wpa-eap']),
|
||||||
|
psk=dict(type='str', no_log=True),
|
||||||
|
wpa_encryption_mode=dict(type='str', choices=['WPA1 and WPA2', 'WPA2 only']),
|
||||||
|
splash_page=dict(type='str', choices=['None',
|
||||||
|
'Click-through splash page',
|
||||||
|
'Billing',
|
||||||
|
'Password-protected with Meraki RADIUS',
|
||||||
|
'Password-protected with custom RADIUS',
|
||||||
|
'Password-protected with Active Directory',
|
||||||
|
'Password-protected with LDAP',
|
||||||
|
'SMS authentication',
|
||||||
|
'Systems Manager Sentry',
|
||||||
|
'Facebook Wi-Fi',
|
||||||
|
'Google OAuth',
|
||||||
|
'Sponsored guest']),
|
||||||
|
radius_servers=dict(type='list', default=None, element='dict', options=radius_arg_spec),
|
||||||
|
radius_coa_enabled=dict(type='bool'),
|
||||||
|
radius_failover_policy=dict(type='str', choices=['Deny access', 'Allow access']),
|
||||||
|
radius_load_balancing_policy=dict(type='str', choices=['Strict priority order', 'Round robin']),
|
||||||
|
radius_accounting_enabled=dict(type='bool'),
|
||||||
|
radius_accounting_servers=dict(type='list', element='dict', options=radius_arg_spec),
|
||||||
|
ip_assignment_mode=dict(type='str', choices=['NAT mode',
|
||||||
|
'Bridge mode',
|
||||||
|
'Layer 3 roaming',
|
||||||
|
'Layer 3 roaming with a concentrator',
|
||||||
|
'VPN']),
|
||||||
|
use_vlan_tagging=dict(type='bool'),
|
||||||
|
concentrator_network_id=dict(type='str'),
|
||||||
|
vlan_id=dict(type='int'),
|
||||||
|
default_vlan_id=dict(type='int'),
|
||||||
|
ap_tags_vlan_ids=dict(type='list', default=None, element='dict', options=vlan_arg_spec),
|
||||||
|
walled_garden_enabled=dict(type='bool'),
|
||||||
|
walled_garden_ranges=dict(type='list'),
|
||||||
|
min_bitrate=dict(type='float', choices=[1, 2, 5.5, 6, 9, 11, 12, 18, 24, 36, 48, 54]),
|
||||||
|
band_selection=dict(type='str', choices=['Dual band operation',
|
||||||
|
'5 GHz band only',
|
||||||
|
'Dual band operation with Band Steering']),
|
||||||
|
per_client_bandwidth_limit_up=dict(type='int'),
|
||||||
|
per_client_bandwidth_limit_down=dict(type='int'),
|
||||||
|
)
|
||||||
|
|
||||||
|
# seed the result dict in the object
|
||||||
|
# we primarily care about changed and state
|
||||||
|
# change is if this module effectively modified the target
|
||||||
|
# state will include any data that you want your module to pass back
|
||||||
|
# for consumption, for example, in a subsequent task
|
||||||
|
result = dict(
|
||||||
|
changed=False,
|
||||||
|
)
|
||||||
|
# the AnsibleModule object will be our abstraction working with Ansible
|
||||||
|
# this includes instantiation, a couple of common attr would be the
|
||||||
|
# args/params passed to the execution, as well as if the module
|
||||||
|
# supports check mode
|
||||||
|
module = AnsibleModule(argument_spec=argument_spec,
|
||||||
|
supports_check_mode=True,
|
||||||
|
)
|
||||||
|
meraki = MerakiModule(module, function='ssid')
|
||||||
|
meraki.params['follow_redirects'] = 'all'
|
||||||
|
|
||||||
|
query_urls = {'ssid': '/networks/{net_id}/ssids'}
|
||||||
|
query_url = {'ssid': 'networks/{net_id}/ssids/'}
|
||||||
|
update_url = {'ssid': 'networks/{net_id}/ssids/'}
|
||||||
|
|
||||||
|
meraki.url_catalog['get_all'].update(query_urls)
|
||||||
|
meraki.url_catalog['get_one'].update(query_url)
|
||||||
|
meraki.url_catalog['update'] = update_url
|
||||||
|
|
||||||
|
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
|
||||||
|
if meraki.params['psk']:
|
||||||
|
if meraki.params['auth_mode'] != 'psk':
|
||||||
|
meraki.fail_json(msg='PSK is only allowed when auth_mode is set to psk')
|
||||||
|
if meraki.params['encryption_mode'] != 'wpa':
|
||||||
|
meraki.fail_json(msg='PSK requires encryption_mode be set to wpa')
|
||||||
|
if meraki.params['radius_servers']:
|
||||||
|
if meraki.params['auth_mode'] not in ('open-with-radius', '8021x-radius'):
|
||||||
|
meraki.fail_json(msg='radius_servers requires auth_mode to be open-with-radius or 8021x-radius')
|
||||||
|
if meraki.params['radius_accounting_enabled'] is True:
|
||||||
|
if meraki.params['auth_mode'] not in ('open-with-radius', '8021x-radius'):
|
||||||
|
meraki.fails_json(msg='radius_accounting_enabled is only allowed when auth_mode is open-with-radius or 8021x-radius')
|
||||||
|
if meraki.params['radius_accounting_servers'] is True:
|
||||||
|
if meraki.params['auth_mode'] not in ('open-with-radius', '8021x-radius') or meraki.params['radius_accounting_enabled'] is False:
|
||||||
|
meraki.fail_json(msg='radius_accounting_servers is only allowed when auth_mode is open_with_radius or 8021x-radius and \
|
||||||
|
radius_accounting_enabled is true')
|
||||||
|
|
||||||
|
# manipulate or modify the state as needed (this is going to be the
|
||||||
|
# part where your module will do what it needs to do)
|
||||||
|
org_id = meraki.params['org_id']
|
||||||
|
net_id = meraki.params['net_id']
|
||||||
|
if org_id is None:
|
||||||
|
org_id = meraki.get_org_id(meraki.params['org_name'])
|
||||||
|
if net_id is None:
|
||||||
|
nets = meraki.get_nets(org_id=org_id)
|
||||||
|
net_id = meraki.get_net_id(org_id, meraki.params['net_name'], data=nets)
|
||||||
|
|
||||||
|
if meraki.params['state'] == 'query':
|
||||||
|
if meraki.params['name']:
|
||||||
|
ssid_id = get_ssid_number(meraki.params['name'], get_ssids(meraki, net_id))
|
||||||
|
path = meraki.construct_path('get_one', net_id=net_id) + str(ssid_id)
|
||||||
|
meraki.result['data'] = meraki.request(path, method='GET')
|
||||||
|
elif meraki.params['number']:
|
||||||
|
path = meraki.construct_path('get_one', net_id=net_id) + meraki.params['number']
|
||||||
|
meraki.result['data'] = meraki.request(path, method='GET')
|
||||||
|
else:
|
||||||
|
meraki.result['data'] = get_ssids(meraki, net_id)
|
||||||
|
elif meraki.params['state'] == 'present':
|
||||||
|
payload = dict()
|
||||||
|
for k, v in param_map.items():
|
||||||
|
if meraki.params[v] is not None:
|
||||||
|
payload[k] = meraki.params[v]
|
||||||
|
ssids = get_ssids(meraki, net_id)
|
||||||
|
original = ssids[get_ssid_number(meraki.params['name'], ssids)]
|
||||||
|
# meraki.fail_json(msg=meraki.is_update_required(original, payload), original=original, payload=payload)
|
||||||
|
if meraki.is_update_required(original, payload):
|
||||||
|
ssid_id = meraki.params['number']
|
||||||
|
if ssid_id is None: # Name should be used to lookup number
|
||||||
|
ssid_id = get_ssid_number(meraki.params['name'], ssids)
|
||||||
|
if ssid_id is False:
|
||||||
|
ssid_id = get_available_number(ssids)
|
||||||
|
if ssid_id is False:
|
||||||
|
meraki.fail_json(msg='No unconfigured SSIDs are available. Specify a number.')
|
||||||
|
path = meraki.construct_path('update', net_id=net_id) + str(ssid_id)
|
||||||
|
result = meraki.request(path, 'PUT', payload=json.dumps(payload))
|
||||||
|
meraki.result['data'] = result
|
||||||
|
meraki.result['changed'] = True
|
||||||
|
elif meraki.params['state'] == 'absent':
|
||||||
|
ssids = get_ssids(meraki, net_id)
|
||||||
|
ssid_id = meraki.params['number']
|
||||||
|
if ssid_id is None: # Name should be used to lookup number
|
||||||
|
ssid_id = get_ssid_number(meraki.params['name'], ssids)
|
||||||
|
if ssid_id is False:
|
||||||
|
ssid_id = get_available_number(ssids)
|
||||||
|
if ssid_id is False:
|
||||||
|
meraki.fail_json(msg='No SSID found by specified name and no number was referenced.')
|
||||||
|
path = meraki.construct_path('update', net_id=net_id) + str(ssid_id)
|
||||||
|
payload = default_payload
|
||||||
|
payload['name'] = payload['name'] + ' ' + str(ssid_id + 1)
|
||||||
|
# meraki.fail_json(msg='Payload', payload=payload)
|
||||||
|
result = meraki.request(path, 'PUT', payload=json.dumps(payload))
|
||||||
|
meraki.result['data'] = result
|
||||||
|
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
|
||||||
|
meraki.exit_json(**meraki.result)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
main()
|
1
test/integration/targets/meraki_ssid/aliases
Normal file
1
test/integration/targets/meraki_ssid/aliases
Normal file
|
@ -0,0 +1 @@
|
||||||
|
unsupported
|
282
test/integration/targets/meraki_ssid/tasks/main.yml
Normal file
282
test/integration/targets/meraki_ssid/tasks/main.yml
Normal file
|
@ -0,0 +1,282 @@
|
||||||
|
# Test code for the Meraki SSID 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)
|
||||||
|
---
|
||||||
|
- 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 test network
|
||||||
|
meraki_network:
|
||||||
|
auth_key: '{{auth_key}}'
|
||||||
|
state: present
|
||||||
|
org_name: '{{test_org_name}}'
|
||||||
|
net_name: TestNetSSID
|
||||||
|
type: wireless
|
||||||
|
register: test_net
|
||||||
|
|
||||||
|
- debug:
|
||||||
|
msg: '{{test_net}}'
|
||||||
|
|
||||||
|
- name: Query all SSIDs
|
||||||
|
meraki_ssid:
|
||||||
|
auth_key: '{{auth_key}}'
|
||||||
|
state: query
|
||||||
|
org_name: '{{test_org_name}}'
|
||||||
|
net_name: TestNetSSID
|
||||||
|
delegate_to: localhost
|
||||||
|
register: query_all
|
||||||
|
|
||||||
|
- debug:
|
||||||
|
msg: '{{query_all}}'
|
||||||
|
|
||||||
|
- name: Enable and name SSID
|
||||||
|
meraki_ssid:
|
||||||
|
auth_key: '{{auth_key}}'
|
||||||
|
state: present
|
||||||
|
org_name: '{{test_org_name}}'
|
||||||
|
net_name: TestNetSSID
|
||||||
|
name: AnsibleSSID
|
||||||
|
enabled: true
|
||||||
|
delegate_to: localhost
|
||||||
|
register: enable_name_ssid
|
||||||
|
|
||||||
|
- debug:
|
||||||
|
msg: '{{ enable_name_ssid }}'
|
||||||
|
|
||||||
|
- assert:
|
||||||
|
that:
|
||||||
|
- query_all.data | length == 15
|
||||||
|
- query_all.data.0.name == 'TestNetSSID WiFi'
|
||||||
|
- enable_name_ssid.data.name == 'AnsibleSSID'
|
||||||
|
|
||||||
|
- name: Check for idempotency
|
||||||
|
meraki_ssid:
|
||||||
|
auth_key: '{{auth_key}}'
|
||||||
|
state: present
|
||||||
|
org_name: '{{test_org_name}}'
|
||||||
|
net_name: TestNetSSID
|
||||||
|
name: AnsibleSSID
|
||||||
|
enabled: true
|
||||||
|
delegate_to: localhost
|
||||||
|
register: enable_name_ssid_idempotent
|
||||||
|
|
||||||
|
- debug:
|
||||||
|
msg: '{{ enable_name_ssid_idempotent }}'
|
||||||
|
|
||||||
|
- assert:
|
||||||
|
that:
|
||||||
|
- enable_name_ssid_idempotent.changed == False
|
||||||
|
|
||||||
|
- name: Query one SSIDs
|
||||||
|
meraki_ssid:
|
||||||
|
auth_key: '{{auth_key}}'
|
||||||
|
state: query
|
||||||
|
org_name: '{{test_org_name}}'
|
||||||
|
net_name: TestNetSSID
|
||||||
|
name: AnsibleSSID
|
||||||
|
delegate_to: localhost
|
||||||
|
register: query_one
|
||||||
|
|
||||||
|
- debug:
|
||||||
|
msg: '{{query_one}}'
|
||||||
|
|
||||||
|
- assert:
|
||||||
|
that:
|
||||||
|
- query_one.data.name == 'AnsibleSSID'
|
||||||
|
|
||||||
|
- name: Disable SSID without specifying number
|
||||||
|
meraki_ssid:
|
||||||
|
auth_key: '{{auth_key}}'
|
||||||
|
state: present
|
||||||
|
org_name: '{{test_org_name}}'
|
||||||
|
net_name: TestNetSSID
|
||||||
|
name: AnsibleSSID
|
||||||
|
enabled: false
|
||||||
|
delegate_to: localhost
|
||||||
|
register: disable_ssid
|
||||||
|
|
||||||
|
- debug:
|
||||||
|
msg: '{{ disable_ssid.data.enabled }}'
|
||||||
|
|
||||||
|
- assert:
|
||||||
|
that:
|
||||||
|
- disable_ssid.data.enabled == False
|
||||||
|
|
||||||
|
- name: Enable SSID with number
|
||||||
|
meraki_ssid:
|
||||||
|
auth_key: '{{auth_key}}'
|
||||||
|
state: present
|
||||||
|
org_name: '{{test_org_name}}'
|
||||||
|
net_name: TestNetSSID
|
||||||
|
number: 1
|
||||||
|
enabled: true
|
||||||
|
delegate_to: localhost
|
||||||
|
register: enable_ssid_number
|
||||||
|
|
||||||
|
- debug:
|
||||||
|
msg: '{{ enable_ssid_number.data.enabled }}'
|
||||||
|
|
||||||
|
- assert:
|
||||||
|
that:
|
||||||
|
- enable_ssid_number.data.enabled == True
|
||||||
|
|
||||||
|
- name: Set PSK with wrong mode
|
||||||
|
meraki_ssid:
|
||||||
|
auth_key: '{{auth_key}}'
|
||||||
|
state: present
|
||||||
|
org_name: '{{test_org_name}}'
|
||||||
|
net_name: TestNetSSID
|
||||||
|
name: AnsibleSSID
|
||||||
|
auth_mode: open
|
||||||
|
psk: abc1234
|
||||||
|
delegate_to: localhost
|
||||||
|
register: psk_invalid
|
||||||
|
ignore_errors: yes
|
||||||
|
|
||||||
|
- debug:
|
||||||
|
msg: '{{ psk_invalid }}'
|
||||||
|
|
||||||
|
- assert:
|
||||||
|
that:
|
||||||
|
- psk_invalid.msg == 'PSK is only allowed when auth_mode is set to psk'
|
||||||
|
|
||||||
|
- name: Set PSK with invalid encryption mode
|
||||||
|
meraki_ssid:
|
||||||
|
auth_key: '{{auth_key}}'
|
||||||
|
state: present
|
||||||
|
org_name: '{{test_org_name}}'
|
||||||
|
net_name: TestNetSSID
|
||||||
|
name: AnsibleSSID
|
||||||
|
auth_mode: psk
|
||||||
|
psk: abc1234
|
||||||
|
encryption_mode: eap
|
||||||
|
delegate_to: localhost
|
||||||
|
register: psk_invalid_mode
|
||||||
|
ignore_errors: yes
|
||||||
|
|
||||||
|
- debug:
|
||||||
|
msg: '{{ psk_invalid_mode }}'
|
||||||
|
|
||||||
|
- assert:
|
||||||
|
that:
|
||||||
|
- psk_invalid_mode.msg == 'PSK requires encryption_mode be set to wpa'
|
||||||
|
|
||||||
|
- name: Set PSK
|
||||||
|
meraki_ssid:
|
||||||
|
auth_key: '{{auth_key}}'
|
||||||
|
state: present
|
||||||
|
org_name: '{{test_org_name}}'
|
||||||
|
net_name: TestNetSSID
|
||||||
|
name: AnsibleSSID
|
||||||
|
auth_mode: psk
|
||||||
|
psk: abc1234567890
|
||||||
|
encryption_mode: wpa
|
||||||
|
delegate_to: localhost
|
||||||
|
register: psk
|
||||||
|
|
||||||
|
- debug:
|
||||||
|
msg: '{{ psk }}'
|
||||||
|
|
||||||
|
- assert:
|
||||||
|
that:
|
||||||
|
- psk.data.authMode == 'psk'
|
||||||
|
- psk.data.encryptionMode == 'wpa'
|
||||||
|
- psk.data.wpaEncryptionMode == 'WPA2 only'
|
||||||
|
|
||||||
|
- name: Enable click-through splash page
|
||||||
|
meraki_ssid:
|
||||||
|
auth_key: '{{auth_key}}'
|
||||||
|
state: present
|
||||||
|
org_name: '{{test_org_name}}'
|
||||||
|
net_name: TestNetSSID
|
||||||
|
name: AnsibleSSID
|
||||||
|
splash_page: Click-through splash page
|
||||||
|
delegate_to: localhost
|
||||||
|
register: splash_click
|
||||||
|
|
||||||
|
- debug:
|
||||||
|
msg: '{{ splash_click }}'
|
||||||
|
|
||||||
|
- assert:
|
||||||
|
that:
|
||||||
|
- splash_click.data.splashPage == 'Click-through splash page'
|
||||||
|
|
||||||
|
- name: Configure RADIUS servers
|
||||||
|
meraki_ssid:
|
||||||
|
auth_key: '{{auth_key}}'
|
||||||
|
state: present
|
||||||
|
org_name: '{{test_org_name}}'
|
||||||
|
net_name: TestNetSSID
|
||||||
|
name: AnsibleSSID
|
||||||
|
auth_mode: open-with-radius
|
||||||
|
radius_servers:
|
||||||
|
- host: 192.0.1.200
|
||||||
|
port: 1234
|
||||||
|
secret: abc98765
|
||||||
|
delegate_to: localhost
|
||||||
|
register: set_radius_server
|
||||||
|
|
||||||
|
- debug:
|
||||||
|
msg: '{{ set_radius_server }}'
|
||||||
|
|
||||||
|
- assert:
|
||||||
|
that:
|
||||||
|
- set_radius_server.data.radiusServers.0.host == '192.0.1.200'
|
||||||
|
|
||||||
|
- name: Delete SSID
|
||||||
|
meraki_ssid:
|
||||||
|
auth_key: '{{auth_key}}'
|
||||||
|
state: absent
|
||||||
|
org_name: '{{test_org_name}}'
|
||||||
|
net_name: TestNetSSID
|
||||||
|
name: AnsibleSSID
|
||||||
|
delegate_to: localhost
|
||||||
|
register: delete_ssid
|
||||||
|
|
||||||
|
- debug:
|
||||||
|
msg: '{{ delete_ssid }}'
|
||||||
|
|
||||||
|
- assert:
|
||||||
|
that:
|
||||||
|
- delete_ssid.data.name == 'Unconfigured SSID 2'
|
||||||
|
|
||||||
|
- name: Delete test network
|
||||||
|
meraki_network:
|
||||||
|
auth_key: '{{auth_key}}'
|
||||||
|
state: absent
|
||||||
|
org_name: '{{test_org_name}}'
|
||||||
|
net_name: TestNetSSID
|
||||||
|
register: delete_net
|
||||||
|
|
||||||
|
- debug:
|
||||||
|
msg: '{{delete_net}}'
|
Loading…
Reference in a new issue