summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnsible Core Team <info@ansible.com>2020-03-09 09:40:34 +0000
committerAnsible Core Team <info@ansible.com>2020-03-09 09:40:34 +0000
commita16d88b068f7086ace193e020c5157e0065a6685 (patch)
tree219f1e4f99b12eebdb78fad69c30d1d6f72c19fc
parente1f0162333d5c70bb631bc26f63ef1d64e74e7b7 (diff)
downloadansible-a16d88b068f7086ace193e020c5157e0065a6685.tar.gz
Migrated to cisco.meraki
-rw-r--r--lib/ansible/module_utils/network/meraki/__init__.py0
-rw-r--r--lib/ansible/module_utils/network/meraki/meraki.py461
-rw-r--r--lib/ansible/modules/network/meraki/__init__.py0
-rw-r--r--lib/ansible/modules/network/meraki/meraki_admin.py498
-rw-r--r--lib/ansible/modules/network/meraki/meraki_config_template.py331
-rw-r--r--lib/ansible/modules/network/meraki/meraki_content_filtering.py248
-rw-r--r--lib/ansible/modules/network/meraki/meraki_device.py430
-rw-r--r--lib/ansible/modules/network/meraki/meraki_firewalled_services.py238
-rw-r--r--lib/ansible/modules/network/meraki/meraki_malware.py276
-rw-r--r--lib/ansible/modules/network/meraki/meraki_mr_l3_firewall.py283
-rw-r--r--lib/ansible/modules/network/meraki/meraki_mx_l3_firewall.py328
-rw-r--r--lib/ansible/modules/network/meraki/meraki_mx_l7_firewall.py506
-rw-r--r--lib/ansible/modules/network/meraki/meraki_nat.py673
-rw-r--r--lib/ansible/modules/network/meraki/meraki_network.py390
-rw-r--r--lib/ansible/modules/network/meraki/meraki_organization.py244
-rw-r--r--lib/ansible/modules/network/meraki/meraki_snmp.py401
-rw-r--r--lib/ansible/modules/network/meraki/meraki_ssid.py606
-rw-r--r--lib/ansible/modules/network/meraki/meraki_static_route.py375
-rw-r--r--lib/ansible/modules/network/meraki/meraki_switchport.py397
-rw-r--r--lib/ansible/modules/network/meraki/meraki_syslog.py257
-rw-r--r--lib/ansible/modules/network/meraki/meraki_vlan.py446
-rw-r--r--lib/ansible/modules/network/meraki/meraki_webhook.py342
-rw-r--r--lib/ansible/plugins/doc_fragments/meraki.py78
-rw-r--r--test/integration/targets/meraki_admin/tasks/main.yml384
-rw-r--r--test/integration/targets/meraki_config_template/aliases1
-rw-r--r--test/integration/targets/meraki_config_template/tasks/main.yml196
-rw-r--r--test/integration/targets/meraki_content_filtering/aliases1
-rw-r--r--test/integration/targets/meraki_content_filtering/meraki_config_template/aliases1
-rw-r--r--test/integration/targets/meraki_content_filtering/meraki_config_template/tasks/main.yml117
-rw-r--r--test/integration/targets/meraki_content_filtering/tasks/main.yml247
-rw-r--r--test/integration/targets/meraki_device/aliases1
-rw-r--r--test/integration/targets/meraki_device/tasks/main.yml215
-rw-r--r--test/integration/targets/meraki_firewalled_services/aliases1
-rw-r--r--test/integration/targets/meraki_firewalled_services/tasks/main.yml7
-rw-r--r--test/integration/targets/meraki_firewalled_services/tasks/tests.yml196
-rw-r--r--test/integration/targets/meraki_malware/aliases1
-rw-r--r--test/integration/targets/meraki_malware/tasks/main.yml247
-rw-r--r--test/integration/targets/meraki_mr_l3_firewall/aliases1
-rw-r--r--test/integration/targets/meraki_mr_l3_firewall/tasks/main.yml100
-rw-r--r--test/integration/targets/meraki_mx_l3_firewall/aliases1
-rw-r--r--test/integration/targets/meraki_mx_l3_firewall/tasks/main.yml203
-rw-r--r--test/integration/targets/meraki_mx_l7_firewall/aliases2
-rw-r--r--test/integration/targets/meraki_mx_l7_firewall/tasks/main.yml7
-rw-r--r--test/integration/targets/meraki_mx_l7_firewall/tasks/tests.yml494
-rw-r--r--test/integration/targets/meraki_nat/tasks/main.yml7
-rw-r--r--test/integration/targets/meraki_nat/tasks/tests.yml363
-rw-r--r--test/integration/targets/meraki_network/aliases1
-rw-r--r--test/integration/targets/meraki_network/tasks/main.yml402
-rw-r--r--test/integration/targets/meraki_organization/aliases1
-rw-r--r--test/integration/targets/meraki_organization/tasks/main.yml8
-rw-r--r--test/integration/targets/meraki_organization/tasks/tests.yml127
-rw-r--r--test/integration/targets/meraki_snmp/aliases1
-rw-r--r--test/integration/targets/meraki_snmp/tasks/main.yml306
-rw-r--r--test/integration/targets/meraki_ssid/aliases1
-rw-r--r--test/integration/targets/meraki_ssid/tasks/main.yml408
-rw-r--r--test/integration/targets/meraki_static_route/aliases1
-rw-r--r--test/integration/targets/meraki_static_route/tasks/main.yml170
-rw-r--r--test/integration/targets/meraki_switchport/aliases1
-rw-r--r--test/integration/targets/meraki_switchport/tasks/main.yml297
-rw-r--r--test/integration/targets/meraki_syslog/tasks/main.yml169
-rw-r--r--test/integration/targets/meraki_vlan/aliases1
-rw-r--r--test/integration/targets/meraki_vlan/tasks/main.yml412
-rw-r--r--test/integration/targets/meraki_webhook/aliases1
-rw-r--r--test/integration/targets/meraki_webhook/tasks/main.yml7
-rw-r--r--test/integration/targets/meraki_webhook/tasks/tests.yml273
-rw-r--r--test/sanity/ignore.txt40
-rw-r--r--test/units/module_utils/network/meraki/fixtures/orgs.json6
-rw-r--r--test/units/module_utils/network/meraki/test_meraki.py160
68 files changed, 0 insertions, 13394 deletions
diff --git a/lib/ansible/module_utils/network/meraki/__init__.py b/lib/ansible/module_utils/network/meraki/__init__.py
deleted file mode 100644
index e69de29bb2..0000000000
--- a/lib/ansible/module_utils/network/meraki/__init__.py
+++ /dev/null
diff --git a/lib/ansible/module_utils/network/meraki/meraki.py b/lib/ansible/module_utils/network/meraki/meraki.py
deleted file mode 100644
index 50567562c1..0000000000
--- a/lib/ansible/module_utils/network/meraki/meraki.py
+++ /dev/null
@@ -1,461 +0,0 @@
-# -*- coding: utf-8 -*-
-
-# This code is part of Ansible, but is an independent component
-
-# This particular file snippet, and this file snippet only, is BSD licensed.
-# Modules you write using this snippet, which is embedded dynamically by Ansible
-# still belong to the author of the module, and may assign their own license
-# to the complete work.
-
-# Copyright: (c) 2018, Kevin Breit <kevin.breit@kevinbreit.net>
-# All rights reserved.
-
-# Redistribution and use in source and binary forms, with or without modification,
-# are permitted provided that the following conditions are met:
-#
-# * Redistributions of source code must retain the above copyright
-# notice, this list of conditions and the following disclaimer.
-# * Redistributions in binary form must reproduce the above copyright notice,
-# this list of conditions and the following disclaimer in the documentation
-# and/or other materials provided with the distribution.
-#
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
-# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
-# IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
-# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
-# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
-# USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-import time
-import os
-import re
-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.six.moves.urllib.parse import urlencode
-from ansible.module_utils._text import to_native, to_bytes, to_text
-
-
-RATE_LIMIT_RETRY_MULTIPLIER = 3
-INTERNAL_ERROR_RETRY_MULTIPLIER = 3
-
-
-def meraki_argument_spec():
- return dict(auth_key=dict(type='str', no_log=True, fallback=(env_fallback, ['MERAKI_KEY']), required=True),
- host=dict(type='str', default='api.meraki.com'),
- use_proxy=dict(type='bool', default=False),
- use_https=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']),
- timeout=dict(type='int', default=30),
- org_name=dict(type='str', aliases=['organization']),
- org_id=dict(type='str'),
- rate_limit_retry_time=dict(type='int', default=165),
- internal_error_retry_time=dict(type='int', default=60)
- )
-
-
-class RateLimitException(Exception):
- def __init__(self, *args, **kwargs):
- Exception.__init__(self, *args, **kwargs)
-
-
-class InternalErrorException(Exception):
- def __init__(self, *args, **kwargs):
- Exception.__init__(self, *args, **kwargs)
-
-
-class HTTPError(Exception):
- def __init__(self, *args, **kwargs):
- Exception.__init__(self, *args, **kwargs)
-
-
-def _error_report(function):
- def inner(self, *args, **kwargs):
- while True:
- try:
- response = function(self, *args, **kwargs)
- if self.status == 429:
- raise RateLimitException(
- "Rate limiter hit, retry {0}".format(self.retry))
- elif self.status == 500:
- raise InternalErrorException(
- "Internal server error 500, retry {0}".format(self.retry))
- elif self.status == 502:
- raise InternalErrorException(
- "Internal server error 502, retry {0}".format(self.retry))
- elif self.status >= 400:
- raise HTTPError("HTTP error {0} - {1}".format(self.status, response))
- self.retry = 0 # Needs to reset in case of future retries
- return response
- except RateLimitException as e:
- self.retry += 1
- if self.retry <= 10:
- self.retry_time += self.retry * RATE_LIMIT_RETRY_MULTIPLIER
- time.sleep(self.retry * RATE_LIMIT_RETRY_MULTIPLIER)
- else:
- self.retry_time += 30
- time.sleep(30)
- if self.retry_time > self.params['rate_limit_retry_time']:
- raise RateLimitException(e)
- except InternalErrorException as e:
- self.retry += 1
- if self.retry <= 10:
- self.retry_time += self.retry * INTERNAL_ERROR_RETRY_MULTIPLIER
- time.sleep(self.retry * INTERNAL_ERROR_RETRY_MULTIPLIER)
- else:
- self.retry_time += 9
- time.sleep(9)
- if self.retry_time > self.params['internal_error_retry_time']:
- raise InternalErrorException(e)
- except HTTPError as e:
- raise HTTPError(e)
- return inner
-
-
-class MerakiModule(object):
-
- def __init__(self, module, function=None):
- self.module = module
- self.params = module.params
- self.result = dict(changed=False)
- self.headers = dict()
- self.function = function
- self.orgs = None
- self.nets = None
- self.org_id = None
- self.net_id = None
- self.check_mode = module.check_mode
- self.key_map = {}
- self.request_attempts = 0
-
- # normal output
- self.existing = None
-
- # info output
- self.config = dict()
- self.original = None
- self.proposed = dict()
- self.merged = None
- self.ignored_keys = ['id', 'organizationId']
-
- # debug output
- self.filter_string = ''
- self.method = None
- self.path = None
- self.response = None
- self.status = None
- self.url = None
-
- # rate limiting statistics
- self.retry = 0
- self.retry_time = 0
-
- # If URLs need to be modified or added for specific purposes, use .update() on the url_catalog dictionary
- self.get_urls = {'organizations': '/organizations',
- 'network': '/organizations/{org_id}/networks',
- 'admins': '/organizations/{org_id}/admins',
- 'configTemplates': '/organizations/{org_id}/configTemplates',
- 'samlymbols': '/organizations/{org_id}/samlRoles',
- 'ssids': '/networks/{net_id}/ssids',
- 'groupPolicies': '/networks/{net_id}/groupPolicies',
- 'staticRoutes': '/networks/{net_id}/staticRoutes',
- 'vlans': '/networks/{net_id}/vlans',
- 'devices': '/networks/{net_id}/devices',
- }
-
- # Used to retrieve only one item
- self.get_one_urls = {'organizations': '/organizations/{org_id}',
- 'network': '/networks/{net_id}',
- }
-
- # Module should add URLs which are required by the module
- self.url_catalog = {'get_all': self.get_urls,
- 'get_one': self.get_one_urls,
- 'create': None,
- 'update': None,
- 'delete': None,
- 'misc': None,
- }
-
- if self.module._debug or self.params['output_level'] == 'debug':
- self.module.warn('Enable debug output because ANSIBLE_DEBUG was set or output_level is set to debug.')
-
- # TODO: This should be removed as org_name isn't always required
- self.module.required_if = [('state', 'present', ['org_name']),
- ('state', 'absent', ['org_name']),
- ]
- # self.module.mutually_exclusive = [('org_id', 'org_name'),
- # ]
- self.modifiable_methods = ['POST', 'PUT', 'DELETE']
-
- self.headers = {'Content-Type': 'application/json',
- 'X-Cisco-Meraki-API-Key': module.params['auth_key'],
- }
-
- def define_protocol(self):
- """Set protocol based on use_https parameters."""
- if self.params['use_https'] is True:
- self.params['protocol'] = 'https'
- else:
- self.params['protocol'] = 'http'
-
- def sanitize_keys(self, data):
- if isinstance(data, dict):
- items = {}
- for k, v in data.items():
- try:
- new = {self.key_map[k]: data[k]}
- items[self.key_map[k]] = self.sanitize_keys(data[k])
- except KeyError:
- snake_k = re.sub('([a-z0-9])([A-Z])', r'\1_\2', k).lower()
- 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):
- ''' Compare two data-structures '''
- self.ignored_keys.append('net_id')
- if optional_ignore is not None:
- self.ignored_keys = self.ignored_keys + optional_ignore
-
- if isinstance(original, list):
- if len(original) != len(proposed):
- # self.fail_json(msg="Length of lists don't match")
- return True
- for a, b in zip(original, proposed):
- if self.is_update_required(a, b):
- # self.fail_json(msg="List doesn't match", a=a, b=b)
- return True
- elif isinstance(original, dict):
- for k, v in proposed.items():
- if k not in self.ignored_keys:
- if k in original:
- if self.is_update_required(original[k], proposed[k]):
- return True
- else:
- # self.fail_json(msg="Key not in original", k=k)
- return True
- else:
- if original != proposed:
- # self.fail_json(msg="Fallback", original=original, proposed=proposed)
- return True
- return False
-
- def get_orgs(self):
- """Downloads all organizations for a user."""
- response = self.request('/organizations', method='GET')
- if self.status != 200:
- self.fail_json(msg='Organization lookup failed')
- self.orgs = response
- return self.orgs
-
- def is_org_valid(self, data, org_name=None, org_id=None):
- """Checks whether a specific org exists and is duplicated.
-
- If 0, doesn't exist. 1, exists and not duplicated. >1 duplicated.
- """
- org_count = 0
- if org_name is not None:
- for o in data:
- if o['name'] == org_name:
- org_count += 1
- if org_id is not None:
- for o in data:
- if o['id'] == org_id:
- org_count += 1
- return org_count
-
- def get_org_id(self, org_name):
- """Returns an organization id based on organization name, only if unique.
-
- If org_id is specified as parameter, return that instead of a lookup.
- """
- orgs = self.get_orgs()
- # self.fail_json(msg='ogs', orgs=orgs)
- if self.params['org_id'] is not None:
- if self.is_org_valid(orgs, org_id=self.params['org_id']) is True:
- return self.params['org_id']
- org_count = self.is_org_valid(orgs, org_name=org_name)
- if org_count == 0:
- self.fail_json(msg='There are no organizations with the name {org_name}'.format(org_name=org_name))
- if org_count > 1:
- self.fail_json(msg='There are multiple organizations with the name {org_name}'.format(org_name=org_name))
- elif org_count == 1:
- for i in orgs:
- if org_name == i['name']:
- # self.fail_json(msg=i['id'])
- return str(i['id'])
-
- def get_nets(self, org_name=None, org_id=None):
- """Downloads all networks in an organization."""
- if org_name:
- org_id = self.get_org_id(org_name)
- path = self.construct_path('get_all', org_id=org_id, function='network')
- r = self.request(path, method='GET')
- if self.status != 200:
- self.fail_json(msg='Network lookup failed')
- self.nets = r
- templates = self.get_config_templates(org_id)
- for t in templates:
- self.nets.append(t)
- return self.nets
-
- def get_net(self, org_name, net_name=None, org_id=None, data=None, net_id=None):
- ''' Return network information '''
- if not data:
- if not org_id:
- org_id = self.get_org_id(org_name)
- data = self.get_nets(org_id=org_id)
- for n in data:
- if net_id:
- if n['id'] == net_id:
- return n
- elif net_name:
- if n['name'] == net_name:
- return n
- return False
-
- def get_net_id(self, org_name=None, net_name=None, data=None):
- """Return network id from lookup or existing data."""
- if data is None:
- self.fail_json(msg='Must implement lookup')
- for n in data:
- if n['name'] == net_name:
- return n['id']
- self.fail_json(msg='No network found with the name {0}'.format(net_name))
-
- def get_config_templates(self, org_id):
- path = self.construct_path('get_all', function='configTemplates', org_id=org_id)
- response = self.request(path, 'GET')
- if self.status != 200:
- self.fail_json(msg='Unable to get configuration templates')
- return response
-
- def get_template_id(self, name, data):
- for template in data:
- if name == template['name']:
- return template['id']
- 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):
- qs = {}
- for key in keys:
- if key in aliases:
- qs[aliases[key]] = self.module.params[key]
- else:
- qs[key] = self.module.params[key]
- return qs
-
- def encode_url_params(self, params):
- """Encodes key value pairs for URL"""
- return "?{0}".format(urlencode(params))
-
- def construct_path(self,
- action,
- function=None,
- org_id=None,
- net_id=None,
- org_name=None,
- custom=None,
- params=None):
- """Build a path from the URL catalog.
- Uses function property from class for catalog lookup.
- """
- built_path = None
- if function is None:
- built_path = self.url_catalog[action][self.function]
- else:
- built_path = self.url_catalog[action][function]
- if org_name:
- org_id = self.get_org_id(org_name)
- if custom:
- built_path = built_path.format(org_id=org_id, net_id=net_id, **custom)
- else:
- built_path = built_path.format(org_id=org_id, net_id=net_id)
- if params:
- built_path += self.encode_url_params(params)
- return built_path
-
- @_error_report
- def request(self, path, method=None, payload=None):
- """Generic HTTP method for Meraki requests."""
- self.path = path
- self.define_protocol()
-
- if method is not None:
- self.method = method
- self.url = '{protocol}://{host}/api/v0/{path}'.format(path=self.path.lstrip('/'), **self.params)
- resp, info = fetch_url(self.module, self.url,
- headers=self.headers,
- data=payload,
- method=self.method,
- timeout=self.params['timeout'],
- use_proxy=self.params['use_proxy'],
- )
- self.response = info['msg']
- self.status = info['status']
-
- try:
- return json.loads(to_native(resp.read()))
- except Exception:
- pass
-
- def exit_json(self, **kwargs):
- """Custom written method to exit from module."""
- self.result['response'] = self.response
- self.result['status'] = self.status
- if self.retry > 0:
- self.module.warn("Rate limiter triggered - retry count {0}".format(self.retry))
- # Return the gory details when we need it
- if self.params['output_level'] == 'debug':
- self.result['method'] = self.method
- self.result['url'] = self.url
- 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)
-
- def fail_json(self, msg, **kwargs):
- """Custom written method to return info on failure."""
- self.result['response'] = self.response
- self.result['status'] = self.status
-
- if self.params['output_level'] == 'debug':
- if self.url is not None:
- self.result['method'] = self.method
- self.result['url'] = self.url
-
- self.result.update(**kwargs)
- self.module.fail_json(msg=msg, **self.result)
diff --git a/lib/ansible/modules/network/meraki/__init__.py b/lib/ansible/modules/network/meraki/__init__.py
deleted file mode 100644
index e69de29bb2..0000000000
--- a/lib/ansible/modules/network/meraki/__init__.py
+++ /dev/null
diff --git a/lib/ansible/modules/network/meraki/meraki_admin.py b/lib/ansible/modules/network/meraki/meraki_admin.py
deleted file mode 100644
index 342d071f0e..0000000000
--- a/lib/ansible/modules/network/meraki/meraki_admin.py
+++ /dev/null
@@ -1,498 +0,0 @@
-#!/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_admin
-short_description: Manage administrators in the Meraki cloud
-version_added: '2.6'
-description:
-- Allows for creation, management, and visibility into administrators within Meraki.
-options:
- name:
- description:
- - Name of the dashboard administrator.
- - Required when creating a new administrator.
- type: str
- email:
- description:
- - Email address for the dashboard administrator.
- - Email cannot be updated.
- - Required when creating or editing an administrator.
- type: str
- org_access:
- description:
- - Privileges assigned to the administrator in the organization.
- aliases: [ orgAccess ]
- choices: [ full, none, read-only ]
- type: str
- tags:
- description:
- - Tags the administrator has privileges on.
- - When creating a new administrator, C(org_name), C(network), or C(tags) must be specified.
- - If C(none) is specified, C(network) or C(tags) must be specified.
- suboptions:
- tag:
- description:
- - Object tag which privileges should be assigned.
- type: str
- access:
- description:
- - The privilege of the dashboard administrator for the tag.
- type: str
- networks:
- description:
- - List of networks the administrator has privileges on.
- - When creating a new administrator, C(org_name), C(network), or C(tags) must be specified.
- suboptions:
- id:
- description:
- - Network ID for which administrator should have privileges assigned.
- type: str
- access:
- description:
- - The privilege of the dashboard administrator on the network.
- - Valid options are C(full), C(read-only), or C(none).
- type: str
- state:
- description:
- - Create or modify, or delete an organization
- - If C(state) is C(absent), name takes priority over email if both are specified.
- choices: [ absent, present, query ]
- required: true
- type: str
- org_name:
- description:
- - Name of organization.
- - Used when C(name) should refer to another object.
- - When creating a new administrator, C(org_name), C(network), or C(tags) must be specified.
- aliases: ['organization']
- type: str
-author:
- - Kevin Breit (@kbreit)
-extends_documentation_fragment: meraki
-'''
-
-EXAMPLES = r'''
-- name: Query information about all administrators associated to the organization
- meraki_admin:
- auth_key: abc12345
- org_name: YourOrg
- state: query
- delegate_to: localhost
-
-- name: Query information about a single administrator by name
- meraki_admin:
- auth_key: abc12345
- org_id: 12345
- state: query
- name: Jane Doe
-
-- name: Query information about a single administrator by email
- meraki_admin:
- auth_key: abc12345
- org_name: YourOrg
- state: query
- email: jane@doe.com
-
-- name: Create new administrator with organization access
- meraki_admin:
- auth_key: abc12345
- org_name: YourOrg
- state: present
- name: Jane Doe
- org_access: read-only
- email: jane@doe.com
-
-- name: Create new administrator with organization access
- meraki_admin:
- auth_key: abc12345
- org_name: YourOrg
- state: present
- name: Jane Doe
- org_access: read-only
- email: jane@doe.com
-
-- name: Create a new administrator with organization access
- meraki_admin:
- auth_key: abc12345
- org_name: YourOrg
- state: present
- name: Jane Doe
- org_access: read-only
- email: jane@doe.com
-
-- name: Revoke access to an organization for an administrator
- meraki_admin:
- auth_key: abc12345
- org_name: YourOrg
- state: absent
- email: jane@doe.com
-
-- name: Create a new administrator with full access to two tags
- meraki_admin:
- auth_key: abc12345
- org_name: YourOrg
- state: present
- name: Jane Doe
- orgAccess: read-only
- email: jane@doe.com
- tags:
- - tag: tenant
- access: full
- - tag: corporate
- access: read-only
-
-- name: Create a new administrator with full access to a network
- meraki_admin:
- auth_key: abc12345
- org_name: YourOrg
- state: present
- name: Jane Doe
- orgAccess: read-only
- email: jane@doe.com
- networks:
- - id: N_12345
- access: full
-'''
-
-RETURN = r'''
-data:
- description: List of administrators.
- returned: success
- type: complex
- contains:
- email:
- description: Email address of administrator.
- returned: success
- type: str
- sample: your@email.com
- id:
- description: Unique identification number of administrator.
- returned: success
- type: str
- sample: 1234567890
- name:
- description: Given name of administrator.
- returned: success
- type: str
- sample: John Doe
- account_status:
- description: Status of account.
- returned: success
- type: str
- sample: ok
- two_factor_auth_enabled:
- description: Enabled state of two-factor authentication for administrator.
- returned: success
- type: bool
- sample: false
- has_api_key:
- description: Defines whether administrator has an API assigned to their account.
- returned: success
- type: bool
- sample: false
- last_active:
- description: Date and time of time the administrator was active within Dashboard.
- returned: success
- type: str
- sample: 2019-01-28 14:58:56 -0800
- networks:
- description: List of networks administrator has access on.
- returned: success
- type: complex
- contains:
- id:
- description: The network ID.
- returned: when network permissions are set
- type: str
- sample: N_0123456789
- access:
- description: Access level of administrator. Options are 'full', 'read-only', or 'none'.
- returned: when network permissions are set
- type: str
- sample: read-only
- tags:
- description: Tags the administrator has access on.
- returned: success
- type: complex
- contains:
- tag:
- description: Tag name.
- returned: when tag permissions are set
- type: str
- sample: production
- access:
- description: Access level of administrator. Options are 'full', 'read-only', or 'none'.
- returned: when tag permissions are set
- type: str
- sample: full
- org_access:
- description: The privilege of the dashboard administrator on the organization. Options are 'full', 'read-only', or 'none'.
- returned: success
- type: str
- sample: full
-
-'''
-
-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.common.dict_transformations import recursive_diff
-from ansible.module_utils.network.meraki.meraki import MerakiModule, meraki_argument_spec
-
-
-def get_admins(meraki, org_id):
- admins = meraki.request(
- meraki.construct_path(
- 'query',
- function='admin',
- org_id=org_id
- ),
- method='GET'
- )
- if meraki.status == 200:
- return admins
-
-
-def get_admin_id(meraki, data, name=None, email=None):
- admin_id = None
- for a in data:
- if meraki.params['name'] is not None:
- if meraki.params['name'] == a['name']:
- if admin_id is not None:
- meraki.fail_json(msg='There are multiple administrators with the same name')
- else:
- admin_id = a['id']
- elif meraki.params['email']:
- if meraki.params['email'] == a['email']:
- return a['id']
- if admin_id is None:
- meraki.fail_json(msg='No admin_id found')
- return admin_id
-
-
-def get_admin(meraki, data, id):
- for a in data:
- if a['id'] == id:
- return a
- meraki.fail_json(msg='No admin found by specified name or email')
-
-
-def find_admin(meraki, data, email):
- for a in data:
- if a['email'] == email:
- return a
- return None
-
-
-def delete_admin(meraki, org_id, admin_id):
- path = meraki.construct_path('revoke', 'admin', org_id=org_id) + admin_id
- r = meraki.request(path,
- method='DELETE'
- )
- if meraki.status == 204:
- return r
-
-
-def network_factory(meraki, networks, nets):
- networks = json.loads(networks)
- networks_new = []
- for n in networks:
- networks_new.append({'id': meraki.get_net_id(org_name=meraki.params['org_name'],
- net_name=n['network'],
- data=nets),
- 'access': n['access']
- })
- return networks_new
-
-
-def create_admin(meraki, org_id, name, email):
- payload = dict()
- payload['name'] = name
- payload['email'] = email
-
- is_admin_existing = find_admin(meraki, get_admins(meraki, org_id), email)
-
- if meraki.params['org_access'] is not None:
- payload['orgAccess'] = meraki.params['org_access']
- if meraki.params['tags'] is not None:
- payload['tags'] = json.loads(meraki.params['tags'])
- if meraki.params['networks'] is not None:
- nets = meraki.get_nets(org_id=org_id)
- networks = network_factory(meraki, meraki.params['networks'], nets)
- payload['networks'] = networks
- if is_admin_existing is None: # Create new admin
- 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', function='admin', org_id=org_id)
- r = meraki.request(path,
- method='POST',
- payload=json.dumps(payload)
- )
- if meraki.status == 201:
- meraki.result['changed'] = True
- return r
- elif is_admin_existing is not None: # Update existing admin
- if not meraki.params['tags']:
- payload['tags'] = []
- if not meraki.params['networks']:
- payload['networks'] = []
- if meraki.is_update_required(is_admin_existing, payload) is True:
- if meraki.module.check_mode is True:
- diff = recursive_diff(is_admin_existing, payload)
- is_admin_existing.update(payload)
- meraki.result['diff'] = {'before': diff[0],
- 'after': diff[1],
- }
- meraki.result['changed'] = True
- meraki.result['data'] = payload
- meraki.exit_json(**meraki.result)
- path = meraki.construct_path('update', function='admin', org_id=org_id) + is_admin_existing['id']
- r = meraki.request(path,
- method='PUT',
- payload=json.dumps(payload)
- )
- if meraki.status == 200:
- meraki.result['changed'] = True
- return r
- else:
- meraki.result['data'] = is_admin_existing
- if meraki.module.check_mode is True:
- meraki.result['data'] = payload
- meraki.exit_json(**meraki.result)
- return -1
-
-
-def main():
- # define the available arguments/parameters that a user can pass to
- # the module
- argument_spec = meraki_argument_spec()
- argument_spec.update(state=dict(type='str', choices=['present', 'query', 'absent'], required=True),
- name=dict(type='str'),
- email=dict(type='str'),
- org_access=dict(type='str', aliases=['orgAccess'], choices=['full', 'read-only', 'none']),
- tags=dict(type='json'),
- networks=dict(type='json'),
- org_name=dict(type='str', aliases=['organization']),
- org_id=dict(type='str'),
- )
-
- # 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='admin')
-
- meraki.function = 'admin'
- meraki.params['follow_redirects'] = 'all'
-
- query_urls = {'admin': '/organizations/{org_id}/admins',
- }
- create_urls = {'admin': '/organizations/{org_id}/admins',
- }
- update_urls = {'admin': '/organizations/{org_id}/admins/',
- }
- revoke_urls = {'admin': '/organizations/{org_id}/admins/',
- }
-
- meraki.url_catalog['query'] = query_urls
- meraki.url_catalog['create'] = create_urls
- meraki.url_catalog['update'] = update_urls
- meraki.url_catalog['revoke'] = revoke_urls
-
- try:
- meraki.params['auth_key'] = os.environ['MERAKI_KEY']
- except KeyError:
- pass
-
- 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
-
- # execute checks for argument completeness
- if meraki.params['state'] == 'query':
- meraki.mututally_exclusive = ['name', 'email']
- if not meraki.params['org_name'] and not meraki.params['org_id']:
- meraki.fail_json(msg='org_name or org_id required')
- meraki.required_if = [(['state'], ['absent'], ['email']),
- ]
-
- # 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']
- if not meraki.params['org_id']:
- org_id = meraki.get_org_id(meraki.params['org_name'])
- if meraki.params['state'] == 'query':
- admins = get_admins(meraki, org_id)
- if not meraki.params['name'] and not meraki.params['email']: # Return all admins for org
- meraki.result['data'] = admins
- if meraki.params['name'] is not None: # Return a single admin for org
- admin_id = get_admin_id(meraki, admins, name=meraki.params['name'])
- meraki.result['data'] = admin_id
- admin = get_admin(meraki, admins, admin_id)
- meraki.result['data'] = admin
- elif meraki.params['email'] is not None:
- admin_id = get_admin_id(meraki, admins, email=meraki.params['email'])
- meraki.result['data'] = admin_id
- admin = get_admin(meraki, admins, admin_id)
- meraki.result['data'] = admin
- elif meraki.params['state'] == 'present':
- r = create_admin(meraki,
- org_id,
- meraki.params['name'],
- meraki.params['email'],
- )
- if r != -1:
- meraki.result['data'] = r
- elif meraki.params['state'] == 'absent':
- if meraki.module.check_mode is True:
- meraki.result['data'] = {}
- meraki.result['changed'] = True
- meraki.exit_json(**meraki.result)
- admin_id = get_admin_id(meraki,
- get_admins(meraki, org_id),
- email=meraki.params['email']
- )
- r = delete_admin(meraki, org_id, admin_id)
-
- if r != -1:
- meraki.result['data'] = r
- 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()
diff --git a/lib/ansible/modules/network/meraki/meraki_config_template.py b/lib/ansible/modules/network/meraki/meraki_config_template.py
deleted file mode 100644
index ad6258db73..0000000000
--- a/lib/ansible/modules/network/meraki/meraki_config_template.py
+++ /dev/null
@@ -1,331 +0,0 @@
-#!/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_config_template
-short_description: Manage configuration templates in the Meraki cloud
-version_added: "2.7"
-description:
-- Allows for querying, deleting, binding, and unbinding of configuration templates.
-notes:
-- Module is not idempotent as the Meraki API is limited in what information it provides about configuration templates.
-- Meraki's API does not support creating new configuration templates.
-- To use the configuration template, simply pass its ID via C(net_id) parameters in Meraki modules.
-options:
- state:
- description:
- - Specifies whether configuration template information should be queried, modified, or deleted.
- choices: ['absent', 'query', 'present']
- default: query
- org_name:
- description:
- - Name of organization containing the configuration template.
- type: str
- org_id:
- description:
- - ID of organization associated to a configuration template.
- type: str
- config_template:
- description:
- - Name of the configuration template within an organization to manipulate.
- aliases: ['name']
- net_name:
- description:
- - Name of the network to bind or unbind configuration template to.
- type: str
- net_id:
- description:
- - ID of the network to bind or unbind configuration template to.
- type: str
- auto_bind:
- description:
- - Optional boolean indicating whether the network's switches should automatically bind to profiles of the same model.
- - This option only affects switch networks and switch templates.
- - Auto-bind is not valid unless the switch template has at least one profile and has at most one profile per switch model.
- type: bool
-
-author:
-- Kevin Breit (@kbreit)
-extends_documentation_fragment: meraki
-'''
-
-EXAMPLES = r'''
-- name: Query configuration templates
- meraki_config_template:
- auth_key: abc12345
- org_name: YourOrg
- state: query
- delegate_to: localhost
-
-- name: Bind a template from a network
- meraki_config_template:
- auth_key: abc123
- state: present
- org_name: YourOrg
- net_name: YourNet
- config_template: DevConfigTemplate
- delegate_to: localhost
-
-- name: Unbind a template from a network
- meraki_config_template:
- auth_key: abc123
- state: absent
- org_name: YourOrg
- net_name: YourNet
- config_template: DevConfigTemplate
- delegate_to: localhost
-
-- name: Delete a configuration template
- meraki_config_template:
- auth_key: abc123
- state: absent
- org_name: YourOrg
- config_template: DevConfigTemplate
- delegate_to: localhost
-'''
-
-RETURN = r'''
-data:
- description: Information about queried object.
- returned: success
- type: complex
- contains:
- id:
- description: Unique identification number of organization
- returned: success
- type: int
- sample: L_2930418
- name:
- description: Name of configuration template
- returned: success
- type: str
- sample: YourTemplate
-'''
-
-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_config_templates(meraki, org_id):
- path = meraki.construct_path('get_all', org_id=org_id)
- response = meraki.request(path, 'GET')
- if meraki.status != 200:
- meraki.fail_json(msg='Unable to get configuration templates')
- return response
-
-
-def get_template_id(meraki, name, data):
- for template in data:
- if name == template['name']:
- return template['id']
- 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):
- for net in nets:
- if net['id'] == net_id:
- try:
- if net['configTemplateId'] == template_id:
- return True
- except KeyError:
- pass
- return False
-
-
-def delete_template(meraki, org_id, name, data):
- template_id = get_template_id(meraki, name, data)
- path = meraki.construct_path('delete', org_id=org_id)
- path = path + '/' + template_id
- response = meraki.request(path, 'DELETE')
- if meraki.status != 204:
- meraki.fail_json(msg='Unable to remove configuration template')
- return response
-
-
-def bind(meraki, net_id, template_id):
- path = meraki.construct_path('bind', net_id=net_id)
- payload = {'configTemplateId': template_id}
- if meraki.params['auto_bind']:
- payload['autoBind'] = meraki.params['auto_bind']
- r = meraki.request(path, method='POST', payload=json.dumps(payload))
- return r
-
-
-def unbind(meraki, net_id):
- path = meraki.construct_path('unbind', net_id=net_id)
- meraki.result['changed'] = True
- return meraki.request(path, method='POST')
-
-
-def main():
-
- # define the available arguments/parameters that a user can pass to
- # the module
- argument_spec = meraki_argument_spec()
- argument_spec.update(state=dict(type='str', choices=['absent', 'query', 'present'], default='query'),
- config_template=dict(type='str', aliases=['name']),
- net_name=dict(type='str'),
- net_id=dict(type='str'),
- # config_template_id=dict(type='str', aliases=['id']),
- auto_bind=dict(type='bool'),
- )
-
- # 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='config_template')
- meraki.params['follow_redirects'] = 'all'
-
- query_urls = {'config_template': '/organizations/{org_id}/configTemplates'}
- delete_urls = {'config_template': '/organizations/{org_id}/configTemplates'}
- bind_urls = {'config_template': '/networks/{net_id}/bind'}
- unbind_urls = {'config_template': '/networks/{net_id}/unbind'}
-
- meraki.url_catalog['get_all'].update(query_urls)
- meraki.url_catalog['delete'] = delete_urls
- meraki.url_catalog['bind'] = bind_urls
- meraki.url_catalog['unbind'] = unbind_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
-
- # 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)
- org_id = meraki.params['org_id']
- if meraki.params['org_name']:
- org_id = meraki.get_org_id(meraki.params['org_name'])
- net_id = meraki.params['net_id']
- nets = None
- if net_id is None:
- if meraki.params['net_name'] is not None:
- nets = meraki.get_nets(org_id=org_id)
- net_id = meraki.get_net_id(net_name=meraki.params['net_name'], data=nets)
- else:
- nets = meraki.get_nets(org_id=org_id)
-
- if meraki.params['state'] == 'query':
- meraki.result['data'] = get_config_templates(meraki, org_id)
- elif meraki.params['state'] == 'present':
- template_id = get_template_id(meraki,
- meraki.params['config_template'],
- get_config_templates(meraki, org_id))
- if nets is None:
- nets = meraki.get_nets(org_id=org_id)
- 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,
- net_id,
- template_id)
- if meraki.status != 200:
- meraki.fail_json(msg='Unable to bind configuration template to network')
- meraki.result['changed'] = True
- meraki.result['data'] = template_bind
- else: # Network is already bound, being explicit
- if meraki.check_mode is True: # Include to be explicit
- 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':
- 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,
- org_id,
- meraki.params['config_template'],
- get_config_templates(meraki, org_id))
- if meraki.status == 204:
- meraki.result['data'] = {}
- meraki.result['changed'] = True
- 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,
- meraki.params['config_template'],
- get_config_templates(meraki, org_id))
- if nets is None:
- nets = meraki.get_nets(org_id=org_id)
- 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,
- net_id)
- if meraki.status != 200:
- meraki.fail_json(msg='Unable to unbind configuration template from network')
- meraki.result['changed'] = True
- meraki.result['data'] = config_unbind
- else: # No network is bound, nothing to do
- if meraki.check_mode is True: # Include to be explicit
- 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
- # simple AnsibleModule.exit_json(), passing the key/value results
- meraki.exit_json(**meraki.result)
-
-
-if __name__ == '__main__':
- main()
diff --git a/lib/ansible/modules/network/meraki/meraki_content_filtering.py b/lib/ansible/modules/network/meraki/meraki_content_filtering.py
deleted file mode 100644
index 498bf43ab0..0000000000
--- a/lib/ansible/modules/network/meraki/meraki_content_filtering.py
+++ /dev/null
@@ -1,248 +0,0 @@
-#!/usr/bin/python
-# -*- coding: utf-8 -*-
-
-# Copyright: (c) 2019, 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_content_filtering
-short_description: Edit Meraki MX content filtering policies
-version_added: "2.8"
-description:
-- Allows for setting policy on content filtering.
-
-options:
- auth_key:
- description:
- - Authentication key provided by the dashboard. Required if environmental variable MERAKI_KEY is not set.
- type: str
- net_name:
- description:
- - Name of a network.
- aliases: [ network ]
- type: str
- net_id:
- description:
- - ID number of a network.
- type: str
- state:
- description:
- - States that a policy should be created or modified.
- choices: [present, query]
- default: present
- type: str
- allowed_urls:
- description:
- - List of URL patterns which should be allowed.
- type: list
- blocked_urls:
- description:
- - List of URL patterns which should be blocked.
- type: list
- blocked_categories:
- description:
- - List of content categories which should be blocked.
- - Use the C(meraki_content_filtering_facts) module for a full list of categories.
- type: list
- category_list_size:
- description:
- - Determines whether a network filters fo rall URLs in a category or only the list of top blocked sites.
- choices: [ top sites, full list ]
- type: str
- subset:
- description:
- - Display only certain facts.
- choices: [categories, policy]
- type: str
- version_added: '2.9'
-author:
- - Kevin Breit (@kbreit)
-extends_documentation_fragment: meraki
-'''
-
-EXAMPLES = r'''
- - name: Set single allowed URL pattern
- meraki_content_filtering:
- auth_key: abc123
- org_name: YourOrg
- net_name: YourMXNet
- allowed_urls:
- - "http://www.ansible.com/*"
-
- - name: Set blocked URL category
- meraki_content_filtering:
- auth_key: abc123
- org_name: YourOrg
- net_name: YourMXNet
- state: present
- category_list_size: full list
- blocked_categories:
- - "Adult and Pornography"
-
- - name: Remove match patterns and categories
- meraki_content_filtering:
- auth_key: abc123
- org_name: YourOrg
- net_name: YourMXNet
- state: present
- category_list_size: full list
- allowed_urls: []
- blocked_urls: []
-'''
-
-RETURN = r'''
-data:
- description: Information about the created or manipulated object.
- returned: info
- type: complex
- contains:
- id:
- description: Identification string of network.
- returned: success
- type: str
- sample: N_12345
-'''
-
-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.common.dict_transformations import recursive_diff
-from ansible.module_utils.network.meraki.meraki import MerakiModule, meraki_argument_spec
-
-
-def get_category_dict(meraki, full_list, category):
- for i in full_list['categories']:
- if i['name'] == category:
- return i['id']
- meraki.fail_json(msg="{0} is not a valid content filtering category".format(category))
-
-
-def main():
-
- # define the available arguments/parameters that a user can pass to
- # the module
-
- argument_spec = meraki_argument_spec()
- argument_spec.update(
- net_id=dict(type='str'),
- net_name=dict(type='str', aliases=['network']),
- state=dict(type='str', default='present', choices=['present', 'query']),
- allowed_urls=dict(type='list'),
- blocked_urls=dict(type='list'),
- blocked_categories=dict(type='list'),
- category_list_size=dict(type='str', choices=['top sites', 'full list']),
- subset=dict(type='str', choices=['categories', 'policy']),
- )
-
- # 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='content_filtering')
- module.params['follow_redirects'] = 'all'
-
- category_urls = {'content_filtering': '/networks/{net_id}/contentFiltering/categories'}
- policy_urls = {'content_filtering': '/networks/{net_id}/contentFiltering'}
-
- meraki.url_catalog['categories'] = category_urls
- meraki.url_catalog['policy'] = policy_urls
-
- if meraki.params['net_name'] and meraki.params['net_id']:
- meraki.fail_json(msg='net_name and net_id are mutually exclusive')
-
- # 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']
- if not org_id:
- org_id = meraki.get_org_id(meraki.params['org_name'])
- net_id = meraki.params['net_id']
- 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['subset']:
- if meraki.params['subset'] == 'categories':
- path = meraki.construct_path('categories', net_id=net_id)
- elif meraki.params['subset'] == 'policy':
- path = meraki.construct_path('policy', net_id=net_id)
- meraki.result['data'] = meraki.request(path, method='GET')
- else:
- response_data = {'categories': None,
- 'policy': None,
- }
- path = meraki.construct_path('categories', net_id=net_id)
- response_data['categories'] = meraki.request(path, method='GET')
- path = meraki.construct_path('policy', net_id=net_id)
- response_data['policy'] = meraki.request(path, method='GET')
- meraki.result['data'] = response_data
- if module.params['state'] == 'present':
- payload = dict()
- if meraki.params['allowed_urls']:
- payload['allowedUrlPatterns'] = meraki.params['allowed_urls']
- if meraki.params['blocked_urls']:
- payload['blockedUrlPatterns'] = meraki.params['blocked_urls']
- if meraki.params['blocked_categories']:
- if len(meraki.params['blocked_categories']) == 0: # Corner case for resetting
- payload['blockedUrlCategories'] = []
- else:
- category_path = meraki.construct_path('categories', net_id=net_id)
- categories = meraki.request(category_path, method='GET')
- payload['blockedUrlCategories'] = []
- for category in meraki.params['blocked_categories']:
- payload['blockedUrlCategories'].append(get_category_dict(meraki,
- categories,
- category))
- if meraki.params['category_list_size']:
- if meraki.params['category_list_size'].lower() == 'top sites':
- payload['urlCategoryListSize'] = "topSites"
- elif meraki.params['category_list_size'].lower() == 'full list':
- payload['urlCategoryListSize'] = "fullList"
- path = meraki.construct_path('policy', net_id=net_id)
- current = meraki.request(path, method='GET')
- proposed = current.copy()
- proposed.update(payload)
- if meraki.is_update_required(current, payload) is True:
- meraki.result['diff'] = dict()
- diff = recursive_diff(current, payload)
- meraki.result['diff']['before'] = diff[0]
- meraki.result['diff']['after'] = diff[1]
- if module.check_mode:
- current.update(payload)
- meraki.result['changed'] = True
- meraki.result['data'] = current
- meraki.exit_json(**meraki.result)
- response = meraki.request(path, method='PUT', payload=json.dumps(payload))
- meraki.result['data'] = response
- meraki.result['changed'] = True
- else:
- meraki.result['data'] = current
- if module.check_mode:
- meraki.result['data'] = current
- meraki.exit_json(**meraki.result)
- meraki.result['data'] = current
- meraki.exit_json(**meraki.result)
-
- # 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()
diff --git a/lib/ansible/modules/network/meraki/meraki_device.py b/lib/ansible/modules/network/meraki/meraki_device.py
deleted file mode 100644
index 72662959f5..0000000000
--- a/lib/ansible/modules/network/meraki/meraki_device.py
+++ /dev/null
@@ -1,430 +0,0 @@
-#!/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_device
-short_description: Manage devices in the Meraki cloud
-version_added: "2.7"
-description:
-- Visibility into devices associated to a Meraki environment.
-notes:
-- This module does not support claiming of devices or licenses into a Meraki organization.
-- 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.
-options:
- state:
- description:
- - Query an organization.
- choices: [absent, present, query]
- default: query
- type: str
- net_name:
- description:
- - Name of a network.
- aliases: [network]
- type: str
- net_id:
- description:
- - ID of a network.
- type: str
- serial:
- description:
- - Serial number of a device to query.
- type: str
- hostname:
- description:
- - Hostname of network device to search for.
- aliases: [name]
- type: str
- model:
- description:
- - Model of network device to search for.
- type: str
- tags:
- description:
- - Space delimited list of tags to assign to device.
- type: str
- lat:
- description:
- - Latitude of device's geographic location.
- - Use negative number for southern hemisphere.
- aliases: [latitude]
- type: float
- lng:
- description:
- - Longitude of device's geographic location.
- - Use negative number for western hemisphere.
- aliases: [longitude]
- type: float
- address:
- description:
- - Postal address of device's location.
- type: str
- move_map_marker:
- description:
- - Whether or not to set the latitude and longitude of a device based on the new address.
- - Only applies when C(lat) and C(lng) are not specified.
- type: bool
- serial_lldp_cdp:
- description:
- - Serial number of device to query LLDP/CDP information from.
- type: str
- lldp_cdp_timespan:
- description:
- - Timespan, in seconds, used to query LLDP and CDP information.
- - Must be less than 1 month.
- type: int
- serial_uplink:
- description:
- - Serial number of device to query uplink information from.
- type: str
- note:
- description:
- - Informational notes about a device.
- - Limited to 255 characters.
- version_added: '2.8'
- type: str
-
-
-author:
-- Kevin Breit (@kbreit)
-extends_documentation_fragment: meraki
-'''
-
-EXAMPLES = r'''
-- name: Query all devices in an organization.
- meraki_device:
- auth_key: abc12345
- org_name: YourOrg
- state: query
- delegate_to: localhost
-
-- name: Query all devices in a network.
- meraki_device:
- auth_key: abc12345
- org_name: YourOrg
- net_name: YourNet
- state: query
- delegate_to: localhost
-
-- name: Query a device by serial number.
- meraki_device:
- auth_key: abc12345
- org_name: YourOrg
- net_name: YourNet
- serial: ABC-123
- state: query
- delegate_to: localhost
-
-- name: Lookup uplink information about a device.
- meraki_device:
- auth_key: abc12345
- org_name: YourOrg
- net_name: YourNet
- serial_uplink: ABC-123
- state: query
- delegate_to: localhost
-
-- name: Lookup LLDP and CDP information about devices connected to specified device.
- meraki_device:
- auth_key: abc12345
- org_name: YourOrg
- net_name: YourNet
- serial_lldp_cdp: ABC-123
- state: query
- delegate_to: localhost
-
-- name: Lookup a device by hostname.
- meraki_device:
- auth_key: abc12345
- org_name: YourOrg
- net_name: YourNet
- hostname: main-switch
- state: query
- delegate_to: localhost
-
-- name: Query all devices of a specific model.
- meraki_device:
- auth_key: abc123
- org_name: YourOrg
- net_name: YourNet
- model: MR26
- state: query
- delegate_to: localhost
-
-- name: Update information about a device.
- meraki_device:
- auth_key: abc123
- org_name: YourOrg
- net_name: YourNet
- state: present
- serial: '{{serial}}'
- name: mr26
- address: 1060 W. Addison St., Chicago, IL
- lat: 41.948038
- lng: -87.65568
- tags: recently-added
- delegate_to: localhost
-
-- name: Claim a device into a network.
- meraki_device:
- auth_key: abc123
- org_name: YourOrg
- net_name: YourNet
- serial: ABC-123
- state: present
- delegate_to: localhost
-
-- name: Remove a device from a network.
- meraki_device:
- auth_key: abc123
- org_name: YourOrg
- net_name: YourNet
- serial: ABC-123
- state: absent
- delegate_to: localhost
-'''
-
-RETURN = r'''
-response:
- description: Data returned from Meraki dashboard.
- type: dict
- returned: info
-'''
-
-import os
-from ansible.module_utils.basic import AnsibleModule, json, env_fallback
-from ansible.module_utils._text import to_native
-from ansible.module_utils.network.meraki.meraki import MerakiModule, meraki_argument_spec
-
-
-def format_tags(tags):
- return " {tags} ".format(tags=tags)
-
-
-def is_device_valid(meraki, serial, data):
- for device in data:
- if device['serial'] == serial:
- return True
- return False
-
-
-def get_org_devices(meraki, org_id):
- path = meraki.construct_path('get_all_org', org_id=org_id)
- response = meraki.request(path, method='GET')
- if meraki.status != 200:
- meraki.fail_json(msg='Failed to query all devices belonging to the organization')
- return response
-
-
-def main():
-
- # define the available arguments/parameters that a user can pass to
- # the module
- argument_spec = meraki_argument_spec()
- argument_spec.update(state=dict(type='str', choices=['absent', 'present', 'query'], default='query'),
- net_name=dict(type='str', aliases=['network']),
- net_id=dict(type='str'),
- serial=dict(type='str'),
- serial_uplink=dict(type='str'),
- serial_lldp_cdp=dict(type='str'),
- lldp_cdp_timespan=dict(type='int'),
- hostname=dict(type='str', aliases=['name']),
- model=dict(type='str'),
- tags=dict(type='str'),
- lat=dict(type='float', aliases=['latitude']),
- lng=dict(type='float', aliases=['longitude']),
- address=dict(type='str'),
- move_map_marker=dict(type='bool'),
- note=dict(type='str'),
- )
-
- # 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='device')
-
- if meraki.params['serial_lldp_cdp'] and not meraki.params['lldp_cdp_timespan']:
- meraki.fail_json(msg='lldp_cdp_timespan is required when querying LLDP and CDP information')
- if meraki.params['net_name'] and meraki.params['net_id']:
- meraki.fail_json(msg='net_name and net_id are mutually exclusive')
-
- meraki.params['follow_redirects'] = 'all'
-
- query_urls = {'device': '/networks/{net_id}/devices'}
- query_org_urls = {'device': '/organizations/{org_id}/inventory'}
- query_device_urls = {'device': '/networks/{net_id}/devices/'}
- claim_device_urls = {'device': '/networks/{net_id}/devices/claim'}
- bind_org_urls = {'device': '/organizations/{org_id}/claim'}
- update_device_urls = {'device': '/networks/{net_id}/devices/'}
- delete_device_urls = {'device': '/networks/{net_id}/devices/'}
-
- meraki.url_catalog['get_all'].update(query_urls)
- meraki.url_catalog['get_all_org'] = query_org_urls
- meraki.url_catalog['get_device'] = query_device_urls
- meraki.url_catalog['create'] = claim_device_urls
- meraki.url_catalog['bind_org'] = bind_org_urls
- meraki.url_catalog['update'] = update_device_urls
- meraki.url_catalog['delete'] = delete_device_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)
- org_id = meraki.params['org_id']
- if org_id is None:
- org_id = meraki.get_org_id(meraki.params['org_name'])
- nets = meraki.get_nets(org_id=org_id)
- net_id = None
- if meraki.params['net_id'] or meraki.params['net_name']:
- net_id = meraki.params['net_id']
- if net_id is None:
- net_id = meraki.get_net_id(net_name=meraki.params['net_name'], data=nets)
-
- if meraki.params['state'] == 'query':
- if meraki.params['net_name'] or meraki.params['net_id']:
- device = []
- if meraki.params['serial']:
- path = meraki.construct_path('get_device', net_id=net_id) + meraki.params['serial']
- request = meraki.request(path, method='GET')
- device.append(request)
- meraki.result['data'] = device
- elif meraki.params['serial_uplink']:
- path = meraki.construct_path('get_device', net_id=net_id) + meraki.params['serial_uplink'] + '/uplink'
- meraki.result['data'] = (meraki.request(path, method='GET'))
- elif meraki.params['serial_lldp_cdp']:
- if meraki.params['lldp_cdp_timespan'] > 2592000:
- meraki.fail_json(msg='LLDP/CDP timespan must be less than a month (2592000 seconds)')
- path = meraki.construct_path('get_device', net_id=net_id) + meraki.params['serial_lldp_cdp'] + '/lldp_cdp'
- path = path + '?timespan=' + str(meraki.params['lldp_cdp_timespan'])
- device.append(meraki.request(path, method='GET'))
- meraki.result['data'] = device
- elif meraki.params['hostname']:
- path = meraki.construct_path('get_all', net_id=net_id)
- devices = meraki.request(path, method='GET')
- for unit in devices:
- try:
- if unit['name'] == meraki.params['hostname']:
- device.append(unit)
- meraki.result['data'] = device
- except KeyError:
- pass
- elif meraki.params['model']:
- path = meraki.construct_path('get_all', net_id=net_id)
- devices = meraki.request(path, method='GET')
- device_match = []
- for device in devices:
- if device['model'] == meraki.params['model']:
- device_match.append(device)
- meraki.result['data'] = device_match
- else:
- path = meraki.construct_path('get_all', net_id=net_id)
- request = meraki.request(path, method='GET')
- meraki.result['data'] = request
- else:
- path = meraki.construct_path('get_all_org', org_id=org_id)
- devices = meraki.request(path, method='GET')
- if meraki.params['serial']:
- for device in devices:
- if device['serial'] == meraki.params['serial']:
- meraki.result['data'] = device
- else:
- meraki.result['data'] = devices
- elif meraki.params['state'] == 'present':
- device = []
- if meraki.params['hostname']:
- query_path = meraki.construct_path('get_all', net_id=net_id)
- device_list = meraki.request(query_path, method='GET')
- if is_device_valid(meraki, meraki.params['serial'], device_list):
- payload = {'name': meraki.params['hostname'],
- 'tags': format_tags(meraki.params['tags']),
- 'lat': meraki.params['lat'],
- 'lng': meraki.params['lng'],
- 'address': meraki.params['address'],
- 'moveMapMarker': meraki.params['move_map_marker'],
- 'notes': meraki.params['note'],
- }
- query_path = meraki.construct_path('get_device', net_id=net_id) + meraki.params['serial']
- device_data = meraki.request(query_path, method='GET')
- ignore_keys = ['lanIp', 'serial', 'mac', 'model', 'networkId', 'moveMapMarker', 'wan1Ip', 'wan2Ip']
- # meraki.fail_json(msg="Compare", original=device_data, payload=payload, ignore=ignore_keys)
- if meraki.is_update_required(device_data, payload, optional_ignore=ignore_keys):
- path = meraki.construct_path('update', net_id=net_id) + meraki.params['serial']
- updated_device = []
- updated_device.append(meraki.request(path, method='PUT', payload=json.dumps(payload)))
- meraki.result['data'] = updated_device
- meraki.result['changed'] = True
- else:
- meraki.result['data'] = device_data
- else:
- if net_id is None:
- device_list = get_org_devices(meraki, org_id)
- if is_device_valid(meraki, meraki.params['serial'], device_list) is False:
- payload = {'serial': meraki.params['serial']}
- path = meraki.construct_path('bind_org', org_id=org_id)
- created_device = []
- created_device.append(meraki.request(path, method='POST', payload=json.dumps(payload)))
- meraki.result['data'] = created_device
- meraki.result['changed'] = True
- else:
- query_path = meraki.construct_path('get_all', net_id=net_id)
- device_list = meraki.request(query_path, method='GET')
- if is_device_valid(meraki, meraki.params['serial'], device_list) is False:
- if net_id:
- payload = {'serial': meraki.params['serial']}
- path = meraki.construct_path('create', net_id=net_id)
- created_device = []
- created_device.append(meraki.request(path, method='POST', payload=json.dumps(payload)))
- meraki.result['data'] = created_device
- meraki.result['changed'] = True
- elif meraki.params['state'] == 'absent':
- device = []
- query_path = meraki.construct_path('get_all', net_id=net_id)
- device_list = meraki.request(query_path, method='GET')
- if is_device_valid(meraki, meraki.params['serial'], device_list) is True:
- path = meraki.construct_path('delete', net_id=net_id)
- path = path + meraki.params['serial'] + '/remove'
- request = meraki.request(path, method='POST')
- 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()
diff --git a/lib/ansible/modules/network/meraki/meraki_firewalled_services.py b/lib/ansible/modules/network/meraki/meraki_firewalled_services.py
deleted file mode 100644
index 43842c343f..0000000000
--- a/lib/ansible/modules/network/meraki/meraki_firewalled_services.py
+++ /dev/null
@@ -1,238 +0,0 @@
-#!/usr/bin/python
-# -*- coding: utf-8 -*-
-
-# Copyright: (c) 2019, 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_firewalled_services
-short_description: Edit firewall policies for administrative network services
-version_added: "2.9"
-description:
-- Allows for setting policy firewalled services for Meraki network devices.
-
-options:
- auth_key:
- description:
- - Authentication key provided by the dashboard. Required if environmental variable MERAKI_KEY is not set.
- type: str
- net_name:
- description:
- - Name of a network.
- aliases: [ network ]
- type: str
- net_id:
- description:
- - ID number of a network.
- type: str
- org_name:
- description:
- - Name of organization associated to a network.
- type: str
- org_id:
- description:
- - ID of organization associated to a network.
- type: str
- state:
- description:
- - States that a policy should be created or modified.
- choices: [present, query]
- default: present
- type: str
- service:
- description:
- - Network service to query or modify.
- choices: [ICMP, SNMP, web]
- type: str
- access:
- description:
- - Network service to query or modify.
- choices: [blocked, restricted, unrestricted]
- type: str
- allowed_ips:
- description:
- - List of IP addresses allowed to access a service.
- - Only used when C(access) is set to restricted.
- type: list
-
-author:
- - Kevin Breit (@kbreit)
-extends_documentation_fragment: meraki
-'''
-
-EXAMPLES = r'''
-- name: Set icmp service to blocked
- meraki_firewalled_services:
- auth_key: '{{ auth_key }}'
- state: present
- org_name: '{{test_org_name}}'
- net_name: IntTestNetworkAppliance
- service: ICMP
- access: blocked
- delegate_to: localhost
-
-- name: Set icmp service to restricted
- meraki_firewalled_services:
- auth_key: abc123
- state: present
- org_name: YourOrg
- net_name: YourNet
- service: web
- access: restricted
- allowed_ips:
- - 192.0.1.1
- - 192.0.1.2
- delegate_to: localhost
-
-- name: Query appliance services
- meraki_firewalled_services:
- auth_key: abc123
- state: query
- org_name: YourOrg
- net_name: YourNet
- delegate_to: localhost
-
-- name: Query services
- meraki_firewalled_services:
- auth_key: abc123
- state: query
- org_name: YourOrg
- net_name: YourNet
- service: ICMP
- delegate_to: localhost
-'''
-
-RETURN = r'''
-data:
- description: List of network services.
- returned: info
- type: complex
- contains:
- access:
- description: Access assigned to a service type.
- returned: success
- type: str
- sample: unrestricted
- service:
- description: Service to apply policy to.
- returned: success
- type: str
- sample: ICMP
- allowed_ips:
- description: List of IP addresses to have access to service.
- returned: success
- type: str
- sample: 192.0.1.0
-'''
-
-from ansible.module_utils.basic import AnsibleModule, json
-from ansible.module_utils.common.dict_transformations import recursive_diff
-from ansible.module_utils.network.meraki.meraki import MerakiModule, meraki_argument_spec
-
-
-def main():
-
- # define the available arguments/parameters that a user can pass to
- # the module
-
- argument_spec = meraki_argument_spec()
- argument_spec.update(
- net_id=dict(type='str'),
- net_name=dict(type='str', aliases=['network']),
- state=dict(type='str', default='present', choices=['query', 'present']),
- service=dict(type='str', default=None, choices=['ICMP', 'SNMP', 'web']),
- access=dict(type='str', choices=['blocked', 'restricted', 'unrestricted']),
- allowed_ips=dict(type='list', elements='str'),
- )
-
- mutually_exclusive = [('net_name', 'net_id')]
-
- # 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,
- mutually_exclusive=mutually_exclusive
- )
-
- meraki = MerakiModule(module, function='firewalled_services')
- module.params['follow_redirects'] = 'all'
-
- net_services_urls = {'firewalled_services': '/networks/{net_id}/firewalledServices'}
- services_urls = {'firewalled_services': '/networks/{net_id}/firewalledServices/{service}'}
-
- meraki.url_catalog['network_services'] = net_services_urls
- meraki.url_catalog['service'] = services_urls
-
- # 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']
- if not org_id:
- org_id = meraki.get_org_id(meraki.params['org_name'])
- net_id = meraki.params['net_id']
- 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'] == 'present':
- if meraki.params['access'] != 'restricted' and meraki.params['allowed_ips'] is not None:
- meraki.fail_json(msg="allowed_ips is only allowed when access is restricted.")
- payload = {'access': meraki.params['access']}
- if meraki.params['access'] == 'restricted':
- payload['allowedIps'] = meraki.params['allowed_ips']
-
- if meraki.params['state'] == 'query':
- if meraki.params['service'] is None:
- path = meraki.construct_path('network_services', net_id=net_id)
- response = meraki.request(path, method='GET')
- meraki.result['data'] = response
- meraki.exit_json(**meraki.result)
- else:
- path = meraki.construct_path('service', net_id=net_id, custom={'service': meraki.params['service']})
- response = meraki.request(path, method='GET')
- meraki.result['data'] = response
- meraki.exit_json(**meraki.result)
- elif meraki.params['state'] == 'present':
- path = meraki.construct_path('service', net_id=net_id, custom={'service': meraki.params['service']})
- original = meraki.request(path, method='GET')
- if meraki.is_update_required(original, payload, optional_ignore=['service']):
- if meraki.check_mode is True:
- diff_payload = {'service': meraki.params['service']} # Need to add service as it's not in payload
- diff_payload.update(payload)
- diff = recursive_diff(original, diff_payload)
- original.update(payload)
- meraki.result['diff'] = {'before': diff[0],
- 'after': diff[1]}
- meraki.result['data'] = original
- meraki.result['changed'] = True
- meraki.exit_json(**meraki.result)
- path = meraki.construct_path('service', net_id=net_id, custom={'service': meraki.params['service']})
- response = meraki.request(path, method='PUT', payload=json.dumps(payload))
- if meraki.status == 200:
- diff = recursive_diff(original, response)
- meraki.result['diff'] = {'before': diff[0],
- 'after': diff[1]}
- meraki.result['data'] = response
- meraki.result['changed'] = True
- else:
- meraki.result['data'] = original
-
- # 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()
diff --git a/lib/ansible/modules/network/meraki/meraki_malware.py b/lib/ansible/modules/network/meraki/meraki_malware.py
deleted file mode 100644
index 93de320285..0000000000
--- a/lib/ansible/modules/network/meraki/meraki_malware.py
+++ /dev/null
@@ -1,276 +0,0 @@
-#!/usr/bin/python
-# -*- coding: utf-8 -*-
-
-# Copyright: (c) 2019, 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_malware
-short_description: Manage Malware Protection in the Meraki cloud
-version_added: "2.9"
-description:
-- Fully configure malware protection in a Meraki environment.
-notes:
-- Some of the options are likely only used for developers within Meraki.
-options:
- state:
- description:
- - Specifies whether object should be queried, created/modified, or removed.
- choices: [absent, present, query]
- default: query
- type: str
- net_name:
- description:
- - Name of network which configuration is applied to.
- aliases: [network]
- type: str
- net_id:
- description:
- - ID of network which configuration is applied to.
- type: str
- allowed_urls:
- description:
- - List of URLs to whitelist.
- suboptions:
- url:
- description:
- - URL string to allow.
- type: str
- comment:
- description:
- - Human readable information about URL.
- type: str
- allowed_files:
- description:
- - List of files to whitelist.
- suboptions:
- sha256:
- description:
- - 256-bit hash of file.
- type: str
- aliases: [ hash ]
- comment:
- description:
- - Human readable information about file.
- type: str
- mode:
- description:
- - Enabled or disabled state of malware protection.
- choices: [disabled, enabled]
-
-
-author:
-- Kevin Breit (@kbreit)
-extends_documentation_fragment: meraki
-'''
-
-EXAMPLES = r'''
- - name: Enable malware protection
- meraki_malware:
- auth_key: abc123
- state: present
- org_name: YourOrg
- net_name: YourNet
- mode: enabled
- delegate_to: localhost
-
- - name: Set whitelisted url
- meraki_malware:
- auth_key: abc123
- state: present
- org_name: YourOrg
- net_name: YourNet
- mode: enabled
- allowed_urls:
- - url: www.google.com
- comment: Google
- delegate_to: localhost
-
- - name: Set whitelisted file
- meraki_malware:
- auth_key: abc123
- state: present
- org_name: YourOrg
- net_name: YourNet
- mode: enabled
- allowed_files:
- - sha256: e82c5f7d75004727e1f3b94426b9a11c8bc4c312a9170ac9a73abace40aef503
- comment: random zip
- delegate_to: localhost
-
- - name: Get malware settings
- meraki_malware:
- auth_key: abc123
- state: query
- org_name: YourNet
- net_name: YourOrg
- delegate_to: localhost
-'''
-
-RETURN = r'''
-data:
- description: List of administrators.
- returned: success
- type: complex
- contains:
- mode:
- description: Mode to enable or disable malware scanning.
- returned: success
- type: str
- sample: enabled
- allowed_files:
- description: List of files which are whitelisted.
- returned: success
- type: complex
- contains:
- sha256:
- description: sha256 hash of whitelisted file.
- returned: success
- type: str
- sample: e82c5f7d75004727e1f3b94426b9a11c8bc4c312a9170ac9a73abace40aef503
- comment:
- description: Comment about the whitelisted entity
- returned: success
- type: str
- sample: TPS report
- allowed_urls:
- description: List of URLs which are whitelisted.
- returned: success
- type: complex
- contains:
- url:
- description: URL of whitelisted site.
- returned: success
- type: str
- sample: site.com
- comment:
- description: Comment about the whitelisted entity
- returned: success
- type: str
- sample: Corporate HQ
-'''
-
-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
-
-
-def main():
- # define the available arguments/parameters that a user can pass to
- # the module
-
- urls_arg_spec = dict(url=dict(type='str'),
- comment=dict(type='str'),
- )
-
- files_arg_spec = dict(sha256=dict(type='str', aliases=['hash']),
- comment=dict(type='str'),
- )
-
- argument_spec = meraki_argument_spec()
- argument_spec.update(state=dict(type='str', choices=['absent', 'present', 'query'], default='query'),
- net_name=dict(type='str', aliases=['network']),
- net_id=dict(type='str'),
- mode=dict(type='str', choices=['enabled', 'disabled']),
- allowed_urls=dict(type='list', default=None, elements='dict', options=urls_arg_spec),
- allowed_files=dict(type='list', default=None, elements='dict', options=files_arg_spec),
- )
-
- # 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='malware')
-
- meraki.params['follow_redirects'] = 'all'
-
- query_url = {'malware': '/networks/{net_id}/security/malwareSettings'}
- update_url = {'malware': '/networks/{net_id}/security/malwareSettings'}
-
- meraki.url_catalog['get_one'].update(query_url)
- meraki.url_catalog['update'] = update_url
-
- org_id = meraki.params['org_id']
- if org_id is None:
- org_id = meraki.get_org_id(meraki.params['org_name'])
- net_id = meraki.params['net_id']
- if net_id is None:
- nets = meraki.get_nets(org_id=org_id)
- net_id = meraki.get_net_id(net_name=meraki.params['net_name'], data=nets)
-
- # Check for argument completeness
- if meraki.params['state'] == 'present':
- if meraki.params['allowed_files'] is not None or meraki.params['allowed_urls'] is not None:
- if meraki.params['mode'] is None:
- meraki.fail_json(msg="mode must be set when allowed_files or allowed_urls is set.")
-
- # Assemble payload
- if meraki.params['state'] == 'present':
- payload = dict()
- if meraki.params['mode'] is not None:
- payload['mode'] = meraki.params['mode']
- if meraki.params['allowed_urls'] is not None:
- payload['allowedUrls'] = meraki.params['allowed_urls']
- if meraki.params['allowed_files'] is not None:
- payload['allowedFiles'] = meraki.params['allowed_files']
-
- if meraki.params['state'] == 'query':
- path = meraki.construct_path('get_one', net_id=net_id)
- data = meraki.request(path, method='GET')
- if meraki.status == 200:
- meraki.result['data'] = data
- elif meraki.params['state'] == 'present':
- path = meraki.construct_path('get_one', net_id=net_id)
- original = meraki.request(path, method='GET')
- if meraki.is_update_required(original, payload):
- if meraki.module.check_mode is True:
- diff = recursive_diff(original, payload)
- original.update(payload)
- meraki.result['diff'] = {'before': diff[0],
- 'after': diff[1],
- }
- meraki.result['data'] = original
- meraki.result['changed'] = True
- meraki.exit_json(**meraki.result)
- path = meraki.construct_path('update', net_id=net_id)
- data = meraki.request(path, method='PUT', payload=json.dumps(payload))
- if meraki.status == 200:
- diff = recursive_diff(original, payload)
- meraki.result['diff'] = {'before': diff[0],
- 'after': diff[1],
- }
- meraki.result['data'] = data
- meraki.result['changed'] = True
- else:
- meraki.result['data'] = original
-
- # 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()
diff --git a/lib/ansible/modules/network/meraki/meraki_mr_l3_firewall.py b/lib/ansible/modules/network/meraki/meraki_mr_l3_firewall.py
deleted file mode 100644
index 2b07373d95..0000000000
--- a/lib/ansible/modules/network/meraki/meraki_mr_l3_firewall.py
+++ /dev/null
@@ -1,283 +0,0 @@
-#!/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_mr_l3_firewall
-short_description: Manage MR access point layer 3 firewalls in the Meraki cloud
-version_added: "2.7"
-description:
-- Allows for creation, management, and visibility into layer 3 firewalls implemented on Meraki MR access points.
-- Module is not idempotent as of current release.
-options:
- state:
- description:
- - Create or modify an organization.
- type: str
- choices: [ present, query ]
- default: present
- net_name:
- description:
- - Name of network containing access points.
- type: str
- net_id:
- description:
- - ID of network containing access points.
- type: str
- number:
- description:
- - Number of SSID to apply firewall rule to.
- type: int
- aliases: [ ssid_number ]
- ssid_name:
- description:
- - Name of SSID to apply firewall rule to.
- type: str
- aliases: [ ssid ]
- allow_lan_access:
- description:
- - Sets whether devices can talk to other devices on the same LAN.
- type: bool
- default: yes
- rules:
- description:
- - List of firewall rules.
- type: list
- suboptions:
- policy:
- description:
- - Specifies the action that should be taken when rule is hit.
- type: str
- choices: [ allow, deny ]
- protocol:
- description:
- - Specifies protocol to match against.
- type: str
- choices: [ any, icmp, tcp, udp ]
- dest_port:
- description:
- - Comma-seperated list of destination ports to match.
- type: str
- dest_cidr:
- description:
- - Comma-separated list of CIDR notation networks to match.
- type: str
- comment:
- description:
- - Optional comment describing the firewall rule.
- type: str
-author:
-- Kevin Breit (@kbreit)
-extends_documentation_fragment: meraki
-'''
-
-EXAMPLES = r'''
-- name: Create single firewall rule
- meraki_mr_l3_firewall:
- auth_key: abc123
- state: present
- org_name: YourOrg
- net_id: 12345
- number: 1
- rules:
- - comment: Integration test rule
- policy: allow
- protocol: tcp
- dest_port: 80
- dest_cidr: 192.0.2.0/24
- allow_lan_access: no
- delegate_to: localhost
-
-- name: Enable local LAN access
- meraki_mr_l3_firewall:
- auth_key: abc123
- state: present
- org_name: YourOrg
- net_id: 123
- number: 1
- rules:
- allow_lan_access: yes
- delegate_to: localhost
-
-- name: Query firewall rules
- meraki_mr_l3_firewall:
- auth_key: abc123
- state: query
- org_name: YourOrg
- net_name: YourNet
- number: 1
- delegate_to: localhost
-'''
-
-RETURN = r'''
-
-'''
-
-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 assemble_payload(meraki):
- params_map = {'policy': 'policy',
- 'protocol': 'protocol',
- 'dest_port': 'destPort',
- 'dest_cidr': 'destCidr',
- 'comment': 'comment',
- }
- rules = []
- for rule in meraki.params['rules']:
- proposed_rule = dict()
- for k, v in rule.items():
- proposed_rule[params_map[k]] = v
- rules.append(proposed_rule)
- payload = {'rules': rules}
- return payload
-
-
-def get_rules(meraki, net_id, number):
- path = meraki.construct_path('get_all', net_id=net_id, custom={'number': number})
- response = meraki.request(path, method='GET')
- if meraki.status == 200:
- return response
-
-
-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():
- # define the available arguments/parameters that a user can pass to
- # the module
-
- fw_rules = dict(policy=dict(type='str', choices=['allow', 'deny']),
- protocol=dict(type='str', choices=['tcp', 'udp', 'icmp', 'any']),
- dest_port=dict(type='str'),
- dest_cidr=dict(type='str'),
- comment=dict(type='str'),
- )
-
- argument_spec = meraki_argument_spec()
- argument_spec.update(state=dict(type='str', choices=['present', 'query'], default='present'),
- net_name=dict(type='str'),
- net_id=dict(type='str'),
- number=dict(type='str', aliases=['ssid_number']),
- ssid_name=dict(type='str', aliases=['ssid']),
- rules=dict(type='list', default=None, elements='dict', options=fw_rules),
- allow_lan_access=dict(type='bool', default=True),
- )
-
- # 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='mr_l3_firewall')
-
- meraki.params['follow_redirects'] = 'all'
-
- query_urls = {'mr_l3_firewall': '/networks/{net_id}/ssids/{number}/l3FirewallRules'}
- update_urls = {'mr_l3_firewall': '/networks/{net_id}/ssids/{number}/l3FirewallRules'}
-
- meraki.url_catalog['get_all'].update(query_urls)
- meraki.url_catalog['update'] = update_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)
- org_id = meraki.params['org_id']
- orgs = None
- if org_id is None:
- orgs = meraki.get_orgs()
- for org in orgs:
- if org['name'] == meraki.params['org_name']:
- org_id = org['id']
- net_id = meraki.params['net_id']
- if net_id is None:
- if orgs is None:
- orgs = meraki.get_orgs()
- net_id = meraki.get_net_id(net_name=meraki.params['net_name'],
- data=meraki.get_nets(org_id=org_id))
- number = meraki.params['number']
- if meraki.params['ssid_name']:
- number = get_ssid_number(meraki.params['ssid_name'], get_ssids(meraki, net_id))
-
- if meraki.params['state'] == 'query':
- meraki.result['data'] = get_rules(meraki, net_id, number)
- elif meraki.params['state'] == 'present':
- rules = get_rules(meraki, net_id, number)
- path = meraki.construct_path('get_all', net_id=net_id, custom={'number': number})
- if meraki.params['rules']:
- payload = assemble_payload(meraki)
- else:
- payload = dict()
- update = False
- try:
- if len(rules) != len(payload['rules']): # Quick and simple check to avoid more processing
- update = True
- if update is False:
- for r in range(len(rules) - 2):
- if meraki.is_update_required(rules[r], payload[r]) is True:
- update = True
- except KeyError:
- pass
- if rules[len(rules) - 2] != meraki.params['allow_lan_access']:
- update = True
- if update is True:
- payload['allowLanAccess'] = meraki.params['allow_lan_access']
- response = meraki.request(path, method='PUT', payload=json.dumps(payload))
- if meraki.status == 200:
- meraki.result['data'] = response
- meraki.result['changed'] = True
- else:
- meraki.result['data'] = rules
-
- # 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()
diff --git a/lib/ansible/modules/network/meraki/meraki_mx_l3_firewall.py b/lib/ansible/modules/network/meraki/meraki_mx_l3_firewall.py
deleted file mode 100644
index db83164742..0000000000
--- a/lib/ansible/modules/network/meraki/meraki_mx_l3_firewall.py
+++ /dev/null
@@ -1,328 +0,0 @@
-#!/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_mx_l3_firewall
-short_description: Manage MX appliance layer 3 firewalls in the Meraki cloud
-version_added: "2.7"
-description:
-- Allows for creation, management, and visibility into layer 3 firewalls implemented on Meraki MX firewalls.
-notes:
-- Module assumes a complete list of firewall rules are passed as a parameter.
-- If there is interest in this module allowing manipulation of a single firewall rule, please submit an issue against this module.
-options:
- state:
- description:
- - Create or modify an organization.
- choices: ['present', 'query']
- default: present
- net_name:
- description:
- - Name of network which MX firewall is in.
- net_id:
- description:
- - ID of network which MX firewall is in.
- rules:
- description:
- - List of firewall rules.
- suboptions:
- policy:
- description:
- - Policy to apply if rule is hit.
- choices: [allow, deny]
- protocol:
- description:
- - Protocol to match against.
- choices: [any, icmp, tcp, udp]
- dest_port:
- description:
- - Comma separated list of destination port numbers to match against.
- dest_cidr:
- description:
- - Comma separated list of CIDR notation destination networks.
- src_port:
- description:
- - Comma separated list of source port numbers to match against.
- src_cidr:
- description:
- - Comma separated list of CIDR notation source networks.
- comment:
- description:
- - Optional comment to describe the firewall rule.
- syslog_enabled:
- description:
- - Whether to log hints against the firewall rule.
- - Only applicable if a syslog server is specified against the network.
-
- syslog_default_rule:
- description:
- - Whether to log hits against the default firewall rule.
- - Only applicable if a syslog server is specified against the network.
- - This is not shown in response from Meraki. Instead, refer to the C(syslog_enabled) value in the default rule.
- type: bool
- default: no
-author:
-- Kevin Breit (@kbreit)
-extends_documentation_fragment: meraki
-'''
-
-EXAMPLES = r'''
-- name: Query firewall rules
- meraki_mx_l3_firewall:
- auth_key: abc123
- org_name: YourOrg
- net_name: YourNet
- state: query
- delegate_to: localhost
-
-- name: Set two firewall rules
- meraki_mx_l3_firewall:
- auth_key: abc123
- org_name: YourOrg
- net_name: YourNet
- state: present
- rules:
- - comment: Block traffic to server
- src_cidr: 192.0.1.0/24
- src_port: any
- dest_cidr: 192.0.2.2/32
- dest_port: any
- protocol: any
- policy: deny
- - comment: Allow traffic to group of servers
- src_cidr: 192.0.1.0/24
- src_port: any
- dest_cidr: 192.0.2.0/24
- dest_port: any
- protocol: any
- policy: permit
- delegate_to: localhost
-
-- name: Set one firewall rule and enable logging of the default rule
- meraki_mx_l3_firewall:
- auth_key: abc123
- org_name: YourOrg
- net_name: YourNet
- state: present
- rules:
- - comment: Block traffic to server
- src_cidr: 192.0.1.0/24
- src_port: any
- dest_cidr: 192.0.2.2/32
- dest_port: any
- protocol: any
- policy: deny
- syslog_default_rule: yes
- delegate_to: localhost
-'''
-
-RETURN = r'''
-data:
- description: Firewall rules associated to network.
- returned: success
- type: complex
- contains:
- comment:
- description: Comment to describe the firewall rule.
- returned: always
- type: str
- sample: Block traffic to server
- src_cidr:
- description: Comma separated list of CIDR notation source networks.
- returned: always
- type: str
- sample: 192.0.1.1/32,192.0.1.2/32
- src_port:
- description: Comma separated list of source ports.
- returned: always
- type: str
- sample: 80,443
- dest_cidr:
- description: Comma separated list of CIDR notation destination networks.
- returned: always
- type: str
- sample: 192.0.1.1/32,192.0.1.2/32
- dest_port:
- description: Comma separated list of destination ports.
- returned: always
- type: str
- sample: 80,443
- protocol:
- description: Network protocol for which to match against.
- returned: always
- type: str
- sample: tcp
- policy:
- description: Action to take when rule is matched.
- returned: always
- type: str
- syslog_enabled:
- description: Whether to log to syslog when rule is matched.
- returned: always
- type: bool
- sample: true
-'''
-
-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 assemble_payload(meraki):
- params_map = {'policy': 'policy',
- 'protocol': 'protocol',
- 'dest_port': 'destPort',
- 'dest_cidr': 'destCidr',
- 'src_port': 'srcPort',
- 'src_cidr': 'srcCidr',
- 'syslog_enabled': 'syslogEnabled',
- 'comment': 'comment',
- }
- rules = []
- for rule in meraki.params['rules']:
- proposed_rule = dict()
- for k, v in rule.items():
- proposed_rule[params_map[k]] = v
- rules.append(proposed_rule)
- payload = {'rules': rules}
- return payload
-
-
-def get_rules(meraki, net_id):
- path = meraki.construct_path('get_all', net_id=net_id)
- response = meraki.request(path, method='GET')
- if meraki.status == 200:
- return response
-
-
-def main():
- # define the available arguments/parameters that a user can pass to
- # the module
-
- fw_rules = dict(policy=dict(type='str', choices=['allow', 'deny']),
- protocol=dict(type='str', choices=['tcp', 'udp', 'icmp', 'any']),
- dest_port=dict(type='str'),
- dest_cidr=dict(type='str'),
- src_port=dict(type='str'),
- src_cidr=dict(type='str'),
- comment=dict(type='str'),
- syslog_enabled=dict(type='bool', default=False),
- )
-
- argument_spec = meraki_argument_spec()
- argument_spec.update(state=dict(type='str', choices=['present', 'query'], default='present'),
- net_name=dict(type='str'),
- net_id=dict(type='str'),
- rules=dict(type='list', default=None, elements='dict', options=fw_rules),
- syslog_default_rule=dict(type='bool'),
- )
-
- # 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='mx_l3_firewall')
-
- meraki.params['follow_redirects'] = 'all'
-
- query_urls = {'mx_l3_firewall': '/networks/{net_id}/l3FirewallRules/'}
- update_urls = {'mx_l3_firewall': '/networks/{net_id}/l3FirewallRules/'}
-
- meraki.url_catalog['get_all'].update(query_urls)
- meraki.url_catalog['update'] = update_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)
- org_id = meraki.params['org_id']
- orgs = None
- if org_id is None:
- orgs = meraki.get_orgs()
- for org in orgs:
- if org['name'] == meraki.params['org_name']:
- org_id = org['id']
- net_id = meraki.params['net_id']
- if net_id is None:
- if orgs is None:
- orgs = meraki.get_orgs()
- net_id = meraki.get_net_id(net_name=meraki.params['net_name'],
- data=meraki.get_nets(org_id=org_id))
-
- if meraki.params['state'] == 'query':
- meraki.result['data'] = get_rules(meraki, net_id)
- elif meraki.params['state'] == 'present':
- rules = get_rules(meraki, net_id)
- path = meraki.construct_path('get_all', net_id=net_id)
- if meraki.params['rules']:
- payload = assemble_payload(meraki)
- else:
- payload = dict()
- update = False
- if meraki.params['syslog_default_rule'] is not None:
- payload['syslogDefaultRule'] = meraki.params['syslog_default_rule']
- try:
- if len(rules) - 1 != len(payload['rules']): # Quick and simple check to avoid more processing
- update = True
- if meraki.params['syslog_default_rule'] is not None:
- if rules[len(rules) - 1]['syslogEnabled'] != meraki.params['syslog_default_rule']:
- update = True
- if update is False:
- default_rule = rules[len(rules) - 1].copy()
- del rules[len(rules) - 1] # Remove default rule for comparison
- for r in range(len(rules) - 1):
- if meraki.is_update_required(rules[r], payload['rules'][r]) is True:
- update = True
- rules.append(default_rule)
- except KeyError:
- pass
- if update is True:
- response = meraki.request(path, method='PUT', payload=json.dumps(payload))
- if meraki.status == 200:
- meraki.result['data'] = response
- meraki.result['changed'] = True
- else:
- meraki.result['data'] = rules
-
- # 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()
diff --git a/lib/ansible/modules/network/meraki/meraki_mx_l7_firewall.py b/lib/ansible/modules/network/meraki/meraki_mx_l7_firewall.py
deleted file mode 100644
index f8f87a2eaf..0000000000
--- a/lib/ansible/modules/network/meraki/meraki_mx_l7_firewall.py
+++ /dev/null
@@ -1,506 +0,0 @@
-#!/usr/bin/python
-# -*- coding: utf-8 -*-
-
-# Copyright: (c) 2019, 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_mx_l7_firewall
-short_description: Manage MX appliance layer 7 firewalls in the Meraki cloud
-version_added: "2.9"
-description:
-- Allows for creation, management, and visibility into layer 7 firewalls implemented on Meraki MX firewalls.
-notes:
-- Module assumes a complete list of firewall rules are passed as a parameter.
-- If there is interest in this module allowing manipulation of a single firewall rule, please submit an issue against this module.
-options:
- state:
- description:
- - Query or modify a firewall rule.
- choices: ['present', 'query']
- default: present
- type: str
- net_name:
- description:
- - Name of network which MX firewall is in.
- type: str
- net_id:
- description:
- - ID of network which MX firewall is in.
- type: str
- rules:
- description:
- - List of layer 7 firewall rules.
- type: list
- suboptions:
- policy:
- description:
- - Policy to apply if rule is hit.
- choices: [deny]
- default: deny
- type: str
- type:
- description:
- - Type of policy to apply.
- choices: [application,
- application_category,
- blacklisted_countries,
- host,
- ip_range,
- port,
- whitelisted_countries]
- type: str
- application:
- description:
- - Application to filter.
- suboptions:
- name:
- description:
- - Name of application to filter as defined by Meraki.
- type: str
- id:
- description:
- - URI of application as defined by Meraki.
- type: str
- application_category:
- description:
- - Category of applications to filter.
- suboptions:
- name:
- description:
- - Name of application category to filter as defined by Meraki.
- type: str
- id:
- description:
- - URI of application category as defined by Meraki.
- type: str
- host:
- description:
- - FQDN of host to filter.
- type: str
- ip_range:
- description:
- - CIDR notation range of IP addresses to apply rule to.
- - Port can be appended to range with a C(":").
- type: str
- port:
- description:
- - TCP or UDP based port to filter.
- type: str
- countries:
- description:
- - List of countries to whitelist or blacklist.
- - The countries follow the two-letter ISO 3166-1 alpha-2 format.
- type: list
- categories:
- description:
- - When C(True), specifies that applications and application categories should be queried instead of firewall rules.
- type: bool
-author:
-- Kevin Breit (@kbreit)
-extends_documentation_fragment: meraki
-'''
-
-EXAMPLES = r'''
-- name: Query firewall rules
- meraki_mx_l7_firewall:
- auth_key: abc123
- org_name: YourOrg
- net_name: YourNet
- state: query
- delegate_to: localhost
-
-- name: Query applications and application categories
- meraki_mx_l7_firewall:
- auth_key: abc123
- org_name: YourOrg
- net_name: YourNet
- categories: yes
- state: query
- delegate_to: localhost
-
-- name: Set firewall rules
- meraki_mx_l7_firewall:
- auth_key: abc123
- org_name: YourOrg
- net_name: YourNet
- state: present
- rules:
- - type: whitelisted_countries
- countries:
- - US
- - FR
- - type: blacklisted_countries
- countries:
- - CN
- - policy: deny
- type: port
- port: 8080
- - type: port
- port: 1234
- - type: host
- host: asdf.com
- - type: application
- application:
- id: meraki:layer7/application/205
- - type: application_category
- application:
- id: meraki:layer7/category/24
- delegate_to: localhost
-'''
-
-RETURN = r'''
-data:
- description: Firewall rules associated to network.
- returned: success
- type: complex
- contains:
- rules:
- description: Ordered list of firewall rules.
- returned: success, when not querying applications
- type: list
- contains:
- policy:
- description: Action to apply when rule is hit.
- returned: success
- type: str
- sample: deny
- type:
- description: Type of rule category.
- returned: success
- type: str
- sample: applications
- applications:
- description: List of applications within a category.
- type: list
- contains:
- id:
- description: URI of application.
- returned: success
- type: str
- sample: Gmail
- name:
- description: Descriptive name of application.
- returned: success
- type: str
- sample: meraki:layer7/application/4
- applicationCategory:
- description: List of application categories within a category.
- type: list
- contains:
- id:
- description: URI of application.
- returned: success
- type: str
- sample: Gmail
- name:
- description: Descriptive name of application.
- returned: success
- type: str
- sample: meraki:layer7/application/4
- port:
- description: Port number in rule.
- returned: success
- type: str
- sample: 23
- ipRange:
- description: Range of IP addresses in rule.
- returned: success
- type: str
- sample: 1.1.1.0/23
- whitelistedCountries:
- description: Countries to be whitelisted.
- returned: success
- type: str
- sample: CA
- blacklistedCountries:
- description: Countries to be blacklisted.
- returned: success
- type: str
- sample: RU
- application_categories:
- description: List of application categories and applications.
- type: list
- returned: success, when querying applications
- contains:
- applications:
- description: List of applications within a category.
- type: list
- contains:
- id:
- description: URI of application.
- returned: success
- type: str
- sample: Gmail
- name:
- description: Descriptive name of application.
- returned: success
- type: str
- sample: meraki:layer7/application/4
- id:
- description: URI of application category.
- returned: success
- type: str
- sample: Email
- name:
- description: Descriptive name of application category.
- returned: success
- type: str
- sample: layer7/category/1
-'''
-
-import copy
-import os
-from ansible.module_utils.basic import AnsibleModule, json, env_fallback
-from ansible.module_utils.common.dict_transformations import recursive_diff
-from ansible.module_utils.network.meraki.meraki import MerakiModule, meraki_argument_spec
-
-
-def get_applications(meraki, net_id):
- path = meraki.construct_path('get_categories', net_id=net_id)
- return meraki.request(path, method='GET')
-
-
-def lookup_application(meraki, net_id, application):
- response = get_applications(meraki, net_id)
- for category in response['applicationCategories']:
- if category['name'].lower() == application.lower():
- return category['id']
- for app in category['applications']:
- if app['name'].lower() == application.lower():
- return app['id']
- meraki.fail_json(msg="No application or category named {0} found".format(application))
-
-
-def assemble_payload(meraki, net_id, rule):
- if rule['type'] == 'application':
- new_rule = {'policy': rule['policy'],
- 'type': 'application',
- }
- if rule['application']['id']:
- new_rule['value'] = {'id': rule['application']['id']}
- elif rule['application']['name']:
- new_rule['value'] = {'id': lookup_application(meraki, net_id, rule['application']['name'])}
- elif rule['type'] == 'application_category':
- new_rule = {'policy': rule['policy'],
- 'type': 'applicationCategory',
- }
- if rule['application']['id']:
- new_rule['value'] = {'id': rule['application']['id']}
- elif rule['application']['name']:
- new_rule['value'] = {'id': lookup_application(meraki, net_id, rule['application']['name'])}
- elif rule['type'] == 'ip_range':
- new_rule = {'policy': rule['policy'],
- 'type': 'ipRange',
- 'value': rule['ip_range']}
- elif rule['type'] == 'host':
- new_rule = {'policy': rule['policy'],
- 'type': rule['type'],
- 'value': rule['host']}
- elif rule['type'] == 'port':
- new_rule = {'policy': rule['policy'],
- 'type': rule['type'],
- 'value': rule['port']}
- elif rule['type'] == 'blacklisted_countries':
- new_rule = {'policy': rule['policy'],
- 'type': 'blacklistedCountries',
- 'value': rule['countries']
- }
- elif rule['type'] == 'whitelisted_countries':
- new_rule = {'policy': rule['policy'],
- 'type': 'whitelistedCountries',
- 'value': rule['countries']
- }
- return new_rule
-
-
-def restructure_response(rules):
- for rule in rules['rules']:
- type = rule['type']
- rule[type] = copy.deepcopy(rule['value'])
- del rule['value']
- return rules
-
-
-def get_rules(meraki, net_id):
- path = meraki.construct_path('get_all', net_id=net_id)
- response = meraki.request(path, method='GET')
- if meraki.status == 200:
- return response
-
-
-def rename_id_to_appid(rules):
- for rule in rules['rules']:
- print(rule['type'])
- if rule['type'] == 'application' or rule['type'] == 'applicationCategory':
- rule['value']['appId'] = rule['value'].pop('id')
- return rules
-
-
-def rename_appid_to_id(rules):
- for rule in rules['rules']:
- if rule['type'] == 'application' or rule['type'] == 'applicationCategory':
- rule['value']['id'] = rule['value'].pop('appId')
- return rules
-
-
-def main():
- # define the available arguments/parameters that a user can pass to
- # the module
-
- application_arg_spec = dict(id=dict(type='str'),
- name=dict(type='str'),
- )
-
- rule_arg_spec = dict(policy=dict(type='str', choices=['deny'], default='deny'),
- type=dict(type='str', choices=['application',
- 'application_category',
- 'blacklisted_countries',
- 'host',
- 'ip_range',
- 'port',
- 'whitelisted_countries']),
- ip_range=dict(type='str'),
- application=dict(type='dict', default=None, options=application_arg_spec),
- host=dict(type='str'),
- port=dict(type='str'),
- countries=dict(type='list'),
- )
-
- argument_spec = meraki_argument_spec()
- argument_spec.update(state=dict(type='str', choices=['present', 'query'], default='present'),
- net_name=dict(type='str'),
- net_id=dict(type='str'),
- rules=dict(type='list', default=None, elements='dict', options=rule_arg_spec),
- categories=dict(type='bool'),
- )
-
- # 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='mx_l7_firewall')
-
- # check for argument completeness
- if meraki.params['rules']:
- for rule in meraki.params['rules']:
- if rule['type'] == 'application' and rule['application'] is None:
- meraki.fail_json(msg="application argument is required when type is application.")
- elif rule['type'] == 'application_category' and rule['application'] is None:
- meraki.fail_json(msg="application argument is required when type is application_category.")
- elif rule['type'] == 'blacklisted_countries' and rule['countries'] is None:
- meraki.fail_json(msg="countries argument is required when type is blacklisted_countries.")
- elif rule['type'] == 'host' and rule['host'] is None:
- meraki.fail_json(msg="host argument is required when type is host.")
- elif rule['type'] == 'port' and rule['port'] is None:
- meraki.fail_json(msg="port argument is required when type is port.")
- elif rule['type'] == 'whitelisted_countries' and rule['countries'] is None:
- meraki.fail_json(msg="countries argument is required when type is whitelisted_countries.")
-
- meraki.params['follow_redirects'] = 'all'
-
- query_urls = {'mx_l7_firewall': '/networks/{net_id}/l7FirewallRules/'}
- query_category_urls = {'mx_l7_firewall': '/networks/{net_id}/l7FirewallRules/applicationCategories'}
- update_urls = {'mx_l7_firewall': '/networks/{net_id}/l7FirewallRules/'}
-
- meraki.url_catalog['get_all'].update(query_urls)
- meraki.url_catalog['get_categories'] = (query_category_urls)
- meraki.url_catalog['update'] = update_urls
-
- payload = None
-
- # 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']
- orgs = None
- if org_id is None:
- orgs = meraki.get_orgs()
- for org in orgs:
- if org['name'] == meraki.params['org_name']:
- org_id = org['id']
- net_id = meraki.params['net_id']
- if net_id is None:
- if orgs is None:
- orgs = meraki.get_orgs()
- net_id = meraki.get_net_id(net_name=meraki.params['net_name'],
- data=meraki.get_nets(org_id=org_id))
-
- if meraki.params['state'] == 'query':
- if meraki.params['categories'] is True: # Output only applications
- meraki.result['data'] = get_applications(meraki, net_id)
- else:
- meraki.result['data'] = restructure_response(get_rules(meraki, net_id))
- elif meraki.params['state'] == 'present':
- rules = get_rules(meraki, net_id)
- path = meraki.construct_path('get_all', net_id=net_id)
- if meraki.params['rules']:
- payload = {'rules': []}
- for rule in meraki.params['rules']:
- payload['rules'].append(assemble_payload(meraki, net_id, rule))
- else:
- payload = dict()
-
- '''
- The rename_* functions are needed because the key is id and
- is_update_required() by default ignores id.
- '''
- rules = rename_id_to_appid(rules)
- payload = rename_id_to_appid(payload)
- if meraki.is_update_required(rules, payload):
- rules = rename_appid_to_id(rules)
- payload = rename_appid_to_id(payload)
- if meraki.module.check_mode is True:
- response = restructure_response(payload)
- diff = recursive_diff(restructure_response(rules), response)
- meraki.result['diff'] = {'before': diff[0],
- 'after': diff[1],
- }
- meraki.result['data'] = response
- meraki.result['changed'] = True
- meraki.exit_json(**meraki.result)
- response = meraki.request(path, method='PUT', payload=json.dumps(payload))
- response = restructure_response(response)
- if meraki.status == 200:
- diff = recursive_diff(restructure_response(rules), response)
- meraki.result['diff'] = {'before': diff[0],
- 'after': diff[1],
- }
- meraki.result['data'] = response
- meraki.result['changed'] = True
- else:
- rules = rename_appid_to_id(rules)
- payload = rename_appid_to_id(payload)
- if meraki.module.check_mode is True:
- meraki.result['data'] = rules
- meraki.result['changed'] = False
- meraki.exit_json(**meraki.result)
- meraki.result['data'] = payload
-
- # 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()
diff --git a/lib/ansible/modules/network/meraki/meraki_nat.py b/lib/ansible/modules/network/meraki/meraki_nat.py
deleted file mode 100644
index 69c2f7e657..0000000000
--- a/lib/ansible/modules/network/meraki/meraki_nat.py
+++ /dev/null
@@ -1,673 +0,0 @@
-#!/usr/bin/python
-# -*- coding: utf-8 -*-
-
-# Copyright: (c) 2019, 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_nat
-short_description: Manage NAT rules in Meraki cloud
-version_added: "2.9"
-description:
-- Allows for creation, management, and visibility of NAT rules (1:1, 1:many, port forwarding) within Meraki.
-
-options:
- state:
- description:
- - Create or modify an organization.
- choices: [present, query]
- default: present
- type: str
- net_name:
- description:
- - Name of a network.
- aliases: [name, network]
- type: str
- net_id:
- description:
- - ID number of a network.
- type: str
- org_id:
- description:
- - ID of organization associated to a network.
- type: str
- subset:
- description:
- - Specifies which NAT components to query.
- choices: ['1:1', '1:many', all, port_forwarding]
- default: all
- type: list
- one_to_one:
- description:
- - List of 1:1 NAT rules.
- type: list
- suboptions:
- name:
- description:
- - A descriptive name for the rule.
- type: str
- public_ip:
- description:
- - The IP address that will be used to access the internal resource from the WAN.
- type: str
- lan_ip:
- description:
- - The IP address of the server or device that hosts the internal resource that you wish to make available on the WAN.
- type: str
- uplink:
- description:
- - The physical WAN interface on which the traffic will arrive.
- choices: [both, internet1, internet2]
- type: str
- allowed_inbound:
- description:
- - The ports this mapping will provide access on, and the remote IPs that will be allowed access to the resource.
- type: list
- suboptions:
- protocol:
- description:
- - Protocol to apply NAT rule to.
- choices: [any, icmp-ping, tcp, udp]
- type: str
- default: any
- destination_ports:
- description:
- - List of ports or port ranges that will be forwarded to the host on the LAN.
- type: list
- allowed_ips:
- description:
- - ranges of WAN IP addresses that are allowed to make inbound connections on the specified ports or port ranges, or 'any'.
- type: list
- one_to_many:
- description:
- - List of 1:many NAT rules.
- type: list
- suboptions:
- public_ip:
- description:
- - The IP address that will be used to access the internal resource from the WAN.
- type: str
- uplink:
- description:
- - The physical WAN interface on which the traffic will arrive.
- choices: [both, internet1, internet2]
- type: str
- port_rules:
- description:
- - List of associated port rules.
- type: list
- suboptions:
- name:
- description:
- - A description of the rule.
- type: str
- protocol:
- description:
- - Protocol to apply NAT rule to.
- choices: [tcp, udp]
- type: str
- public_port:
- description:
- - Destination port of the traffic that is arriving on the WAN.
- type: str
- local_ip:
- description:
- - Local IP address to which traffic will be forwarded.
- type: str
- local_port:
- description:
- - Destination port of the forwarded traffic that will be sent from the MX to the specified host on the LAN.
- - If you simply wish to forward the traffic without translating the port, this should be the same as the Public port.
- type: str
- allowed_ips:
- description:
- - Remote IP addresses or ranges that are permitted to access the internal resource via this port forwarding rule, or 'any'.
- type: list
- port_forwarding:
- description:
- - List of port forwarding rules.
- type: list
- suboptions:
- name:
- description:
- - A descriptive name for the rule.
- type: str
- lan_ip:
- description:
- - The IP address of the server or device that hosts the internal resource that you wish to make available on the WAN.
- type: str
- uplink:
- description:
- - The physical WAN interface on which the traffic will arrive.
- choices: [both, internet1, internet2]
- type: str
- public_port:
- description:
- - A port or port ranges that will be forwarded to the host on the LAN.
- type: int
- local_port:
- description:
- - A port or port ranges that will receive the forwarded traffic from the WAN.
- type: int
- allowed_ips:
- description:
- - List of ranges of WAN IP addresses that are allowed to make inbound connections on the specified ports or port ranges (or any).
- type: list
- protocol:
- description:
- - Protocol to forward traffic for.
- choices: [tcp, udp]
- type: str
-
-author:
- - Kevin Breit (@kbreit)
-extends_documentation_fragment: meraki
-'''
-
-EXAMPLES = r'''
-- name: Query all NAT rules
- meraki_nat:
- auth_key: abc123
- org_name: YourOrg
- net_name: YourNet
- state: query
- subset: all
- delegate_to: localhost
-
-- name: Query 1:1 NAT rules
- meraki_nat:
- auth_key: abc123
- org_name: YourOrg
- net_name: YourNet
- state: query
- subset: '1:1'
- delegate_to: localhost
-
-- name: Create 1:1 rule
- meraki_nat:
- auth_key: abc123
- org_name: YourOrg
- net_name: YourNet
- state: present
- one_to_one:
- - name: Service behind NAT
- public_ip: 1.2.1.2
- lan_ip: 192.168.128.1
- uplink: internet1
- allowed_inbound:
- - protocol: tcp
- destination_ports:
- - 80
- allowed_ips:
- - 10.10.10.10
- delegate_to: localhost
-
-- name: Create 1:many rule
- meraki_nat:
- auth_key: abc123
- org_name: YourOrg
- net_name: YourNet
- state: present
- one_to_many:
- - public_ip: 1.1.1.1
- uplink: internet1
- port_rules:
- - name: Test rule
- protocol: tcp
- public_port: 10
- local_ip: 192.168.128.1
- local_port: 11
- allowed_ips:
- - any
- delegate_to: localhost
-
-- name: Create port forwarding rule
- meraki_nat:
- auth_key: abc123
- org_name: YourOrg
- net_name: YourNet
- state: present
- port_forwarding:
- - name: Test map
- lan_ip: 192.168.128.1
- uplink: both
- protocol: tcp
- allowed_ips:
- - 1.1.1.1
- public_port: 10
- local_port: 11
- delegate_to: localhost
-'''
-
-RETURN = r'''
-data:
- description: Information about the created or manipulated object.
- returned: success
- type: complex
- contains:
- one_to_one:
- description: Information about 1:1 NAT object.
- returned: success, when 1:1 NAT object is in task
- type: complex
- contains:
- rules:
- description: List of 1:1 NAT rules.
- returned: success, when 1:1 NAT object is in task
- type: complex
- contains:
- name:
- description: Name of NAT object.
- returned: success, when 1:1 NAT object is in task
- type: str
- example: Web server behind NAT
- lanIp:
- description: Local IP address to be mapped.
- returned: success, when 1:1 NAT object is in task
- type: str
- example: 192.168.128.22
- publicIp:
- description: Public IP address to be mapped.
- returned: success, when 1:1 NAT object is in task
- type: str
- example: 148.2.5.100
- uplink:
- description: Internet port where rule is applied.
- returned: success, when 1:1 NAT object is in task
- type: str
- example: internet1
- allowedInbound:
- description: List of inbound forwarding rules.
- returned: success, when 1:1 NAT object is in task
- type: complex
- contains:
- protocol:
- description: Protocol to apply NAT rule to.
- returned: success, when 1:1 NAT object is in task
- type: str
- example: tcp
- destinationPorts:
- description: Ports to apply NAT rule to.
- returned: success, when 1:1 NAT object is in task
- type: str
- example: 80
- allowedIps:
- description: List of IP addresses to be forwarded.
- returned: success, when 1:1 NAT object is in task
- type: list
- example: 10.80.100.0/24
- one_to_many:
- description: Information about 1:many NAT object.
- returned: success, when 1:many NAT object is in task
- type: complex
- contains:
- rules:
- description: List of 1:many NAT rules.
- returned: success, when 1:many NAT object is in task
- type: complex
- contains:
- publicIp:
- description: Public IP address to be mapped.
- returned: success, when 1:many NAT object is in task
- type: str
- example: 148.2.5.100
- uplink:
- description: Internet port where rule is applied.
- returned: success, when 1:many NAT object is in task
- type: str
- example: internet1
- portRules:
- description: List of NAT port rules.
- returned: success, when 1:many NAT object is in task
- type: complex
- contains:
- name:
- description: Name of NAT object.
- returned: success, when 1:many NAT object is in task
- type: str
- example: Web server behind NAT
- protocol:
- description: Protocol to apply NAT rule to.
- returned: success, when 1:1 NAT object is in task
- type: str
- example: tcp
- publicPort:
- description: Destination port of the traffic that is arriving on WAN.
- returned: success, when 1:1 NAT object is in task
- type: int
- example: 9443
- localIp:
- description: Local IP address traffic will be forwarded.
- returned: success, when 1:1 NAT object is in task
- type: str
- example: 192.0.2.10
- localPort:
- description: Destination port to be forwarded to.
- returned: success, when 1:1 NAT object is in task
- type: int
- example: 443
- allowedIps:
- description: List of IP addresses to be forwarded.
- returned: success, when 1:1 NAT object is in task
- type: list
- example: 10.80.100.0/24
- port_forwarding:
- description: Information about port forwarding rules.
- returned: success, when port forwarding is in task
- type: complex
- contains:
- rules:
- description: List of port forwarding rules.
- returned: success, when port forwarding is in task
- type: complex
- contains:
- lanIp:
- description: Local IP address to be mapped.
- returned: success, when port forwarding is in task
- type: str
- example: 192.168.128.22
- allowedIps:
- description: List of IP addresses to be forwarded.
- returned: success, when port forwarding is in task
- type: list
- example: 10.80.100.0/24
- name:
- description: Name of NAT object.
- returned: success, when port forwarding is in task
- type: str
- example: Web server behind NAT
- protocol:
- description: Protocol to apply NAT rule to.
- returned: success, when port forwarding is in task
- type: str
- example: tcp
- publicPort:
- description: Destination port of the traffic that is arriving on WAN.
- returned: success, when port forwarding is in task
- type: int
- example: 9443
- localPort:
- description: Destination port to be forwarded to.
- returned: success, when port forwarding is in task
- type: int
- example: 443
- uplink:
- description: Internet port where rule is applied.
- returned: success, when port forwarding is in task
- type: str
- example: internet1
-'''
-
-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.common.dict_transformations import recursive_diff
-from ansible.module_utils.network.meraki.meraki import MerakiModule, meraki_argument_spec
-
-key_map = {'name': 'name',
- 'public_ip': 'publicIp',
- 'lan_ip': 'lanIp',
- 'uplink': 'uplink',
- 'allowed_inbound': 'allowedInbound',
- 'protocol': 'protocol',
- 'destination_ports': 'destinationPorts',
- 'allowed_ips': 'allowedIps',
- 'port_rules': 'portRules',
- 'public_port': 'publicPort',
- 'local_ip': 'localIp',
- 'local_port': 'localPort',
- }
-
-
-def construct_payload(params):
- if isinstance(params, list):
- items = []
- for item in params:
- items.append(construct_payload(item))
- return items
- elif isinstance(params, dict):
- info = {}
- for param in params:
- info[key_map[param]] = construct_payload(params[param])
- return info
- elif isinstance(params, str) or isinstance(params, int):
- return params
-
-
-def list_int_to_str(data):
- return [str(item) for item in data]
-
-
-def main():
-
- # define the available arguments/parameters that a user can pass to
- # the module
-
- one_to_one_allowed_inbound_spec = dict(protocol=dict(type='str', choices=['tcp', 'udp', 'icmp-ping', 'any'], default='any'),
- destination_ports=dict(type='list', element='str'),
- allowed_ips=dict(type='list'),
- )
-
- one_to_many_port_inbound_spec = dict(protocol=dict(type='str', choices=['tcp', 'udp']),
- name=dict(type='str'),
- local_ip=dict(type='str'),
- local_port=dict(type='str'),
- allowed_ips=dict(type='list'),
- public_port=dict(type='str'),
- )
-
- one_to_one_spec = dict(name=dict(type='str'),
- public_ip=dict(type='str'),
- lan_ip=dict(type='str'),
- uplink=dict(type='str', choices=['internet1', 'internet2', 'both']),
- allowed_inbound=dict(type='list', element='dict', options=one_to_one_allowed_inbound_spec),
- )
-
- one_to_many_spec = dict(public_ip=dict(type='str'),
- uplink=dict(type='str', choices=['internet1', 'internet2', 'both']),
- port_rules=dict(type='list', element='dict', options=one_to_many_port_inbound_spec),
- )
-
- port_forwarding_spec = dict(name=dict(type='str'),
- lan_ip=dict(type='str'),
- uplink=dict(type='str', choices=['internet1', 'internet2', 'both']),
- protocol=dict(type='str', choices=['tcp', 'udp']),
- public_port=dict(type='int'),
- local_port=dict(type='int'),
- allowed_ips=dict(type='list'),
- )
-
- argument_spec = meraki_argument_spec()
- argument_spec.update(
- net_id=dict(type='str'),
- net_name=dict(type='str', aliases=['name', 'network']),
- state=dict(type='str', choices=['present', 'query'], default='present'),
- subset=dict(type='list', choices=['1:1', '1:many', 'all', 'port_forwarding'], default='all'),
- one_to_one=dict(type='list', elements='dict', options=one_to_one_spec),
- one_to_many=dict(type='list', elements='dict', options=one_to_many_spec),
- port_forwarding=dict(type='list', elements='dict', options=port_forwarding_spec),
- )
-
- # 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='nat')
- module.params['follow_redirects'] = 'all'
-
- one_to_one_payload = None
- one_to_many_payload = None
- port_forwarding_payload = None
- if meraki.params['state'] == 'present':
- if meraki.params['one_to_one'] is not None:
- rules = []
- for i in meraki.params['one_to_one']:
- data = {'name': i['name'],
- 'publicIp': i['public_ip'],
- 'uplink': i['uplink'],
- 'lanIp': i['lan_ip'],
- 'allowedInbound': construct_payload(i['allowed_inbound'])
- }
- for inbound in data['allowedInbound']:
- inbound['destinationPorts'] = list_int_to_str(inbound['destinationPorts'])
- rules.append(data)
- one_to_one_payload = {'rules': rules}
- if meraki.params['one_to_many'] is not None:
- rules = []
- for i in meraki.params['one_to_many']:
- data = {'publicIp': i['public_ip'],
- 'uplink': i['uplink'],
- }
- port_rules = []
- for port_rule in i['port_rules']:
- rule = {'name': port_rule['name'],
- 'protocol': port_rule['protocol'],
- 'publicPort': str(port_rule['public_port']),
- 'localIp': port_rule['local_ip'],
- 'localPort': str(port_rule['local_port']),
- 'allowedIps': port_rule['allowed_ips'],
- }
- port_rules.append(rule)
- data['portRules'] = port_rules
- rules.append(data)
- one_to_many_payload = {'rules': rules}
- if meraki.params['port_forwarding'] is not None:
- port_forwarding_payload = {'rules': construct_payload(meraki.params['port_forwarding'])}
- for rule in port_forwarding_payload['rules']:
- rule['localPort'] = str(rule['localPort'])
- rule['publicPort'] = str(rule['publicPort'])
-
- onetomany_urls = {'nat': '/networks/{net_id}/oneToManyNatRules'}
- onetoone_urls = {'nat': '/networks/{net_id}/oneToOneNatRules'}
- port_forwarding_urls = {'nat': '/networks/{net_id}/portForwardingRules'}
- meraki.url_catalog['1:many'] = onetomany_urls
- meraki.url_catalog['1:1'] = onetoone_urls
- meraki.url_catalog['port_forwarding'] = port_forwarding_urls
-
- if meraki.params['net_name'] and meraki.params['net_id']:
- meraki.fail_json(msg='net_name and net_id are mutually exclusive')
-
- org_id = meraki.params['org_id']
- if not org_id:
- org_id = meraki.get_org_id(meraki.params['org_name'])
- net_id = meraki.params['net_id']
- 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['subset'][0] == 'all':
- path = meraki.construct_path('1:many', net_id=net_id)
- data = {'1:many': meraki.request(path, method='GET')}
- path = meraki.construct_path('1:1', net_id=net_id)
- data['1:1'] = meraki.request(path, method='GET')
- path = meraki.construct_path('port_forwarding', net_id=net_id)
- data['port_forwarding'] = meraki.request(path, method='GET')
- meraki.result['data'] = data
- else:
- for subset in meraki.params['subset']:
- path = meraki.construct_path(subset, net_id=net_id)
- data = {subset: meraki.request(path, method='GET')}
- try:
- meraki.result['data'][subset] = data
- except KeyError:
- meraki.result['data'] = {subset: data}
- elif meraki.params['state'] == 'present':
- meraki.result['data'] = dict()
- if one_to_one_payload is not None:
- path = meraki.construct_path('1:1', net_id=net_id)
- current = meraki.request(path, method='GET')
- if meraki.is_update_required(current, one_to_one_payload):
- if meraki.module.check_mode is True:
- diff = recursive_diff(current, one_to_one_payload)
- current.update(one_to_one_payload)
- if 'diff' not in meraki.result:
- meraki.result['diff'] = {'before': {}, 'after': {}}
- meraki.result['diff']['before'].update({'one_to_one': diff[0]})
- meraki.result['diff']['after'].update({'one_to_one': diff[1]})
- meraki.result['data'] = {'one_to_one': current}
- meraki.result['changed'] = True
- else:
- r = meraki.request(path, method='PUT', payload=json.dumps(one_to_one_payload))
- if meraki.status == 200:
- diff = recursive_diff(current, one_to_one_payload)
- if 'diff' not in meraki.result:
- meraki.result['diff'] = {'before': {}, 'after': {}}
- meraki.result['diff']['before'].update({'one_to_one': diff[0]})
- meraki.result['diff']['after'].update({'one_to_one': diff[1]})
- meraki.result['data'] = {'one_to_one': r}
- meraki.result['changed'] = True
- else:
- meraki.result['data']['one_to_one'] = current
- if one_to_many_payload is not None:
- path = meraki.construct_path('1:many', net_id=net_id)
- current = meraki.request(path, method='GET')
- if meraki.is_update_required(current, one_to_many_payload):
- if meraki.module.check_mode is True:
- diff = recursive_diff(current, one_to_many_payload)
- current.update(one_to_many_payload)
- if 'diff' not in meraki.result:
- meraki.result['diff'] = {'before': {}, 'after': {}}
- meraki.result['diff']['before'].update({'one_to_many': diff[0]})
- meraki.result['diff']['after'].update({'one_to_many': diff[1]})
- meraki.result['data']['one_to_many'] = current
- meraki.result['changed'] = True
- else:
- r = meraki.request(path, method='PUT', payload=json.dumps(one_to_many_payload))
- if meraki.status == 200:
- diff = recursive_diff(current, one_to_many_payload)
- if 'diff' not in meraki.result:
- meraki.result['diff'] = {'before': {}, 'after': {}}
- meraki.result['diff']['before'].update({'one_to_many': diff[0]})
- meraki.result['diff']['after'].update({'one_to_many': diff[1]})
- meraki.result['data'].update({'one_to_many': r})
- meraki.result['changed'] = True
- else:
- meraki.result['data']['one_to_many'] = current
- if port_forwarding_payload is not None:
- path = meraki.construct_path('port_forwarding', net_id=net_id)
- current = meraki.request(path, method='GET')
- if meraki.is_update_required(current, port_forwarding_payload):
- if meraki.module.check_mode is True:
- diff = recursive_diff(current, port_forwarding_payload)
- current.update(port_forwarding_payload)
- if 'diff' not in meraki.result:
- meraki.result['diff'] = {'before': {}, 'after': {}}
- meraki.result['diff']['before'].update({'port_forwarding': diff[0]})
- meraki.result['diff']['after'].update({'port_forwarding': diff[1]})
- meraki.result['data']['port_forwarding'] = current
- meraki.result['changed'] = True
- else:
- r = meraki.request(path, method='PUT', payload=json.dumps(port_forwarding_payload))
- if meraki.status == 200:
- if 'diff' not in meraki.result:
- meraki.result['diff'] = {'before': {}, 'after': {}}
- diff = recursive_diff(current, port_forwarding_payload)
- meraki.result['diff']['before'].update({'port_forwarding': diff[0]})
- meraki.result['diff']['after'].update({'port_forwarding': diff[1]})
- meraki.result['data'].update({'port_forwarding': r})
- meraki.result['changed'] = True
- else:
- meraki.result['data']['port_forwarding'] = current
-
- # 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()
diff --git a/lib/ansible/modules/network/meraki/meraki_network.py b/lib/ansible/modules/network/meraki/meraki_network.py
deleted file mode 100644
index 3863b5d163..0000000000
--- a/lib/ansible/modules/network/meraki/meraki_network.py
+++ /dev/null
@@ -1,390 +0,0 @@
-#!/usr/bin/python
-# -*- coding: utf-8 -*-
-
-# Copyright: (c) 2018, 2019 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_network
-short_description: Manage networks in the Meraki cloud
-version_added: "2.6"
-description:
-- Allows for creation, management, and visibility into networks within Meraki.
-
-options:
- state:
- description:
- - Create or modify an organization.
- choices: [ absent, present, query ]
- default: present
- net_name:
- description:
- - Name of a network.
- aliases: [ name, network ]
- net_id:
- description:
- - ID number of a network.
- type:
- description:
- - Type of network device network manages.
- - Required when creating a network.
- - As of Ansible 2.8, C(combined) type is no longer accepted.
- - As of Ansible 2.8, changes to this parameter are no longer idempotent.
- choices: [ appliance, switch, wireless ]
- aliases: [ net_type ]
- type: list
- tags:
- type: list
- description:
- - List of tags to assign to network.
- - C(tags) name conflicts with the tags parameter in Ansible. Indentation problems may cause unexpected behaviors.
- - Ansible 2.8 converts this to a list from a comma separated list.
- timezone:
- description:
- - Timezone associated to network.
- - See U(https://en.wikipedia.org/wiki/List_of_tz_database_time_zones) for a list of valid timezones.
- enable_vlans:
- description:
- - Boolean value specifying whether VLANs should be supported on a network.
- - Requires C(net_name) or C(net_id) to be specified.
- type: bool
- version_added: '2.9'
- disable_my_meraki:
- description: >
- - Disables the local device status pages (U[my.meraki.com](my.meraki.com), U[ap.meraki.com](ap.meraki.com), U[switch.meraki.com](switch.meraki.com),
- U[wired.meraki.com](wired.meraki.com)).
- - Mutually exclusive of C(enable_my_meraki).
- - Will be deprecated in Ansible 2.13 in favor of C(enable_my_meraki).
- type: bool
- version_added: '2.7'
- enable_my_meraki:
- description: >
- - Enables the local device status pages (U[my.meraki.com](my.meraki.com), U[ap.meraki.com](ap.meraki.com), U[switch.meraki.com](switch.meraki.com),
- U[wired.meraki.com](wired.meraki.com)).
- - Ansible 2.7 had this parameter as C(disable_my_meraki).
- type: bool
- version_added: '2.9'
- enable_remote_status_page:
- description:
- - Enables access to the device status page (U(http://device LAN IP)).
- - Can only be set if C(enable_my_meraki:) is set to C(yes).
- type: bool
- version_added: '2.9'
-
-author:
- - Kevin Breit (@kbreit)
-extends_documentation_fragment: meraki
-'''
-
-EXAMPLES = r'''
-- delegate_to: localhost
- block:
- - name: List all networks associated to the YourOrg organization
- meraki_network:
- auth_key: abc12345
- state: query
- org_name: YourOrg
- - name: Query network named MyNet in the YourOrg organization
- meraki_network:
- auth_key: abc12345
- state: query
- org_name: YourOrg
- net_name: MyNet
- - name: Create network named MyNet in the YourOrg organization
- meraki_network:
- auth_key: abc12345
- state: present
- org_name: YourOrg
- net_name: MyNet
- type: switch
- timezone: America/Chicago
- tags: production, chicago
- - name: Create combined network named MyNet in the YourOrg organization
- meraki_network:
- auth_key: abc12345
- state: present
- org_name: YourOrg
- net_name: MyNet
- type:
- - switch
- - appliance
- timezone: America/Chicago
- tags: production, chicago
- - name: Enable VLANs on a network
- meraki_network:
- auth_key: abc12345
- state: query
- org_name: YourOrg
- net_name: MyNet
- enable_vlans: yes
-'''
-
-RETURN = r'''
-data:
- description: Information about the created or manipulated object.
- returned: info
- type: complex
- contains:
- id:
- description: Identification string of network.
- returned: success
- type: str
- sample: N_12345
- name:
- description: Written name of network.
- returned: success
- type: str
- sample: YourNet
- organization_id:
- description: Organization ID which owns the network.
- returned: success
- type: str
- sample: 0987654321
- tags:
- description: Space delimited tags assigned to network.
- returned: success
- type: str
- sample: " production wireless "
- time_zone:
- description: Timezone where network resides.
- returned: success
- type: str
- sample: America/Chicago
- type:
- description: Functional type of network.
- returned: success
- type: str
- sample: switch
- disable_my_meraki_com:
- description: States whether U(my.meraki.com) and other device portals should be disabled.
- returned: success
- type: bool
- sample: true
- disableRemoteStatusPage:
- description: Disables access to the device status page.
- returned: success
- type: bool
- sample: true
-'''
-
-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 is_net_valid(data, net_name=None, net_id=None):
- if net_name is None and net_id is None:
- return False
- for n in data:
- if net_name:
- if n['name'] == net_name:
- return True
- elif net_id:
- if n['id'] == net_id:
- return True
- return False
-
-
-def construct_tags(tags):
- formatted_tags = ' '.join(tags)
- return ' {0} '.format(formatted_tags) # Meraki needs space padding
-
-
-def list_to_string(data):
- new_string = str()
- for i, item in enumerate(data):
- if i == len(new_string) - 1:
- new_string += i
- else:
- new_string = "{0}{1} ".format(new_string, item)
- return new_string.strip()
-
-
-def main():
-
- # define the available arguments/parameters that a user can pass to
- # the module
-
- argument_spec = meraki_argument_spec()
- argument_spec.update(
- net_id=dict(type='str'),
- type=dict(type='list', choices=['wireless', 'switch', 'appliance'], aliases=['net_type']),
- tags=dict(type='list'),
- timezone=dict(type='str'),
- net_name=dict(type='str', aliases=['name', 'network']),
- state=dict(type='str', choices=['present', 'query', 'absent'], default='present'),
- enable_vlans=dict(type='bool'),
- disable_my_meraki=dict(type='bool', removed_in_version=2.13),
- enable_my_meraki=dict(type='bool'),
- enable_remote_status_page=dict(type='bool'),
- )
-
- # 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=False,
- mutually_exclusive=[('disable_my_meraki', 'enable_my_meraki'),
- ]
- )
-
- meraki = MerakiModule(module, function='network')
- module.params['follow_redirects'] = 'all'
- payload = None
-
- create_urls = {'network': '/organizations/{org_id}/networks'}
- update_urls = {'network': '/networks/{net_id}'}
- delete_urls = {'network': '/networks/{net_id}'}
- enable_vlans_urls = {'network': '/networks/{net_id}/vlansEnabledState'}
- get_vlan_status_urls = {'network': '/networks/{net_id}/vlansEnabledState'}
- meraki.url_catalog['create'] = create_urls
- meraki.url_catalog['update'] = update_urls
- meraki.url_catalog['delete'] = delete_urls
- meraki.url_catalog['enable_vlans'] = enable_vlans_urls
- meraki.url_catalog['status_vlans'] = get_vlan_status_urls
-
- if not meraki.params['org_name'] and not meraki.params['org_id']:
- meraki.fail_json(msg='org_name or org_id parameters are required')
- if meraki.params['state'] != 'query':
- if not meraki.params['net_name'] and not meraki.params['net_id']:
- meraki.fail_json(msg='net_name or net_id is required for present or absent states')
- if meraki.params['net_name'] and meraki.params['net_id']:
- meraki.fail_json(msg='net_name and net_id are mutually exclusive')
- if not meraki.params['net_name'] and not meraki.params['net_id']:
- if meraki.params['enable_vlans']:
- meraki.fail_json(msg="The parameter 'enable_vlans' requires 'net_name' or 'net_id' to be specified")
- if meraki.params['enable_my_meraki'] is True and meraki.params['enable_remote_status_page'] is False:
- meraki.fail_json(msg='enable_my_meraki must be true when setting enable_remote_status_page')
-
- # 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
- if module.check_mode:
- return meraki.result
-
- # Construct payload
- if meraki.params['state'] == 'present':
- payload = dict()
- if meraki.params['net_name']:
- payload['name'] = meraki.params['net_name']
- if meraki.params['type']:
- payload['type'] = list_to_string(meraki.params['type'])
- if meraki.params['tags']:
- payload['tags'] = construct_tags(meraki.params['tags'])
- if meraki.params['timezone']:
- payload['timeZone'] = meraki.params['timezone']
- if meraki.params['enable_my_meraki'] is not None:
- if meraki.params['enable_my_meraki'] is True:
- payload['disableMyMerakiCom'] = False
- else:
- payload['disableMyMerakiCom'] = True
- elif meraki.params['disable_my_meraki'] is not None:
- payload['disableMyMerakiCom'] = meraki.params['disable_my_meraki']
- if meraki.params['enable_remote_status_page'] is not None:
- if meraki.params['enable_remote_status_page'] is True:
- payload['disableRemoteStatusPage'] = False
- # meraki.fail_json(msg="Debug", payload=payload)
- else:
- payload['disableRemoteStatusPage'] = 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']
- if not org_id:
- org_id = meraki.get_org_id(meraki.params['org_name'])
- nets = meraki.get_nets(org_id=org_id)
-
- # check if network is created
- net_id = meraki.params['net_id']
- net_exists = False
- if net_id is not None:
- if is_net_valid(nets, net_id=net_id) is False:
- meraki.fail_json(msg="Network specified by net_id does not exist.")
- net_exists = True
- elif meraki.params['net_name']:
- if is_net_valid(nets, net_name=meraki.params['net_name']) is True:
- net_id = meraki.get_net_id(net_name=meraki.params['net_name'], data=nets)
- net_exists = True
-
- if meraki.params['state'] == 'query':
- if not meraki.params['net_name'] and not meraki.params['net_id']:
- meraki.result['data'] = nets
- elif meraki.params['net_name'] or meraki.params['net_id'] is not None:
- meraki.result['data'] = meraki.get_net(meraki.params['org_name'],
- meraki.params['net_name'],
- data=nets
- )
- elif meraki.params['state'] == 'present':
- if net_exists is False: # Network needs to be created
- if 'type' not in meraki.params or meraki.params['type'] is None:
- meraki.fail_json(msg="type parameter is required when creating a network.")
- path = meraki.construct_path('create',
- org_id=org_id
- )
- r = meraki.request(path,
- method='POST',
- payload=json.dumps(payload)
- )
- if meraki.status == 201:
- meraki.result['data'] = r
- meraki.result['changed'] = True
- else: # Network exists, make changes
- # meraki.fail_json(msg="nets", nets=nets, net_id=net_id)
- # meraki.fail_json(msg="compare", original=net, payload=payload)
- if meraki.params['enable_vlans'] is not None: # Modify VLANs configuration
- status_path = meraki.construct_path('status_vlans', net_id=net_id)
- status = meraki.request(status_path, method='GET')
- payload = {'enabled': meraki.params['enable_vlans']}
- # meraki.fail_json(msg="here", payload=payload)
- if meraki.is_update_required(status, payload):
- path = meraki.construct_path('enable_vlans', net_id=net_id)
- r = meraki.request(path,
- method='PUT',
- payload=json.dumps(payload))
- if meraki.status == 200:
- meraki.result['data'] = r
- meraki.result['changed'] = True
- meraki.exit_json(**meraki.result)
- else:
- meraki.result['data'] = status
- meraki.exit_json(**meraki.result)
- net = meraki.get_net(meraki.params['org_name'], net_id=net_id, data=nets)
- if meraki.is_update_required(net, payload):
- path = meraki.construct_path('update', net_id=net_id)
- # meraki.fail_json(msg="Payload", path=path, payload=payload)
- r = meraki.request(path,
- method='PUT',
- payload=json.dumps(payload))
- if meraki.status == 200:
- meraki.result['data'] = r
- meraki.result['changed'] = True
- else:
- meraki.result['data'] = net
- elif meraki.params['state'] == 'absent':
- if is_net_valid(nets, net_id=net_id) is True:
- path = meraki.construct_path('delete', net_id=net_id)
- r = meraki.request(path, method='DELETE')
- if meraki.status == 204:
- 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()
diff --git a/lib/ansible/modules/network/meraki/meraki_organization.py b/lib/ansible/modules/network/meraki/meraki_organization.py
deleted file mode 100644
index 85a644a5af..0000000000
--- a/lib/ansible/modules/network/meraki/meraki_organization.py
+++ /dev/null
@@ -1,244 +0,0 @@
-#!/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_organization
-short_description: Manage organizations in the Meraki cloud
-version_added: "2.6"
-description:
-- Allows for creation, management, and visibility into organizations within Meraki.
-options:
- state:
- description:
- - Create or modify an organization.
- - C(org_id) must be specified if multiple organizations of the same name exist.
- - C(absent) WILL DELETE YOUR ENTIRE ORGANIZATION, AND ALL ASSOCIATED OBJECTS, WITHOUT CONFIRMATION. USE WITH CAUTION.
- choices: ['absent', 'present', 'query']
- default: present
- clone:
- description:
- - Organization to clone to a new organization.
- org_name:
- description:
- - Name of organization.
- - If C(clone) is specified, C(org_name) is the name of the new organization.
- aliases: [ name, organization ]
- org_id:
- description:
- - ID of organization.
- aliases: [ id ]
- type: str
-author:
-- Kevin Breit (@kbreit)
-extends_documentation_fragment: meraki
-'''
-
-EXAMPLES = r'''
-- name: Create a new organization named YourOrg
- meraki_organization:
- auth_key: abc12345
- org_name: YourOrg
- 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
- state: query
- delegate_to: localhost
-
-- name: Query information about a single organization named YourOrg
- meraki_organization:
- auth_key: abc12345
- org_name: YourOrg
- state: query
- delegate_to: localhost
-
-- name: Rename an organization to RenamedOrg
- meraki_organization:
- auth_key: abc12345
- org_id: 987654321
- org_name: RenamedOrg
- state: present
- delegate_to: localhost
-
-- name: Clone an organization named Org to a new one called ClonedOrg
- meraki_organization:
- auth_key: abc12345
- clone: Org
- org_name: ClonedOrg
- state: present
- delegate_to: localhost
-'''
-
-RETURN = r'''
-data:
- description: Information about the organization which was created or modified
- returned: success
- type: complex
- contains:
- id:
- description: Unique identification number of organization
- returned: success
- type: int
- sample: 2930418
- name:
- description: Name of organization
- returned: success
- type: str
- sample: YourOrg
-
-'''
-
-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_org(meraki, org_id, data):
- # meraki.fail_json(msg=str(org_id), data=data, oid0=data[0]['id'], oid1=data[1]['id'])
- for o in data:
- # meraki.fail_json(msg='o', data=o['id'], type=str(type(o['id'])))
- if o['id'] == org_id:
- return o
- return -1
-
-
-def main():
-
- # define the available arguments/parameters that a user can pass to
- # the module
- argument_spec = meraki_argument_spec()
- argument_spec.update(clone=dict(type='str'),
- 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']),
- )
-
- # 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='organizations')
-
- meraki.params['follow_redirects'] = 'all'
-
- 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
-
- # 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()
- if meraki.params['state'] == 'query':
- if meraki.params['org_name']: # Query by organization name
- module.warn('All matching organizations will be returned, even if there are duplicate named organizations')
- for o in orgs:
- if o['name'] == meraki.params['org_name']:
- meraki.result['data'] = o
- elif meraki.params['org_id']:
- for o in orgs:
- if o['id'] == meraki.params['org_id']:
- meraki.result['data'] = o
- else: # Query all organizations, no matter what
- meraki.result['data'] = orgs
- elif meraki.params['state'] == 'present':
- if meraki.params['clone']: # Cloning
- payload = {'name': meraki.params['org_name']}
- response = meraki.request(meraki.construct_path('clone',
- org_name=meraki.params['clone']
- ),
- payload=json.dumps(payload),
- method='POST')
- if meraki.status != 201:
- meraki.fail_json(msg='Organization clone failed')
- meraki.result['data'] = response
- meraki.result['changed'] = True
- elif not meraki.params['org_id'] and meraki.params['org_name']: # Create new organization
- payload = {'name': meraki.params['org_name']}
- response = meraki.request(meraki.construct_path('create'),
- method='POST',
- payload=json.dumps(payload))
- if meraki.status == 201:
- meraki.result['data'] = response
- meraki.result['changed'] = True
- elif meraki.params['org_id'] and meraki.params['org_name']: # Update an existing organization
- payload = {'name': meraki.params['org_name'],
- 'id': meraki.params['org_id'],
- }
- original = get_org(meraki, meraki.params['org_id'], orgs)
- if meraki.is_update_required(original, payload, optional_ignore=['url']):
- response = meraki.request(meraki.construct_path('update',
- org_id=meraki.params['org_id']
- ),
- method='PUT',
- payload=json.dumps(payload))
- if meraki.status != 200:
- meraki.fail_json(msg='Organization update failed')
- meraki.result['data'] = response
- 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
- meraki.exit_json(**meraki.result)
-
-
-if __name__ == '__main__':
- main()
diff --git a/lib/ansible/modules/network/meraki/meraki_snmp.py b/lib/ansible/modules/network/meraki/meraki_snmp.py
deleted file mode 100644
index 097d9704b7..0000000000
--- a/lib/ansible/modules/network/meraki/meraki_snmp.py
+++ /dev/null
@@ -1,401 +0,0 @@
-#!/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_snmp
-short_description: Manage organizations in the Meraki cloud
-version_added: "2.6"
-description:
-- Allows for management of SNMP settings for Meraki.
-options:
- state:
- description:
- - Specifies whether SNMP information should be queried or modified.
- choices: ['query', 'present']
- default: present
- type: str
- v2c_enabled:
- description:
- - Specifies whether SNMPv2c is enabled.
- type: bool
- v3_enabled:
- description:
- - Specifies whether SNMPv3 is enabled.
- type: bool
- v3_auth_mode:
- description:
- - Sets authentication mode for SNMPv3.
- choices: ['MD5', 'SHA']
- type: str
- v3_auth_pass:
- description:
- - Authentication password for SNMPv3.
- - Must be at least 8 characters long.
- type: str
- v3_priv_mode:
- description:
- - Specifies privacy mode for SNMPv3.
- choices: ['DES', 'AES128']
- type: str
- v3_priv_pass:
- description:
- - Privacy password for SNMPv3.
- - Must be at least 8 characters long.
- type: str
- peer_ips:
- description:
- - Semi-colon delimited IP addresses which can perform SNMP queries.
- type: str
- net_name:
- description:
- - Name of network.
- type: str
- version_added: '2.9'
- net_id:
- description:
- - ID of network.
- type: str
- version_added: '2.9'
- access:
- description:
- - Type of SNMP access.
- choices: [community, none, users]
- type: str
- version_added: '2.9'
- community_string:
- description:
- - SNMP community string.
- - Only relevant if C(access) is set to C(community).
- type: str
- version_added: '2.9'
- users:
- description:
- - Information about users with access to SNMP.
- - Only relevant if C(access) is set to C(users).
- type: list
- version_added: '2.9'
- suboptions:
- username:
- description: Username of user with access.
- type: str
- version_added: '2.9'
- passphrase:
- description: Passphrase for user SNMP access.
- type: str
- version_added: '2.9'
-author:
-- Kevin Breit (@kbreit)
-extends_documentation_fragment: meraki
-'''
-
-EXAMPLES = r'''
-- name: Query SNMP values
- meraki_snmp:
- auth_key: abc12345
- org_name: YourOrg
- state: query
- delegate_to: localhost
-
-- name: Enable SNMPv2
- meraki_snmp:
- auth_key: abc12345
- org_name: YourOrg
- state: present
- v2c_enabled: yes
- delegate_to: localhost
-
-- name: Disable SNMPv2
- meraki_snmp:
- auth_key: abc12345
- org_name: YourOrg
- state: present
- v2c_enabled: no
- delegate_to: localhost
-
-- name: Enable SNMPv3
- meraki_snmp:
- auth_key: abc12345
- org_name: YourOrg
- state: present
- v3_enabled: true
- v3_auth_mode: SHA
- v3_auth_pass: ansiblepass
- v3_priv_mode: AES128
- v3_priv_pass: ansiblepass
- peer_ips: 192.0.1.1;192.0.1.2
- delegate_to: localhost
-
-- name: Set network access type to community string
- meraki_snmp:
- auth_key: abc1235
- org_name: YourOrg
- net_name: YourNet
- state: present
- access: community
- community_string: abc123
- delegate_to: localhost
-
-- name: Set network access type to username
- meraki_snmp:
- auth_key: abc1235
- org_name: YourOrg
- net_name: YourNet
- state: present
- access: users
- users:
- - username: ansibleuser
- passphrase: ansiblepass
- delegate_to: localhost
-'''
-
-RETURN = r'''
-data:
- description: Information about SNMP settings.
- type: complex
- returned: always
- contains:
- hostname:
- description: Hostname of SNMP server.
- returned: success and no network specified.
- type: str
- sample: n1.meraki.com
- peerIps:
- description: Semi-colon delimited list of IPs which can poll SNMP information.
- returned: success and no network specified.
- type: str
- sample: 192.0.1.1
- port:
- description: Port number of SNMP.
- returned: success and no network specified.
- type: str
- sample: 16100
- v2c_enabled:
- description: Shows enabled state of SNMPv2c
- returned: success and no network specified.
- type: bool
- sample: true
- v3_enabled:
- description: Shows enabled state of SNMPv3
- returned: success and no network specified.
- type: bool
- sample: true
- v3_auth_mode:
- description: The SNMP version 3 authentication mode either MD5 or SHA.
- returned: success and no network specified.
- type: str
- sample: SHA
- v3_priv_mode:
- description: The SNMP version 3 privacy mode DES or AES128.
- returned: success and no network specified.
- type: str
- sample: AES128
- v2_community_string:
- description: Automatically generated community string for SNMPv2c.
- returned: When SNMPv2c is enabled and no network specified.
- type: str
- sample: o/8zd-JaSb
- v3_user:
- description: Automatically generated username for SNMPv3.
- returned: When SNMPv3c is enabled and no network specified.
- type: str
- sample: o/8zd-JaSb
- access:
- description: Type of SNMP access.
- type: str
- returned: success, when network specified
- community_string:
- description: SNMP community string. Only relevant if C(access) is set to C(community).
- type: str
- returned: success, when network specified
- users:
- description: Information about users with access to SNMP. Only relevant if C(access) is set to C(users).
- type: complex
- contains:
- username:
- description: Username of user with access.
- type: str
- returned: success, when network specified
- passphrase:
- description: Passphrase for user SNMP access.
- type: str
- returned: success, when network specified
-'''
-
-from ansible.module_utils.basic import AnsibleModule, json
-from ansible.module_utils.common.dict_transformations import recursive_diff, snake_dict_to_camel_dict
-from ansible.module_utils.network.meraki.meraki import MerakiModule, meraki_argument_spec
-
-
-def get_snmp(meraki, org_id):
- path = meraki.construct_path('get_all', org_id=org_id)
- r = meraki.request(path,
- method='GET',
- )
- if meraki.status == 200:
- return r
-
-
-def set_snmp(meraki, org_id):
- payload = dict()
- if meraki.params['peer_ips']:
- if len(meraki.params['peer_ips']) > 7:
- if ';' not in meraki.params['peer_ips']:
- meraki.fail_json(msg='Peer IP addresses are semi-colon delimited.')
- if meraki.params['v2c_enabled'] is not None:
- payload = {'v2cEnabled': meraki.params['v2c_enabled'],
- }
- if meraki.params['v3_enabled'] is True:
- if len(meraki.params['v3_auth_pass']) < 8 or len(meraki.params['v3_priv_pass']) < 8:
- meraki.fail_json(msg='v3_auth_pass and v3_priv_pass must both be at least 8 characters long.')
- if (meraki.params['v3_auth_mode'] is None or
- meraki.params['v3_auth_pass'] is None or
- meraki.params['v3_priv_mode'] is None or
- meraki.params['v3_priv_pass'] is None):
- meraki.fail_json(msg='v3_auth_mode, v3_auth_pass, v3_priv_mode, and v3_auth_pass are required')
- payload = {'v3Enabled': meraki.params['v3_enabled'],
- 'v3AuthMode': meraki.params['v3_auth_mode'].upper(),
- 'v3AuthPass': meraki.params['v3_auth_pass'],
- 'v3PrivMode': meraki.params['v3_priv_mode'].upper(),
- 'v3PrivPass': meraki.params['v3_priv_pass'],
- }
- if meraki.params['peer_ips'] is not None:
- payload['peerIps'] = meraki.params['peer_ips']
- elif meraki.params['v3_enabled'] is False:
- payload = {'v3Enabled': False}
- full_compare = snake_dict_to_camel_dict(payload)
- path = meraki.construct_path('create', org_id=org_id)
- snmp = get_snmp(meraki, org_id)
- ignored_parameters = ['v3AuthPass', 'v3PrivPass', 'hostname', 'port', 'v2CommunityString', 'v3User']
- if meraki.is_update_required(snmp, full_compare, optional_ignore=ignored_parameters):
- if meraki.module.check_mode is True:
- diff = recursive_diff(snmp, full_compare)
- snmp.update(payload)
- meraki.result['data'] = snmp
- meraki.result['changed'] = True
- meraki.result['diff'] = {'before': diff[0],
- 'after': diff[1]}
- meraki.exit_json(**meraki.result)
- r = meraki.request(path,
- method='PUT',
- payload=json.dumps(payload))
- if meraki.status == 200:
- diff = recursive_diff(snmp, r)
- meraki.result['diff'] = {'before': diff[0],
- 'after': diff[1]}
- meraki.result['changed'] = True
- return r
- else:
- return snmp
-
-
-def main():
-
- # define the available arguments/parameters that a user can pass to
- # the module
- user_arg_spec = dict(username=dict(type='str'),
- passphrase=dict(type='str', no_log=True),
- )
-
- argument_spec = meraki_argument_spec()
- argument_spec.update(state=dict(type='str', choices=['present', 'query'], default='present'),
- v2c_enabled=dict(type='bool'),
- v3_enabled=dict(type='bool'),
- v3_auth_mode=dict(type='str', choices=['SHA', 'MD5']),
- v3_auth_pass=dict(type='str', no_log=True),
- v3_priv_mode=dict(type='str', choices=['DES', 'AES128']),
- v3_priv_pass=dict(type='str', no_log=True),
- peer_ips=dict(type='str'),
- access=dict(type='str', choices=['none', 'community', 'users']),
- community_string=dict(type='str', no_log=True),
- users=dict(type='list', default=None, elements='', options=user_arg_spec),
- net_name=dict(type='str'),
- net_id=dict(type='str'),
- )
-
- # 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='snmp')
- meraki.params['follow_redirects'] = 'all'
-
- query_urls = {'snmp': '/organizations/{org_id}/snmp'}
- query_net_urls = {'snmp': '/networks/{net_id}/snmpSettings'}
- update_urls = {'snmp': '/organizations/{org_id}/snmp'}
- update_net_urls = {'snmp': '/networks/{net_id}/snmpSettings'}
-
- meraki.url_catalog['get_all'].update(query_urls)
- meraki.url_catalog['query_net_all'] = query_net_urls
- meraki.url_catalog['create'] = update_urls
- meraki.url_catalog['create_net'] = update_net_urls
-
- payload = None
-
- if not meraki.params['org_name'] and not meraki.params['org_id']:
- meraki.fail_json(msg='org_name or org_id is required')
-
- org_id = meraki.params['org_id']
- if org_id is None:
- org_id = meraki.get_org_id(meraki.params['org_name'])
- net_id = meraki.params['net_id']
- if net_id is None and meraki.params['net_name']:
- 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'] == 'present':
- if net_id is not None:
- payload = {'access': meraki.params['access']}
- if meraki.params['community_string'] is not None:
- payload['communityString'] = meraki.params['community_string']
- elif meraki.params['users'] is not None:
- payload['users'] = meraki.params['users']
-
- if meraki.params['state'] == 'query':
- if net_id is None:
- meraki.result['data'] = get_snmp(meraki, org_id)
- else:
- path = meraki.construct_path('query_net_all', net_id=net_id)
- response = meraki.request(path, method='GET')
- if meraki.status == 200:
- meraki.result['data'] = response
- elif meraki.params['state'] == 'present':
- if net_id is None:
- meraki.result['data'] = set_snmp(meraki, org_id)
- else:
- path = meraki.construct_path('query_net_all', net_id=net_id)
- original = meraki.request(path, method='GET')
- if meraki.is_update_required(original, payload):
- path = meraki.construct_path('create_net', net_id=net_id)
- response = meraki.request(path, method='PUT', payload=json.dumps(payload))
- if meraki.status == 200:
- if response['access'] == 'none':
- meraki.result['data'] = {}
- else:
- meraki.result['data'] = response
- meraki.result['changed'] = True
- else:
- meraki.result['data'] = original
-
- # 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()
diff --git a/lib/ansible/modules/network/meraki/meraki_ssid.py b/lib/ansible/modules/network/meraki/meraki_ssid.py
deleted file mode 100644
index 7148feadcf..0000000000
--- a/lib/ansible/modules/network/meraki/meraki_ssid.py
+++ /dev/null
@@ -1,606 +0,0 @@
-#!/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.
- type: str
- choices: [ absent, query, present ]
- default: present
- number:
- description:
- - SSID number within network.
- type: int
- aliases: [ssid_number]
- name:
- description:
- - Name of SSID.
- type: str
- net_name:
- description:
- - Name of network.
- type: str
- net_id:
- description:
- - ID of network.
- type: str
- enabled:
- description:
- - Enable or disable SSID network.
- type: bool
- auth_mode:
- description:
- - Set authentication mode of network.
- type: str
- choices: [open, psk, open-with-radius, 8021x-meraki, 8021x-radius]
- encryption_mode:
- description:
- - Set encryption mode of network.
- type: str
- choices: [wpa, eap, wpa-eap]
- psk:
- description:
- - Password for wireless network.
- - Requires auth_mode to be set to psk.
- type: str
- wpa_encryption_mode:
- description:
- - Encryption mode within WPA2 specification.
- type: str
- choices: [WPA1 and WPA2, WPA2 only]
- splash_page:
- description:
- - Set to enable splash page and specify type of splash.
- 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:
- description:
- - List of RADIUS servers.
- type: list
- suboptions:
- host:
- description:
- - IP address or hostname of RADIUS server.
- type: str
- port:
- description:
- - Port number RADIUS server is listening to.
- type: int
- secret:
- description:
- - RADIUS password.
- - Setting password is not idempotent.
- type: str
- 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.
- type: str
- choices: [Deny access, Allow access]
- radius_load_balancing_policy:
- description:
- - Set load balancing policy when multiple RADIUS servers are specified.
- type: str
- 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.
- type: list
- suboptions:
- host:
- description:
- - IP address or hostname of RADIUS server.
- type: str
- port:
- description:
- - Port number RADIUS server is listening to.
- type: int
- secret:
- description:
- - RADIUS password.
- - Setting password is not idempotent.
- type: str
- ip_assignment_mode:
- description:
- - Method of which SSID uses to assign IP addresses.
- type: str
- 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.
- - Requires C(default_vlan_id) to be set.
- type: bool
- default_vlan_id:
- description:
- - Default VLAN ID.
- - Requires C(ip_assignment_mode) to be C(Bridge mode) or C(Layer 3 roaming).
- type: int
- vlan_id:
- description:
- - ID number of VLAN on SSID.
- - Requires C(ip_assignment_mode) to be C(ayer 3 roaming with a concentrator) or C(VPN).
- type: int
- ap_tags_vlan_ids:
- description:
- - List of VLAN tags.
- - Requires C(ip_assignment_mode) to be C(Bridge mode) or C(Layer 3 roaming).
- - Requires C(use_vlan_tagging) to be C(True).
- type: list
- suboptions:
- tags:
- description:
- - List of AP tags.
- type: list
- vlan_id:
- description:
- - Numerical identifier that is assigned to the VLAN.
- type: int
- walled_garden_enabled:
- description:
- - Enable or disable walled garden functionality.
- type: bool
- walled_garden_ranges:
- description:
- - List of walled garden ranges.
- type: list
- min_bitrate:
- description:
- - Minimum bitrate (Mbps) allowed on SSID.
- type: float
- choices: [1, 2, 5.5, 6, 9, 11, 12, 18, 24, 36, 48, 54]
- band_selection:
- description:
- - Set band selection mode.
- type: str
- 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.
- type: int
- per_client_bandwidth_limit_down:
- description:
- - Maximum bandwidth in Mbps devices on SSID can download.
- type: int
- concentrator_network_id:
- description:
- - The concentrator to use for 'Layer 3 roaming with a concentrator' or 'VPN'.
- type: str
-author:
-- Kevin Breit (@kbreit)
-extends_documentation_fragment: meraki
-'''
-
-EXAMPLES = r'''
-- name: Enable and name SSID
- meraki_ssid:
- auth_key: abc123
- state: present
- org_name: YourOrg
- net_name: WiFi
- name: GuestSSID
- enabled: true
- delegate_to: localhost
-
-- name: Set PSK with invalid encryption mode
- meraki_ssid:
- auth_key: abc123
- state: present
- org_name: YourOrg
- net_name: WiFi
- name: GuestSSID
- auth_mode: psk
- psk: abc1234
- encryption_mode: eap
- ignore_errors: yes
- delegate_to: localhost
-
-- name: Configure RADIUS servers
- meraki_ssid:
- auth_key: abc123
- state: present
- org_name: YourOrg
- net_name: WiFi
- name: GuestSSID
- auth_mode: open-with-radius
- radius_servers:
- - host: 192.0.1.200
- port: 1234
- secret: abc98765
- delegate_to: localhost
-
-- name: Enable click-through splash page
- meraki_ssid:
- auth_key: abc123
- state: present
- org_name: YourOrg
- net_name: WiFi
- name: GuestSSID
- splash_page: Click-through splash page
- delegate_to: localhost
-'''
-
-RETURN = r'''
-data:
- description: List of wireless SSIDs.
- returned: success
- type: complex
- contains:
- number:
- description: Zero-based index number for SSIDs.
- returned: success
- type: int
- sample: 0
- name:
- description:
- - Name of wireless SSID.
- - This value is what is broadcasted.
- returned: success
- type: str
- sample: CorpWireless
- enabled:
- description: Enabled state of wireless network.
- returned: success
- type: bool
- sample: true
- splash_page:
- description: Splash page to show when user authenticates.
- returned: success
- type: str
- sample: Click-through splash page
- ssid_admin_accessible:
- description: Whether SSID is administratively accessible.
- returned: success
- type: bool
- sample: true
- auth_mode:
- description: Authentication method.
- returned: success
- type: str
- sample: psk
- psk:
- description: Secret wireless password.
- returned: success
- type: str
- sample: SecretWiFiPass
- encryption_mode:
- description: Wireless traffic encryption method.
- returned: success
- type: str
- sample: wpa
- wpa_encryption_mode:
- description: Enabled WPA versions.
- returned: success
- type: str
- sample: WPA2 only
- ip_assignment_mode:
- description: Wireless client IP assignment method.
- returned: success
- type: str
- sample: NAT mode
- min_bitrate:
- description: Minimum bitrate a wireless client can connect at.
- returned: success
- type: int
- sample: 11
- band_selection:
- description: Wireless RF frequency wireless network will be broadcast on.
- returned: success
- type: str
- sample: 5 GHz band only
- per_client_bandwidth_limit_up:
- description: Maximum upload bandwidth a client can use.
- returned: success
- type: int
- sample: 1000
- per_client_bandwidth_limit_down:
- description: Maximum download bandwidth a client can use.
- returned: success
- type: int
- sample: 0
-'''
-
-from ansible.module_utils.basic import AnsibleModule, json
-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', elements='str'),
- 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='str'),
- 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, elements='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', elements='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, elements='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/{number}'}
- 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')
- if meraki.params['use_vlan_tagging'] is True:
- if meraki.params['default_vlan_id'] is None:
- meraki.fail_json(msg="default_vlan_id is required when use_vlan_tagging 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, custom={'number': ssid_id})
- meraki.result['data'] = meraki.request(path, method='GET')
- elif meraki.params['number'] is not None:
- path = meraki.construct_path('get_one', net_id=net_id, custom={'number': 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]
- # Short term solution for camelCase/snake_case differences
- # Will be addressed later with a method in module utils
- if meraki.params['ap_tags_vlan_ids'] is not None:
- for i in payload['apTagsAndVlanIds']:
- try:
- i['vlanId'] = i['vlan_id']
- del i['vlan_id']
- except KeyError:
- pass
- try:
- tags = ','.join(i['tags'])
- del i['tags']
- i['tags'] = tags
- except KeyError:
- pass
- ssids = get_ssids(meraki, net_id)
- number = meraki.params['number']
- if number is None:
- number = get_ssid_number(meraki.params['name'], ssids)
- original = ssids[number]
- if meraki.is_update_required(original, payload, optional_ignore=['secret']):
- 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
- else:
- meraki.result['data'] = original
- 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)
- 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()
diff --git a/lib/ansible/modules/network/meraki/meraki_static_route.py b/lib/ansible/modules/network/meraki/meraki_static_route.py
deleted file mode 100644
index b9e1acd9e6..0000000000
--- a/lib/ansible/modules/network/meraki/meraki_static_route.py
+++ /dev/null
@@ -1,375 +0,0 @@
-#!/usr/bin/python
-# -*- coding: utf-8 -*-
-
-# Copyright: (c) 2018, 2019 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_static_route
-short_description: Manage static routes in the Meraki cloud
-version_added: "2.8"
-description:
-- Allows for creation, management, and visibility into static routes within Meraki.
-
-options:
- state:
- description:
- - Create or modify an organization.
- choices: [ absent, query, present ]
- default: present
- type: str
- net_name:
- description:
- - Name of a network.
- type: str
- net_id:
- description:
- - ID number of a network.
- type: str
- name:
- description:
- - Descriptive name of the static route.
- type: str
- subnet:
- description:
- - CIDR notation based subnet for static route.
- type: str
- gateway_ip:
- description:
- - IP address of the gateway for the subnet.
- type: str
- route_id:
- description:
- - Unique ID of static route.
- type: str
- fixed_ip_assignments:
- description:
- - List of fixed MAC to IP bindings for DHCP.
- type: list
- suboptions:
- mac:
- description:
- - MAC address of endpoint.
- type: str
- ip:
- description:
- - IP address of endpoint.
- type: str
- name:
- description:
- - Hostname of endpoint.
- type: str
- reserved_ip_ranges:
- description:
- - List of IP ranges reserved for static IP assignments.
- type: list
- suboptions:
- start:
- description:
- - First IP address of reserved range.
- type: str
- end:
- description:
- - Last IP address of reserved range.
- type: str
- comment:
- description:
- - Human readable description of reservation range.
- type: str
- enabled:
- description:
- - Indicates whether static route is enabled within a network.
- type: bool
-
-
-author:
- - Kevin Breit (@kbreit)
-extends_documentation_fragment: meraki
-'''
-
-EXAMPLES = r'''
-- name: Create static_route
- meraki_static_route:
- auth_key: abc123
- state: present
- org_name: YourOrg
- net_name: YourNet
- name: Test Route
- subnet: 192.0.1.0/24
- gateway_ip: 192.168.128.1
- delegate_to: localhost
-
-- name: Update static route with fixed IP assignment
- meraki_static_route:
- auth_key: abc123
- state: present
- org_name: YourOrg
- net_name: YourNet
- route_id: d6fa4821-1234-4dfa-af6b-ae8b16c20c39
- fixed_ip_assignments:
- - mac: aa:bb:cc:dd:ee:ff
- ip: 192.0.1.11
- comment: Server
- delegate_to: localhost
-
-- name: Query static routes
- meraki_static_route:
- auth_key: abc123
- state: query
- org_name: YourOrg
- net_name: YourNet
- delegate_to: localhost
-
-- name: Delete static routes
- meraki_static_route:
- auth_key: abc123
- state: absent
- org_name: YourOrg
- net_name: YourNet
- route_id: '{{item}}'
- delegate_to: localhost
-'''
-
-RETURN = r'''
-data:
- description: Information about the created or manipulated object.
- returned: info
- type: complex
- contains:
- id:
- description: Unique identification string assigned to each static route.
- returned: success
- type: str
- sample: d6fa4821-1234-4dfa-af6b-ae8b16c20c39
- net_id:
- description: Identification string of network.
- returned: query or update
- type: str
- sample: N_12345
- name:
- description: Name of static route.
- returned: success
- type: str
- sample: Data Center static route
- subnet:
- description: CIDR notation subnet for static route.
- returned: success
- type: str
- sample: 192.0.1.0/24
- gatewayIp:
- description: Next hop IP address.
- returned: success
- type: str
- sample: 192.1.1.1
- enabled:
- description: Enabled state of static route.
- returned: query or update
- type: bool
- sample: True
- reservedIpRanges:
- description: List of IP address ranges which are reserved for static assignment.
- returned: query or update
- type: complex
- contains:
- start:
- description: First address in reservation range, inclusive.
- returned: query or update
- type: str
- sample: 192.0.1.2
- end:
- description: Last address in reservation range, inclusive.
- returned: query or update
- type: str
- sample: 192.0.1.10
- comment:
- description: Human readable description of range.
- returned: query or update
- type: str
- sample: Server range
- fixedIpAssignments:
- description: List of static MAC to IP address bindings.
- returned: query or update
- type: complex
- contains:
- mac:
- description: Key is MAC address of endpoint.
- returned: query or update
- type: complex
- contains:
- ip:
- description: IP address to be bound to the endpoint.
- returned: query or update
- type: str
- sample: 192.0.1.11
- name:
- description: Hostname given to the endpoint.
- returned: query or update
- type: str
- sample: JimLaptop
-'''
-
-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 fixed_ip_factory(meraki, data):
- fixed_ips = dict()
- for item in data:
- fixed_ips[item['mac']] = {'ip': item['ip'], 'name': item['name']}
- return fixed_ips
-
-
-def get_static_routes(meraki, net_id):
- path = meraki.construct_path('get_all', net_id=net_id)
- r = meraki.request(path, method='GET')
- return r
-
-
-def get_static_route(meraki, net_id, route_id):
- path = meraki.construct_path('get_one', net_id=net_id, custom={'route_id': meraki.params['route_id']})
- r = meraki.request(path, method='GET')
- return r
-
-
-def main():
-
- # define the available arguments/parameters that a user can pass to
- # the module
-
- fixed_ip_arg_spec = dict(mac=dict(type='str'),
- ip=dict(type='str'),
- name=dict(type='str'),
- )
-
- reserved_ip_arg_spec = dict(start=dict(type='str'),
- end=dict(type='str'),
- comment=dict(type='str'),
- )
-
- argument_spec = meraki_argument_spec()
- argument_spec.update(
- net_id=dict(type='str'),
- net_name=dict(type='str'),
- name=dict(type='str'),
- subnet=dict(type='str'),
- gateway_ip=dict(type='str'),
- state=dict(type='str', default='present', choices=['absent', 'present', 'query']),
- fixed_ip_assignments=dict(type='list', elements='dict', options=fixed_ip_arg_spec),
- reserved_ip_ranges=dict(type='list', elements='dict', options=reserved_ip_arg_spec),
- route_id=dict(type='str'),
- enabled=dict(type='bool'),
- )
-
- # 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='static_route')
- module.params['follow_redirects'] = 'all'
- payload = None
-
- query_urls = {'static_route': '/networks/{net_id}/staticRoutes'}
- query_one_urls = {'static_route': '/networks/{net_id}/staticRoutes/{route_id}'}
- create_urls = {'static_route': '/networks/{net_id}/staticRoutes/'}
- update_urls = {'static_route': '/networks/{net_id}/staticRoutes/{route_id}'}
- delete_urls = {'static_route': '/networks/{net_id}/staticRoutes/{route_id}'}
- meraki.url_catalog['get_all'].update(query_urls)
- meraki.url_catalog['get_one'].update(query_one_urls)
- meraki.url_catalog['create'] = create_urls
- meraki.url_catalog['update'] = update_urls
- meraki.url_catalog['delete'] = delete_urls
-
- if not meraki.params['org_name'] and not meraki.params['org_id']:
- meraki.fail_json(msg="Parameters 'org_name' or 'org_id' parameters are required")
- if not meraki.params['net_name'] and not meraki.params['net_id']:
- meraki.fail_json(msg="Parameters 'net_name' or 'net_id' parameters are required")
- if meraki.params['net_name'] and meraki.params['net_id']:
- meraki.fail_json(msg="'net_name' and 'net_id' are mutually exclusive")
-
- # Construct payload
- if meraki.params['state'] == 'present':
- payload = dict()
- if meraki.params['net_name']:
- payload['name'] = meraki.params['net_name']
-
- # 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']
- if not org_id:
- org_id = meraki.get_org_id(meraki.params['org_name'])
- net_id = meraki.params['net_id']
- if net_id is None:
- nets = meraki.get_nets(org_id=org_id)
- net_id = meraki.get_net_id(net_name=meraki.params['net_name'], data=nets)
-
- if meraki.params['state'] == 'query':
- if meraki.params['route_id'] is not None:
- meraki.result['data'] = get_static_route(meraki, net_id, meraki.params['route_id'])
- else:
- meraki.result['data'] = get_static_routes(meraki, net_id)
- elif meraki.params['state'] == 'present':
- payload = {'name': meraki.params['name'],
- 'subnet': meraki.params['subnet'],
- 'gatewayIp': meraki.params['gateway_ip'],
- }
- if meraki.params['fixed_ip_assignments'] is not None:
- payload['fixedIpAssignments'] = fixed_ip_factory(meraki,
- meraki.params['fixed_ip_assignments'])
- if meraki.params['reserved_ip_ranges'] is not None:
- payload['reservedIpRanges'] = meraki.params['reserved_ip_ranges']
- # meraki.fail_json(msg="payload", payload=payload)
- if meraki.params['enabled'] is not None:
- payload['enabled'] = meraki.params['enabled']
- if meraki.params['route_id']:
- existing_route = get_static_route(meraki, net_id, meraki.params['route_id'])
- proposed = existing_route.copy()
- proposed.update(payload)
- if module.check_mode:
- meraki.result['data'] = proposed
- meraki.result['data'].update(payload)
- meraki.exit_json(**meraki.result)
- if meraki.is_update_required(existing_route, proposed, optional_ignore=['id']):
- path = meraki.construct_path('update', net_id=net_id, custom={'route_id': meraki.params['route_id']})
- meraki.result['data'] = meraki.request(path, method="PUT", payload=json.dumps(payload))
- meraki.result['changed'] = True
- else:
- meraki.result['data'] = existing_route
- else:
- if module.check_mode:
- meraki.result['data'] = payload
- meraki.exit_json(**meraki.result)
- path = meraki.construct_path('create', net_id=net_id)
- meraki.result['data'] = meraki.request(path, method="POST", payload=json.dumps(payload))
- meraki.result['changed'] = True
- elif meraki.params['state'] == 'absent':
- if module.check_mode:
- meraki.exit_json(**meraki.result)
- path = meraki.construct_path('delete', net_id=net_id, custom={'route_id': meraki.params['route_id']})
- meraki.result['data'] = meraki.request(path, method='DELETE')
- 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()
diff --git a/lib/ansible/modules/network/meraki/meraki_switchport.py b/lib/ansible/modules/network/meraki/meraki_switchport.py
deleted file mode 100644
index d84ad46620..0000000000
--- a/lib/ansible/modules/network/meraki/meraki_switchport.py
+++ /dev/null
@@ -1,397 +0,0 @@
-#!/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_switchport
-short_description: Manage switchports on a switch in the Meraki cloud
-version_added: "2.7"
-description:
-- Allows for management of switchports settings for Meraki MS switches.
-options:
- state:
- description:
- - Specifies whether a switchport should be queried or modified.
- choices: [query, present]
- default: query
- type: str
- access_policy_number:
- description:
- - Number of the access policy to apply.
- - Only applicable to access port types.
- allowed_vlans:
- description:
- - List of VLAN numbers to be allowed on switchport.
- default: all
- enabled:
- description:
- - Whether a switchport should be enabled or disabled.
- type: bool
- default: yes
- isolation_enabled:
- description:
- - Isolation status of switchport.
- default: no
- type: bool
- link_negotiation:
- description:
- - Link speed for the switchport.
- default: Auto negotiate
- choices: [Auto negotiate, 100Megabit (auto), 100 Megabit full duplex (forced)]
- name:
- description:
- - Switchport description.
- aliases: [description]
- number:
- description:
- - Port number.
- poe_enabled:
- description:
- - Enable or disable Power Over Ethernet on a port.
- type: bool
- default: true
- rstp_enabled:
- description:
- - Enable or disable Rapid Spanning Tree Protocol on a port.
- type: bool
- default: true
- serial:
- description:
- - Serial nubmer of the switch.
- stp_guard:
- description:
- - Set state of STP guard.
- choices: [disabled, root guard, bpdu guard, loop guard]
- default: disabled
- tags:
- description:
- - Space delimited list of tags to assign to a port.
- type:
- description:
- - Set port type.
- choices: [access, trunk]
- default: access
- vlan:
- description:
- - VLAN number assigned to port.
- - If a port is of type trunk, the specified VLAN is the native VLAN.
- voice_vlan:
- description:
- - VLAN number assigned to a port for voice traffic.
- - Only applicable to access port type.
-
-author:
-- Kevin Breit (@kbreit)
-extends_documentation_fragment: meraki
-'''
-
-EXAMPLES = r'''
-- name: Query information about all switchports on a switch
- meraki_switchport:
- auth_key: abc12345
- state: query
- serial: ABC-123
- delegate_to: localhost
-
-- name: Query information about all switchports on a switch
- meraki_switchport:
- auth_key: abc12345
- state: query
- serial: ABC-123
- number: 2
- delegate_to: localhost
-
-- name: Name switchport
- meraki_switchport:
- auth_key: abc12345
- state: present
- serial: ABC-123
- number: 7
- name: Test Port
- delegate_to: localhost
-
-- name: Configure access port with voice VLAN
- meraki_switchport:
- auth_key: abc12345
- state: present
- serial: ABC-123
- number: 7
- enabled: true
- name: Test Port
- tags: desktop
- type: access
- vlan: 10
- voice_vlan: 11
- delegate_to: localhost
-
-- name: Check access port for idempotency
- meraki_switchport:
- auth_key: abc12345
- state: present
- serial: ABC-123
- number: 7
- enabled: true
- name: Test Port
- tags: desktop
- type: access
- vlan: 10
- voice_vlan: 11
- delegate_to: localhost
-
-- name: Configure trunk port with specific VLANs
- meraki_switchport:
- auth_key: abc12345
- state: present
- serial: ABC-123
- number: 7
- enabled: true
- name: Server port
- tags: server
- type: trunk
- allowed_vlans:
- - 10
- - 15
- - 20
- delegate_to: localhost
-'''
-
-RETURN = r'''
-data:
- description: Information queried or updated switchports.
- returned: success
- type: complex
- contains:
- number:
- description: Number of port.
- returned: success
- type: int
- sample: 1
- name:
- description: Human friendly description of port.
- returned: success
- type: str
- sample: "Jim Phone Port"
- tags:
- description: Space delimited list of tags assigned to port.
- returned: success
- type: str
- sample: phone marketing
- enabled:
- description: Enabled state of port.
- returned: success
- type: bool
- sample: true
- poe_enabled:
- description: Power Over Ethernet enabled state of port.
- returned: success
- type: bool
- sample: true
- type:
- description: Type of switchport.
- returned: success
- type: str
- sample: trunk
- vlan:
- description: VLAN assigned to port.
- returned: success
- type: int
- sample: 10
- voice_vlan:
- description: VLAN assigned to port with voice VLAN enabled devices.
- returned: success
- type: int
- sample: 20
- isolation_enabled:
- description: Port isolation status of port.
- returned: success
- type: bool
- sample: true
- rstp_enabled:
- description: Enabled or disabled state of Rapid Spanning Tree Protocol (RSTP)
- returned: success
- type: bool
- sample: true
- stp_guard:
- description: State of STP guard
- returned: success
- type: str
- sample: "Root Guard"
- access_policy_number:
- description: Number of assigned access policy. Only applicable to access ports.
- returned: success
- type: int
- sample: 1234
- link_negotiation:
- description: Link speed for the port.
- returned: success
- type: str
- sample: "Auto negotiate"
-'''
-
-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
-
-param_map = {'access_policy_number': 'accessPolicyNumber',
- 'allowed_vlans': 'allowedVlans',
- 'enabled': 'enabled',
- 'isolation_enabled': 'isolationEnabled',
- 'link_negotiation': 'linkNegotiation',
- 'name': 'name',
- 'number': 'number',
- 'poe_enabled': 'poeEnabled',
- 'rstp_enabled': 'rstpEnabled',
- 'stp_guard': 'stpGuard',
- 'tags': 'tags',
- 'type': 'type',
- 'vlan': 'vlan',
- 'voice_vlan': 'voiceVlan',
- }
-
-
-def sort_vlans(meraki, vlans):
- converted = set()
- for vlan in vlans:
- converted.add(int(vlan))
- vlans_sorted = sorted(converted)
- vlans_str = []
- for vlan in vlans_sorted:
- vlans_str.append(str(vlan))
- return ','.join(vlans_str)
-
-
-def main():
- # define the available arguments/parameters that a user can pass to
- # the module
- argument_spec = meraki_argument_spec()
- argument_spec.update(state=dict(type='str', choices=['present', 'query'], default='query'),
- serial=dict(type='str', required=True),
- number=dict(type='str'),
- name=dict(type='str', aliases=['description']),
- tags=dict(type='str'),
- enabled=dict(type='bool', default=True),
- type=dict(type='str', choices=['access', 'trunk'], default='access'),
- vlan=dict(type='int'),
- voice_vlan=dict(type='int'),
- allowed_vlans=dict(type='list', default='all'),
- poe_enabled=dict(type='bool', default=True),
- isolation_enabled=dict(type='bool', default=False),
- rstp_enabled=dict(type='bool', default=True),
- stp_guard=dict(type='str', choices=['disabled', 'root guard', 'bpdu guard', 'loop guard'], default='disabled'),
- access_policy_number=dict(type='str'),
- link_negotiation=dict(type='str',
- choices=['Auto negotiate', '100Megabit (auto)', '100 Megabit full duplex (forced)'],
- default='Auto negotiate'),
- )
-
- # 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='switchport')
- meraki.params['follow_redirects'] = 'all'
-
- if meraki.params['type'] == 'trunk':
- if not meraki.params['allowed_vlans']:
- meraki.params['allowed_vlans'] = ['all'] # Backdoor way to set default without conflicting on access
-
- query_urls = {'switchport': '/devices/{serial}/switchPorts'}
- query_url = {'switchport': '/devices/{serial}/switchPorts/{number}'}
- update_url = {'switchport': '/devices/{serial}/switchPorts/{number}'}
-
- 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
-
- # manipulate or modify the state as needed (this is going to be the
- # part where your module will do what it needs to do)
- if meraki.params['state'] == 'query':
- if meraki.params['number']:
- path = meraki.construct_path('get_one', custom={'serial': meraki.params['serial'],
- 'number': meraki.params['number'],
- })
- response = meraki.request(path, method='GET')
- meraki.result['data'] = response
- else:
- path = meraki.construct_path('get_all', custom={'serial': meraki.params['serial']})
- response = meraki.request(path, method='GET')
- meraki.result['data'] = response
- elif meraki.params['state'] == 'present':
- payload = dict()
-
- for k, v in meraki.params.items():
- try:
- payload[param_map[k]] = v
- except KeyError:
- pass
-
- allowed = set() # Use a set to remove duplicate items
- if meraki.params['allowed_vlans'][0] == 'all':
- allowed.add('all')
- else:
- for vlan in meraki.params['allowed_vlans']:
- allowed.add(str(vlan))
- if meraki.params['vlan'] is not None:
- allowed.add(str(meraki.params['vlan']))
- if len(allowed) > 1: # Convert from list to comma separated
- payload['allowedVlans'] = sort_vlans(meraki, allowed)
- else:
- payload['allowedVlans'] = next(iter(allowed))
-
- # Exceptions need to be made for idempotency check based on how Meraki returns
- if meraki.params['type'] == 'access':
- if not meraki.params['vlan']: # VLAN needs to be specified in access ports, but can't default to it
- payload['vlan'] = 1
-
- proposed = payload.copy()
- query_path = meraki.construct_path('get_one', custom={'serial': meraki.params['serial'],
- 'number': meraki.params['number'],
- })
- original = meraki.request(query_path, method='GET')
- if meraki.params['type'] == 'trunk':
- proposed['voiceVlan'] = original['voiceVlan'] # API shouldn't include voice VLAN on a trunk port
- if meraki.is_update_required(original, proposed, optional_ignore=['number']):
- path = meraki.construct_path('update', custom={'serial': meraki.params['serial'],
- 'number': meraki.params['number'],
- })
- response = meraki.request(path, method='PUT', payload=json.dumps(payload))
- meraki.result['data'] = response
- meraki.result['changed'] = True
- else:
- meraki.result['data'] = original
-
- # 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()
diff --git a/lib/ansible/modules/network/meraki/meraki_syslog.py b/lib/ansible/modules/network/meraki/meraki_syslog.py
deleted file mode 100644
index 43bba92eb6..0000000000
--- a/lib/ansible/modules/network/meraki/meraki_syslog.py
+++ /dev/null
@@ -1,257 +0,0 @@
-#!/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_syslog
-short_description: Manage syslog server settings in the Meraki cloud.
-version_added: "2.8"
-description:
-- Allows for creation and management of Syslog servers within Meraki.
-notes:
-- Changes to existing syslog servers replaces existing configuration. If you need to add to an
- existing configuration set state to query to gather the existing configuration and then modify or add.
-options:
- auth_key:
- description:
- - Authentication key provided by the dashboard. Required if environmental variable MERAKI_KEY is not set.
- type: str
- state:
- description:
- - Query or edit syslog servers
- - To delete a syslog server, do not include server in list of servers
- choices: [present, query]
- default: present
- type: str
- net_name:
- description:
- - Name of a network.
- aliases: [name, network]
- type: str
- net_id:
- description:
- - ID number of a network.
- type: str
- servers:
- description:
- - List of syslog server settings.
- type: list
- suboptions:
- host:
- description:
- - IP address or hostname of Syslog server.
- type: str
- port:
- description:
- - Port number Syslog server is listening on.
- default: "514"
- type: int
- roles:
- description:
- - List of applicable Syslog server roles.
- choices: ['Wireless Event log',
- 'Appliance event log',
- 'Switch event log',
- 'Air Marshal events',
- 'Flows',
- 'URLs',
- 'IDS alerts',
- 'Security events']
- type: list
-
-author:
- - Kevin Breit (@kbreit)
-extends_documentation_fragment: meraki
-'''
-
-EXAMPLES = r'''
-- name: Query syslog configurations on network named MyNet in the YourOrg organization
- meraki_syslog:
- auth_key: abc12345
- status: query
- org_name: YourOrg
- net_name: MyNet
- delegate_to: localhost
-
-- name: Add single syslog server with Appliance event log role
- meraki_syslog:
- auth_key: abc12345
- status: query
- org_name: YourOrg
- net_name: MyNet
- servers:
- - host: 192.0.1.2
- port: 514
- roles:
- - Appliance event log
- delegate_to: localhost
-
-- name: Add multiple syslog servers
- meraki_syslog:
- auth_key: abc12345
- status: query
- org_name: YourOrg
- net_name: MyNet
- servers:
- - host: 192.0.1.2
- port: 514
- roles:
- - Appliance event log
- - host: 192.0.1.3
- port: 514
- roles:
- - Appliance event log
- - Flows
- delegate_to: localhost
-'''
-
-RETURN = r'''
-data:
- description: Information about the created or manipulated object.
- returned: info
- type: complex
- contains:
- host:
- description: Hostname or IP address of syslog server.
- returned: success
- type: str
- sample: 192.0.1.1
- port:
- description: Port number for syslog communication.
- returned: success
- type: str
- sample: 443
- roles:
- description: List of roles assigned to syslog server.
- returned: success
- type: list
- sample: "Wireless event log, URLs"
-'''
-
-from ansible.module_utils.basic import AnsibleModule, json
-from ansible.module_utils.common.dict_transformations import recursive_diff
-from ansible.module_utils.network.meraki.meraki import MerakiModule, meraki_argument_spec
-
-
-def main():
-
- # define the available arguments/parameters that a user can pass to
- # the module
-
- server_arg_spec = dict(host=dict(type='str'),
- port=dict(type='int', default="514"),
- roles=dict(type='list', choices=['Wireless Event log',
- 'Appliance event log',
- 'Switch event log',
- 'Air Marshal events',
- 'Flows',
- 'URLs',
- 'IDS alerts',
- 'Security events',
- ]),
- )
-
- argument_spec = meraki_argument_spec()
- argument_spec.update(net_id=dict(type='str'),
- servers=dict(type='list', elements='dict', options=server_arg_spec),
- state=dict(type='str', choices=['present', 'query'], default='present'),
- net_name=dict(type='str', aliases=['name', 'network']),
- )
-
- # 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='syslog')
- module.params['follow_redirects'] = 'all'
- payload = None
-
- syslog_urls = {'syslog': '/networks/{net_id}/syslogServers'}
- meraki.url_catalog['query_update'] = syslog_urls
-
- if not meraki.params['org_name'] and not meraki.params['org_id']:
- meraki.fail_json(msg='org_name or org_id parameters are required')
- if meraki.params['state'] != 'query':
- if not meraki.params['net_name'] and not meraki.params['net_id']:
- meraki.fail_json(msg='net_name or net_id is required for present or absent states')
- if meraki.params['net_name'] and meraki.params['net_id']:
- meraki.fail_json(msg='net_name and net_id are mutually exclusive')
-
- # 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
-
- # 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']
- if not org_id:
- org_id = meraki.get_org_id(meraki.params['org_name'])
- net_id = meraki.params['net_id']
- if net_id is None:
- nets = meraki.get_nets(org_id=org_id)
- net_id = meraki.get_net_id(net_name=meraki.params['net_name'], data=nets)
-
- if meraki.params['state'] == 'query':
- path = meraki.construct_path('query_update', net_id=net_id)
- r = meraki.request(path, method='GET')
- if meraki.status == 200:
- meraki.result['data'] = r
- elif meraki.params['state'] == 'present':
- # Construct payload
- payload = dict()
- payload['servers'] = meraki.params['servers']
-
- # Convert port numbers to string for idempotency checks
- for server in payload['servers']:
- if server['port']:
- server['port'] = str(server['port'])
- path = meraki.construct_path('query_update', net_id=net_id)
- r = meraki.request(path, method='GET')
- if meraki.status == 200:
- original = dict()
- original['servers'] = r
-
- if meraki.is_update_required(original, payload):
- if meraki.module.check_mode is True:
- diff = recursive_diff(original, payload)
- original.update(payload)
- meraki.result['diff'] = {'before': diff[0],
- 'after': diff[1]}
- meraki.result['data'] = original
- meraki.result['changed'] = True
- meraki.exit_json(**meraki.result)
- path = meraki.construct_path('query_update', net_id=net_id)
- r = meraki.request(path, method='PUT', payload=json.dumps(payload))
- if meraki.status == 200:
- meraki.result['data'] = r
- meraki.result['changed'] = True
- else:
- if meraki.module.check_mode is True:
- meraki.result['data'] = original
- meraki.exit_json(**meraki.result)
- meraki.result['data'] = original
-
- # 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()
diff --git a/lib/ansible/modules/network/meraki/meraki_vlan.py b/lib/ansible/modules/network/meraki/meraki_vlan.py
deleted file mode 100644
index 3cb17e7492..0000000000
--- a/lib/ansible/modules/network/meraki/meraki_vlan.py
+++ /dev/null
@@ -1,446 +0,0 @@
-#!/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_vlan
-short_description: Manage VLANs in the Meraki cloud
-version_added: "2.7"
-description:
-- Create, edit, query, or delete VLANs in a Meraki environment.
-notes:
-- Meraki's API will return an error if VLANs aren't enabled on a network. VLANs are returned properly if VLANs are enabled on a network.
-- Some of the options are likely only used for developers within Meraki.
-- Meraki's API defaults to networks having VLAN support disabled and there is no way to enable VLANs support in the API. VLAN support must be enabled manually.
-options:
- state:
- description:
- - Specifies whether object should be queried, created/modified, or removed.
- choices: [absent, present, query]
- default: query
- type: str
- net_name:
- description:
- - Name of network which VLAN is in or should be in.
- aliases: [network]
- type: str
- net_id:
- description:
- - ID of network which VLAN is in or should be in.
- type: str
- vlan_id:
- description:
- - ID number of VLAN.
- - ID should be between 1-4096.
- type: int
- name:
- description:
- - Name of VLAN.
- aliases: [vlan_name]
- type: str
- subnet:
- description:
- - CIDR notation of network subnet.
- type: str
- appliance_ip:
- description:
- - IP address of appliance.
- - Address must be within subnet specified in C(subnet) parameter.
- type: str
- dns_nameservers:
- description:
- - Semi-colon delimited list of DNS IP addresses.
- - Specify one of the following options for preprogrammed DNS entries opendns, google_dns, upstream_dns
- type: str
- reserved_ip_range:
- description:
- - IP address ranges which should be reserve and not distributed via DHCP.
- type: list
- vpn_nat_subnet:
- description:
- - The translated VPN subnet if VPN and VPN subnet translation are enabled on the VLAN.
- type: str
- fixed_ip_assignments:
- description:
- - Static IP address assignments to be distributed via DHCP by MAC address.
- type: list
-author:
-- Kevin Breit (@kbreit)
-extends_documentation_fragment: meraki
-'''
-
-EXAMPLES = r'''
-- name: Query all VLANs in a network.
- meraki_vlan:
- auth_key: abc12345
- org_name: YourOrg
- net_name: YourNet
- state: query
- delegate_to: localhost
-
-- name: Query information about a single VLAN by ID.
- meraki_vlan:
- auth_key: abc12345
- org_name: YourOrg
- net_name: YourNet
- vlan_id: 2
- state: query
- delegate_to: localhost
-
-- name: Create a VLAN.
- meraki_vlan:
- auth_key: abc12345
- org_name: YourOrg
- net_name: YourNet
- state: present
- vlan_id: 2
- name: TestVLAN
- subnet: 192.0.1.0/24
- appliance_ip: 192.0.1.1
- delegate_to: localhost
-
-- name: Update a VLAN.
- meraki_vlan:
- auth_key: abc12345
- org_name: YourOrg
- net_name: YourNet
- state: present
- vlan_id: 2
- name: TestVLAN
- subnet: 192.0.1.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
-
-- name: Delete a VLAN.
- meraki_vlan:
- auth_key: abc12345
- org_name: YourOrg
- net_name: YourNet
- state: absent
- vlan_id: 2
- delegate_to: localhost
-'''
-
-RETURN = r'''
-
-response:
- description: Information about the organization which was created or modified
- returned: success
- type: complex
- contains:
- appliance_ip:
- description: IP address of Meraki appliance in the VLAN
- returned: success
- type: str
- sample: 192.0.1.1
- dnsnamservers:
- description: IP address or Meraki defined DNS servers which VLAN should use by default
- returned: success
- type: str
- sample: upstream_dns
- fixed_ip_assignments:
- description: List of MAC addresses which have IP addresses assigned.
- returned: success
- type: complex
- contains:
- macaddress:
- description: MAC address which has IP address assigned to it. Key value is the actual MAC address.
- returned: success
- type: complex
- contains:
- ip:
- description: IP address which is assigned to the MAC address.
- returned: success
- type: str
- sample: 192.0.1.4
- name:
- description: Descriptive name for binding.
- returned: success
- type: str
- sample: fixed_ip
- reserved_ip_ranges:
- description: List of IP address ranges which are reserved for static assignment.
- returned: success
- type: complex
- contains:
- comment:
- description: Description for IP address reservation.
- returned: success
- type: str
- sample: reserved_range
- end:
- description: Last IP address in reservation range.
- returned: success
- type: str
- sample: 192.0.1.10
- start:
- description: First IP address in reservation range.
- returned: success
- type: str
- sample: 192.0.1.5
- id:
- description: VLAN ID number.
- returned: success
- type: int
- sample: 2
- name:
- description: Descriptive name of VLAN.
- returned: success
- type: str
- sample: TestVLAN
- networkId:
- description: ID number of Meraki network which VLAN is associated to.
- returned: success
- type: str
- sample: N_12345
- subnet:
- description: CIDR notation IP subnet of VLAN.
- returned: success
- type: str
- sample: "192.0.1.0/24"
- dhcp_handling:
- description: Status of DHCP server on VLAN.
- returned: success
- type: str
- sample: Run a DHCP server
- dhcp_lease_time:
- description: DHCP lease time when server is active.
- returned: success
- type: str
- sample: 1 day
- dhcp_boot_options_enabled:
- description: Whether DHCP boot options are enabled.
- returned: success
- type: bool
- sample: no
- dhcp_boot_next_server:
- description: DHCP boot option to direct boot clients to the server to load the boot file from.
- returned: success
- type: str
- sample: 192.0.1.2
- dhcp_boot_filename:
- description: Filename for boot file.
- returned: success
- type: str
- sample: boot.txt
- dhcp_options:
- description: DHCP options.
- returned: success
- type: complex
- contains:
- code:
- description:
- - Code for DHCP option.
- - Integer between 2 and 254.
- returned: success
- type: int
- sample: 43
- type:
- description:
- - Type for DHCP option.
- - Choices are C(text), C(ip), C(hex), C(integer).
- returned: success
- type: str
- sample: text
- value:
- description: Value for the DHCP option.
- returned: success
- type: str
- sample: 192.0.1.2
-'''
-
-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
-
-
-def fixed_ip_factory(meraki, data):
- fixed_ips = dict()
- for item in data:
- fixed_ips[item['mac']] = {'ip': item['ip'], 'name': item['name']}
- return fixed_ips
-
-
-def get_vlans(meraki, net_id):
- path = meraki.construct_path('get_all', net_id=net_id)
- return meraki.request(path, method='GET')
-
-
-# TODO: Allow method to return actual item if True to reduce number of calls needed
-def is_vlan_valid(meraki, net_id, vlan_id):
- vlans = get_vlans(meraki, net_id)
- for vlan in vlans:
- if vlan_id == vlan['id']:
- return True
- return False
-
-
-def format_dns(nameservers):
- return nameservers.replace(';', '\n')
-
-
-def main():
- # define the available arguments/parameters that a user can pass to
- # the module
-
- fixed_ip_arg_spec = dict(mac=dict(type='str'),
- ip=dict(type='str'),
- name=dict(type='str'),
- )
-
- reserved_ip_arg_spec = dict(start=dict(type='str'),
- end=dict(type='str'),
- comment=dict(type='str'),
- )
-
- argument_spec = meraki_argument_spec()
- argument_spec.update(state=dict(type='str', choices=['absent', 'present', 'query'], default='query'),
- net_name=dict(type='str', aliases=['network']),
- net_id=dict(type='str'),
- vlan_id=dict(type='int'),
- name=dict(type='str', aliases=['vlan_name']),
- subnet=dict(type='str'),
- appliance_ip=dict(type='str'),
- fixed_ip_assignments=dict(type='list', default=None, elements='dict', options=fixed_ip_arg_spec),
- reserved_ip_range=dict(type='list', default=None, elements='dict', options=reserved_ip_arg_spec),
- vpn_nat_subnet=dict(type='str'),
- dns_nameservers=dict(type='str'),
- )
-
- # 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='vlan')
-
- meraki.params['follow_redirects'] = 'all'
-
- query_urls = {'vlan': '/networks/{net_id}/vlans'}
- query_url = {'vlan': '/networks/{net_id}/vlans/{vlan_id}'}
- create_url = {'vlan': '/networks/{net_id}/vlans'}
- update_url = {'vlan': '/networks/{net_id}/vlans/'}
- delete_url = {'vlan': '/networks/{net_id}/vlans/'}
-
- meraki.url_catalog['get_all'].update(query_urls)
- meraki.url_catalog['get_one'].update(query_url)
- meraki.url_catalog['create'] = create_url
- meraki.url_catalog['update'] = update_url
- meraki.url_catalog['delete'] = delete_url
-
- payload = None
-
- org_id = meraki.params['org_id']
- if org_id is None:
- org_id = meraki.get_org_id(meraki.params['org_name'])
- net_id = meraki.params['net_id']
- if net_id is None:
- nets = meraki.get_nets(org_id=org_id)
- net_id = meraki.get_net_id(net_name=meraki.params['net_name'], data=nets)
-
- if meraki.params['state'] == 'query':
- if not meraki.params['vlan_id']:
- meraki.result['data'] = get_vlans(meraki, net_id)
- else:
- path = meraki.construct_path('get_one', net_id=net_id, custom={'vlan_id': meraki.params['vlan_id']})
- response = meraki.request(path, method='GET')
- meraki.result['data'] = response
- elif meraki.params['state'] == 'present':
- payload = {'id': meraki.params['vlan_id'],
- 'name': meraki.params['name'],
- 'subnet': meraki.params['subnet'],
- 'applianceIp': meraki.params['appliance_ip'],
- }
- 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: # 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']:
- if meraki.params['dns_nameservers'] not in ('opendns', 'google_dns', 'upstream_dns'):
- payload['dnsNameservers'] = format_dns(meraki.params['dns_nameservers'])
- else:
- payload['dnsNameservers'] = meraki.params['dns_nameservers']
- if meraki.params['fixed_ip_assignments']:
- payload['fixedIpAssignments'] = fixed_ip_factory(meraki, meraki.params['fixed_ip_assignments'])
- if meraki.params['reserved_ip_range']:
- payload['reservedIpRanges'] = meraki.params['reserved_ip_range']
- if meraki.params['vpn_nat_subnet']:
- 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
-
- # 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()
diff --git a/lib/ansible/modules/network/meraki/meraki_webhook.py b/lib/ansible/modules/network/meraki/meraki_webhook.py
deleted file mode 100644
index 53fc62ffa5..0000000000
--- a/lib/ansible/modules/network/meraki/meraki_webhook.py
+++ /dev/null
@@ -1,342 +0,0 @@
-#!/usr/bin/python
-# -*- coding: utf-8 -*-
-
-# Copyright: (c) 2019, 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_webhook
-short_description: Manage webhooks configured in the Meraki cloud
-version_added: "2.9"
-description:
-- Configure and query information about webhooks within the Meraki cloud.
-notes:
-- Some of the options are likely only used for developers within Meraki.
-options:
- state:
- description:
- - Specifies whether object should be queried, created/modified, or removed.
- choices: [absent, present, query]
- default: query
- type: str
- net_name:
- description:
- - Name of network which configuration is applied to.
- aliases: [network]
- type: str
- net_id:
- description:
- - ID of network which configuration is applied to.
- type: str
- name:
- description:
- - Name of webhook.
- type: str
- shared_secret:
- description:
- - Secret password to use when accessing webhook.
- type: str
- url:
- description:
- - URL to access when calling webhook.
- type: str
- webhook_id:
- description:
- - Unique ID of webhook.
- type: str
- test:
- description:
- - Indicates whether to test or query status.
- type: str
- choices: [test, status]
- test_id:
- description:
- - ID of webhook test query.
- type: str
-author:
-- Kevin Breit (@kbreit)
-extends_documentation_fragment: meraki
-'''
-
-EXAMPLES = r'''
-- name: Create webhook
- meraki_webhook:
- auth_key: abc123
- state: present
- org_name: YourOrg
- net_name: YourNet
- name: Test_Hook
- url: https://webhook.url/
- shared_secret: shhhdonttellanyone
- delegate_to: localhost
-
-- name: Query one webhook
- meraki_webhook:
- auth_key: abc123
- state: query
- org_name: YourOrg
- net_name: YourNet
- name: Test_Hook
- delegate_to: localhost
-
-- name: Query all webhooks
- meraki_webhook:
- auth_key: abc123
- state: query
- org_name: YourOrg
- net_name: YourNet
- delegate_to: localhost
-
-- name: Delete webhook
- meraki_webhook:
- auth_key: abc123
- state: absent
- org_name: YourOrg
- net_name: YourNet
- name: Test_Hook
- delegate_to: localhost
-
-- name: Test webhook
- meraki_webhook:
- auth_key: abc123
- state: present
- org_name: YourOrg
- net_name: YourNet
- test: test
- url: https://webhook.url/abc123
- delegate_to: localhost
-
-- name: Get webhook status
- meraki_webhook:
- auth_key: abc123
- state: present
- org_name: YourOrg
- net_name: YourNet
- test: status
- test_id: abc123531234
- delegate_to: localhost
-'''
-
-RETURN = r'''
-data:
- description: List of administrators.
- returned: success
- type: complex
- contains:
- id:
- description: Unique ID of webhook.
- returned: success
- type: str
- sample: aHR0cHM6Ly93ZWJob22LnvpdGUvOGViNWI3NmYtYjE2Ny00Y2I4LTlmYzQtND32Mj3F5NzIaMjQ0
- name:
- description: Descriptive name of webhook.
- returned: success
- type: str
- sample: Test_Hook
- networkId:
- description: ID of network containing webhook object.
- returned: success
- type: str
- sample: N_12345
- shared_secret:
- description: Password for webhook.
- returned: success
- type: str
- sample: VALUE_SPECIFIED_IN_NO_LOG_PARAMETER
- url:
- description: URL of webhook endpoint.
- returned: success
- type: str
- sample: https://webhook.url/abc123
- status:
- description: Status of webhook test.
- returned: success, when testing webhook
- type: str
- sample: enqueued
-'''
-
-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
-
-
-def get_webhook_id(name, webhooks):
- for webhook in webhooks:
- if name == webhook['name']:
- return webhook['id']
- return None
-
-
-def get_all_webhooks(meraki, net_id):
- path = meraki.construct_path('get_all', net_id=net_id)
- response = meraki.request(path, method='GET')
- if meraki.status == 200:
- return response
-
-
-def main():
- # define the available arguments/parameters that a user can pass to
- # the module
-
- argument_spec = meraki_argument_spec()
- argument_spec.update(state=dict(type='str', choices=['absent', 'present', 'query'], default='query'),
- net_name=dict(type='str', aliases=['network']),
- net_id=dict(type='str'),
- name=dict(type='str'),
- url=dict(type='str'),
- shared_secret=dict(type='str', no_log=True),
- webhook_id=dict(type='str'),
- test=dict(type='str', choices=['test', 'status']),
- test_id=dict(type='str'),
- )
-
- # 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='webhooks')
-
- meraki.params['follow_redirects'] = 'all'
-
- query_url = {'webhooks': '/networks/{net_id}/httpServers'}
- query_one_url = {'webhooks': '/networks/{net_id}/httpServers/{hookid}'}
- create_url = {'webhooks': '/networks/{net_id}/httpServers'}
- update_url = {'webhooks': '/networks/{net_id}/httpServers/{hookid}'}
- delete_url = {'webhooks': '/networks/{net_id}/httpServers/{hookid}'}
- test_url = {'webhooks': '/networks/{net_id}/httpServers/webhookTests'}
- test_status_url = {'webhooks': '/networks/{net_id}/httpServers/webhookTests/{testid}'}
-
- meraki.url_catalog['get_all'].update(query_url)
- meraki.url_catalog['get_one'].update(query_one_url)
- meraki.url_catalog['create'] = create_url
- meraki.url_catalog['update'] = update_url
- meraki.url_catalog['delete'] = delete_url
- meraki.url_catalog['test'] = test_url
- meraki.url_catalog['test_status'] = test_status_url
-
- org_id = meraki.params['org_id']
- if org_id is None:
- org_id = meraki.get_org_id(meraki.params['org_name'])
- net_id = meraki.params['net_id']
- if net_id is None:
- nets = meraki.get_nets(org_id=org_id)
- net_id = meraki.get_net_id(net_name=meraki.params['net_name'], data=nets)
- webhook_id = meraki.params['webhook_id']
- if webhook_id is None and meraki.params['name']:
- webhooks = get_all_webhooks(meraki, net_id)
- webhook_id = get_webhook_id(meraki.params['name'], webhooks)
-
- if meraki.params['state'] == 'present' and meraki.params['test'] is None:
- payload = {'name': meraki.params['name'],
- 'url': meraki.params['url'],
- 'sharedSecret': meraki.params['shared_secret']}
-
- if meraki.params['state'] == 'query':
- if webhook_id is not None: # Query a single webhook
- path = meraki.construct_path('get_one', net_id=net_id, custom={'hookid': webhook_id})
- response = meraki.request(path, method='GET')
- if meraki.status == 200:
- meraki.result['data'] = response
- else:
- path = meraki.construct_path('get_all', net_id=net_id)
- response = meraki.request(path, method='GET')
- if meraki.status == 200:
- meraki.result['data'] = response
- elif meraki.params['state'] == 'present':
- if meraki.params['test'] == 'test':
- payload = {'url': meraki.params['url']}
- path = meraki.construct_path('test', net_id=net_id)
- response = meraki.request(path, method='POST', payload=json.dumps(payload))
- if meraki.status == 200:
- meraki.result['data'] = response
- meraki.exit_json(**meraki.result)
- elif meraki.params['test'] == 'status':
- if meraki.params['test_id'] is None:
- meraki.fail_json("test_id is required when querying test status.")
- path = meraki.construct_path('test_status', net_id=net_id, custom={'testid': meraki.params['test_id']})
- response = meraki.request(path, method='GET')
- if meraki.status == 200:
- meraki.result['data'] = response
- meraki.exit_json(**meraki.result)
- if webhook_id is None: # Make sure it is downloaded
- if webhooks is None:
- webhooks = get_all_webhooks(meraki, net_id)
- webhook_id = get_webhook_id(meraki.params['name'], webhooks)
- if webhook_id is None: # Test to see if it needs to be created
- if meraki.check_mode is True:
- meraki.result['data'] = payload
- meraki.result['data']['networkId'] = net_id
- 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))
- if meraki.status == 201:
- meraki.result['data'] = response
- meraki.result['changed'] = True
- else: # Need to update
- path = meraki.construct_path('get_one', net_id=net_id, custom={'hookid': webhook_id})
- original = meraki.request(path, method='GET')
- if meraki.is_update_required(original, payload):
- if meraki.check_mode is True:
- diff = recursive_diff(original, payload)
- original.update(payload)
- meraki.result['diff'] = {'before': diff[0],
- 'after': diff[1]}
- meraki.result['data'] = original
- meraki.result['changed'] = True
- meraki.exit_json(**meraki.result)
- path = meraki.construct_path('update', net_id=net_id, custom={'hookid': webhook_id})
- response = meraki.request(path, method='PUT', payload=json.dumps(payload))
- if meraki.status == 200:
- meraki.result['data'] = response
- meraki.result['changed'] = True
- else:
- meraki.result['data'] = original
- elif meraki.params['state'] == 'absent':
- if webhook_id is None: # Make sure it is downloaded
- if webhooks is None:
- webhooks = get_all_webhooks(meraki, net_id)
- webhook_id = get_webhook_id(meraki.params['name'], webhooks)
- if webhook_id is None:
- meraki.fail_json(msg="There is no webhook with the name {0}".format(meraki.params['name']))
- if webhook_id: # Test to see if it exists
- if meraki.module.check_mode is True:
- meraki.result['data'] = None
- meraki.result['changed'] = True
- meraki.exit_json(**meraki.result)
- path = meraki.construct_path('delete', net_id=net_id, custom={'hookid': webhook_id})
- response = meraki.request(path, method='DELETE')
- if meraki.status == 204:
- meraki.result['data'] = response
- 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()
diff --git a/lib/ansible/plugins/doc_fragments/meraki.py b/lib/ansible/plugins/doc_fragments/meraki.py
deleted file mode 100644
index 8a5cd98d94..0000000000
--- a/lib/ansible/plugins/doc_fragments/meraki.py
+++ /dev/null
@@ -1,78 +0,0 @@
-# -*- 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)
-
-
-class ModuleDocFragment(object):
- # Standard files for documentation fragment
- DOCUMENTATION = r'''
-notes:
-- 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.
-- 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:
- auth_key:
- description:
- - Authentication key provided by the dashboard. Required if environmental variable C(MERAKI_KEY) is not set.
- type: str
- required: yes
- host:
- description:
- - Hostname for Meraki dashboard.
- - Can be used to access regional Meraki environments, such as China.
- type: str
- default: api.meraki.com
- use_proxy:
- description:
- - If C(no), it will not use a proxy, even if one is defined in an environment variable on the target hosts.
- type: bool
- use_https:
- description:
- - If C(no), it will use HTTP. Otherwise it will use HTTPS.
- - Only useful for internal Meraki developers.
- type: bool
- 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:
- description:
- - Set amount of debug output during module execution.
- type: str
- choices: [ debug, normal ]
- default: normal
- timeout:
- description:
- - Time to timeout for HTTP requests.
- type: int
- default: 30
- validate_certs:
- description:
- - Whether to validate HTTP certificates.
- type: bool
- default: yes
- org_name:
- description:
- - Name of organization.
- type: str
- aliases: [ organization ]
- org_id:
- description:
- - ID of organization.
- type: str
- rate_limit_retry_time:
- description:
- - Number of seconds to retry if rate limiter is triggered.
- type: int
- default: 165
- internal_error_retry_time:
- description:
- - Number of seconds to retry if server returns an internal server error.
- type: int
- default: 60
-'''
diff --git a/test/integration/targets/meraki_admin/tasks/main.yml b/test/integration/targets/meraki_admin/tasks/main.yml
deleted file mode 100644
index 2fcc9eb6e9..0000000000
--- a/test/integration/targets/meraki_admin/tasks/main.yml
+++ /dev/null
@@ -1,384 +0,0 @@
-# Test code for the Meraki Admin 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: Create new administrator in check mode
- meraki_admin:
- auth_key: '{{auth_key}}'
- state: present
- org_name: '{{test_org_name}}'
- name: Jane Doe
- email: '{{email_prefix}}+janedoe@{{email_domain}}'
- org_access: read-only
- delegate_to: localhost
- check_mode: yes
- register: create_org_check
-
- - name: Create new admin check mode assertion
- assert:
- that:
- - create_org_check is changed
- - 'create_org_check.data.name == "Jane Doe"'
-
- - name: Create new administrator
- meraki_admin:
- auth_key: '{{auth_key}}'
- state: present
- org_name: '{{test_org_name}}'
- name: Jane Doe
- email: '{{email_prefix}}+janedoe@{{email_domain}}'
- org_access: read-only
- delegate_to: localhost
- register: create_orgaccess
-
- - name: Create new admin assertion
- assert:
- that:
- - create_orgaccess.changed == true
- - 'create_orgaccess.data.name == "Jane Doe"'
-
- - name: Delete recently created administrator with check mode
- meraki_admin:
- auth_key: '{{auth_key}}'
- state: absent
- org_name: '{{test_org_name}}'
- email: '{{email_prefix}}+janedoe@{{email_domain}}'
- delegate_to: localhost
- register: delete_one_check
- check_mode: yes
-
- - assert:
- that:
- - delete_one_check is changed
-
- - name: Delete recently created administrator
- meraki_admin:
- auth_key: '{{auth_key}}'
- state: absent
- org_name: '{{test_org_name}}'
- email: '{{email_prefix}}+janedoe@{{email_domain}}'
- delegate_to: localhost
- register: delete_one
-
- - name: Create new administrator with org_id
- meraki_admin:
- auth_key: '{{auth_key}}'
- state: present
- org_id: '{{test_org_id}}'
- name: Jane Doe
- email: '{{email_prefix}}+janedoe@{{email_domain}}'
- orgAccess: read-only
- delegate_to: localhost
- register: create_orgaccess_id
-
- - name: Create new admin assertion
- assert:
- that:
- - create_orgaccess_id.changed == true
- - 'create_orgaccess_id.data.name == "Jane Doe"'
-
- - name: Create administrator with tags with check mode
- meraki_admin:
- auth_key: '{{auth_key}}'
- state: present
- org_name: '{{test_org_name}}'
- name: John Doe
- email: '{{email_prefix}}+johndoe@{{email_domain}}'
- orgAccess: none
- tags:
- - { "tag": "production", "access": "read-only" }
- - tag: beta
- access: full
- delegate_to: localhost
- register: create_tags_check
- check_mode: yes
-
- - debug:
- var: create_tags_check
-
- - assert:
- that:
- - create_tags_check is changed
- - create_tags_check.data.name == "John Doe"
- - create_tags_check.data.tags | length == 2
-
- - name: Create administrator with tags
- meraki_admin:
- auth_key: '{{auth_key}}'
- state: present
- org_name: '{{test_org_name}}'
- name: John Doe
- email: '{{email_prefix}}+johndoe@{{email_domain}}'
- orgAccess: none
- tags:
- - { "tag": "production", "access": "read-only" }
- - tag: beta
- access: full
- delegate_to: localhost
- register: create_tags
-
- - assert:
- that:
- - create_tags.changed == true
- - create_tags.data.name == "John Doe"
- - create_tags.data.tags | length == 2
-
- - name: Create administrator with invalid tags
- meraki_admin:
- auth_key: '{{auth_key}}'
- state: present
- org_name: '{{test_org_name}}'
- name: Jake Doe
- email: '{{email_prefix}}+jakedoe@{{email_domain}}'
- orgAccess: none
- tags:
- - { "tag": "production", "access": "read-only" }
- - { "tag": "alpha", "access": "invalid" }
- delegate_to: localhost
- register: create_tags_invalid
- ignore_errors: yes
-
- - assert:
- that:
- - '"400" in create_tags_invalid.msg'
- # - '"must contain only valid tags" in create_tags_invalid.msg'
-
- - name: Create administrator with invalid tag permission
- meraki_admin:
- auth_key: '{{auth_key}}'
- state: present
- org_name: '{{test_org_name}}'
- name: Jake Doe
- email: '{{email_prefix}}+jakedoe@{{email_domain}}'
- orgAccess: none
- tags:
- - { "tag": "production", "access": "read-only" }
- - { "tag": "beta", "access": "invalid" }
- delegate_to: localhost
- register: create_tags_invalid_permission
- ignore_errors: yes
-
- - assert:
- that:
- - '"400" in create_tags_invalid_permission.msg'
- # - '"Invalid permission type" in create_tags_invalid_permission.msg'
-
- - name: Make sure TestNet and TestNet2 are created
- meraki_network:
- auth_key: '{{auth_key}}'
- state: present
- org_name: '{{test_org_name}}'
- net_name: '{{item}}'
- type: switch
- loop:
- - TestNet
- - TestNet2
-
- - name: Create administrator with networks with check mode
- meraki_admin:
- auth_key: '{{auth_key}}'
- state: present
- org_name: '{{test_org_name}}'
- name: Jim Doe
- email: '{{email_prefix}}+jimdoe@{{email_domain}}'
- orgAccess: none
- networks:
- - { "network": "TestNet", "access": "read-only" }
- - { "network": "TestNet2", "access": "full" }
- delegate_to: localhost
- register: create_network_check
- check_mode: yes
-
- - assert:
- that:
- - create_network_check is changed
- - create_network_check.data.name == "Jim Doe"
- - create_network_check.data.networks | length == 2
-
- - name: Create administrator with networks
- meraki_admin:
- auth_key: '{{auth_key}}'
- state: present
- org_name: '{{test_org_name}}'
- name: Jim Doe
- email: '{{email_prefix}}+jimdoe@{{email_domain}}'
- orgAccess: none
- networks:
- - { "network": "TestNet", "access": "read-only" }
- - { "network": "TestNet2", "access": "full" }
- delegate_to: localhost
- register: create_network
-
- - assert:
- that:
- - create_network.changed == true
- - create_network.data.name == "Jim Doe"
- - create_network.data.networks | length == 2
-
- - name: Update administrator with check mode
- meraki_admin:
- auth_key: '{{auth_key}}'
- state: present
- org_name: '{{test_org_name}}'
- name: Jim Doe
- email: '{{email_prefix}}+jimdoe@{{email_domain}}'
- orgAccess: none
- networks:
- - { "network": "TestNet", "access": "full" }
- delegate_to: localhost
- register: update_network_check
- check_mode: yes
-
- - debug:
- var: update_network_check
-
- - assert:
- that:
- - update_network_check is changed
- - update_network_check.data.networks.0.access == "full"
- - update_network_check.data.networks | length == 1
-
- - name: Update administrator
- meraki_admin:
- auth_key: '{{auth_key}}'
- state: present
- org_name: '{{test_org_name}}'
- name: Jim Doe
- email: '{{email_prefix}}+jimdoe@{{email_domain}}'
- orgAccess: none
- networks:
- - { "network": "TestNet", "access": "full" }
- delegate_to: localhost
- register: update_network
-
- - assert:
- that:
- - update_network.changed == true
- - update_network.data.networks.0.access == "full"
- - update_network.data.networks | length == 1
-
- - name: Update administrator for idempotency check with check mode
- meraki_admin:
- auth_key: '{{auth_key}}'
- state: present
- org_name: '{{test_org_name}}'
- name: Jim Doe
- email: '{{email_prefix}}+jimdoe@{{email_domain}}'
- orgAccess: none
- networks:
- - { "network": "TestNet", "access": "full" }
- delegate_to: localhost
- register: update_network_idempotent_check
- check_mode: yes
-
- - debug:
- var: update_network_idempotent_check
-
- - assert:
- that:
- - update_network_idempotent_check is not changed
-
- - name: Update administrator for idempotency
- meraki_admin:
- auth_key: '{{auth_key}}'
- state: present
- org_name: '{{test_org_name}}'
- name: Jim Doe
- email: '{{email_prefix}}+jimdoe@{{email_domain}}'
- orgAccess: none
- networks:
- - { "network": "TestNet", "access": "full" }
- delegate_to: localhost
- register: update_network_idempotent
-
- - assert:
- that:
- - update_network_idempotent.changed == false
- - update_network_idempotent.data is defined
-
- - name: Create administrator with invalid network
- meraki_admin:
- auth_key: '{{auth_key}}'
- state: present
- org_name: '{{test_org_name}}'
- name: John Doe
- email: '{{email_prefix}}+John@{{email_domain}}'
- orgAccess: none
- networks:
- - { "network": "readnet", "access": "read-only" }
- delegate_to: localhost
- register: create_network_invalid
- ignore_errors: yes
-
- - assert:
- that:
- - '"No network found with the name" in create_network_invalid.msg'
- # - '"400" in create_network_invalid.msg'
-
- - name: Query all administrators
- meraki_admin:
- auth_key: '{{auth_key}}'
- state: query
- org_name: '{{test_org_name}}'
- delegate_to: localhost
- register: query_all
-
- - assert:
- that:
- - query_all.data | length == 4
- - query_all.changed == False
-
- - name: Query admin by name
- meraki_admin:
- auth_key: '{{auth_key}}'
- state: query
- org_name: '{{test_org_name}}'
- name: Jane Doe
- delegate_to: localhost
- register: query_name
-
- - name: Query admin by email
- meraki_admin:
- auth_key: '{{auth_key}}'
- state: query
- org_name: '{{test_org_name}}'
- email: '{{email_prefix}}+janedoe@{{email_domain}}'
- delegate_to: localhost
- register: query_email
-
- - assert:
- that:
- - query_name.data.name == "Jane Doe"
- - 'query_email.data.email == "{{email_prefix}}+janedoe@{{email_domain}}"'
-
- always:
- #############################################################################
- # Tear down starts here
- #############################################################################
- - name: Delete administrators
- meraki_admin:
- auth_key: '{{auth_key}}'
- state: absent
- org_name: '{{test_org_name}}'
- email: '{{item}}'
- delegate_to: localhost
- register: delete_all
- ignore_errors: yes
- loop:
- - '{{email_prefix}}+janedoe@{{email_domain}}'
- - '{{email_prefix}}+johndoe@{{email_domain}}'
- - '{{email_prefix}}+jimdoe@{{email_domain}}'
-
- - name: Query all administrators
- meraki_admin:
- auth_key: '{{auth_key}}'
- state: query
- org_name: '{{test_org_name}}'
- delegate_to: localhost
- register: query_all_deleted
-
- - assert:
- that:
- - query_all_deleted.data | length == 1 \ No newline at end of file
diff --git a/test/integration/targets/meraki_config_template/aliases b/test/integration/targets/meraki_config_template/aliases
deleted file mode 100644
index ad7ccf7ada..0000000000
--- a/test/integration/targets/meraki_config_template/aliases
+++ /dev/null
@@ -1 +0,0 @@
-unsupported
diff --git a/test/integration/targets/meraki_config_template/tasks/main.yml b/test/integration/targets/meraki_config_template/tasks/main.yml
deleted file mode 100644
index 12b18d1a28..0000000000
--- a/test/integration/targets/meraki_config_template/tasks/main.yml
+++ /dev/null
@@ -1,196 +0,0 @@
-# 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: Query all configuration templates
- meraki_config_template:
- auth_key: '{{auth_key}}'
- state: query
- org_name: '{{test_org_name}}'
- register: get_all
-
- - name: Delete non-existant configuration template
- meraki_config_template:
- auth_key: '{{auth_key}}'
- state: absent
- org_name: '{{test_org_name}}'
- config_template: FakeConfigTemplate
- register: deleted
- ignore_errors: yes
-
- - assert:
- that:
- - '"No configuration template named" in deleted.msg'
-
- - name: Create a network
- meraki_network:
- auth_key: '{{auth_key}}'
- state: present
- org_name: '{{ test_org_name }}'
- net_name: '{{ test_net_name }}'
- type: appliance
- delegate_to: localhost
- register: net_info
-
- - set_fact:
- 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
- meraki_config_template:
- auth_key: '{{auth_key}}'
- state: present
- org_name: '{{ test_org_name }}'
- net_name: '{{ test_net_name }}'
- config_template: '{{test_template_name}}'
- register: bind
-
- - assert:
- that:
- bind.changed == True
-
- - assert:
- that:
- bind_check is changed
-
- - name: Bind a template to a network when it's already bound
- meraki_config_template:
- auth_key: '{{auth_key}}'
- state: present
- org_name: '{{ test_org_name }}'
- net_name: '{{ test_net_name }}'
- config_template: '{{test_template_name}}'
- register: bind_invalid
- ignore_errors: yes
-
- - assert:
- that:
- - bind_invalid.changed == False
-
- - name: Unbind a template from a network
- meraki_config_template:
- auth_key: '{{auth_key}}'
- state: absent
- org_name: '{{ test_org_name }}'
- net_name: '{{ test_net_name }}'
- config_template: '{{test_template_name}}'
- register: unbind
-
- - assert:
- that:
- unbind.changed == True
-
- - name: Unbind a template from a network when it's not bound
- meraki_config_template:
- auth_key: '{{auth_key}}'
- state: absent
- org_name: '{{ test_org_name }}'
- net_name: '{{ test_net_name }}'
- config_template: '{{test_template_name}}'
- register: unbind_invalid
-
- - assert:
- that:
- unbind_invalid.changed == False
-
- - name: Bind a template to a network via id
- meraki_config_template:
- auth_key: '{{auth_key}}'
- state: present
- org_name: '{{test_org_name}}'
- net_id: '{{net_id}}'
- config_template: '{{test_template_name}}'
- register: bind_id
-
- - assert:
- that:
- bind_id.changed == True
-
- - name: Bind a template to a network via id for idempotency
- meraki_config_template:
- auth_key: '{{auth_key}}'
- state: present
- org_name: '{{test_org_name}}'
- net_id: '{{net_id}}'
- config_template: '{{test_template_name}}'
- register: bind_id_idempotent
-
- - assert:
- that:
- - bind_id_idempotent.changed == False
- - bind_id_idempotent.data is defined
-
- - 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:
- auth_key: '{{auth_key}}'
- state: absent
- org_name: '{{test_org_name}}'
- net_id: '{{net_id}}'
- config_template: '{{test_template_name}}'
- register: unbind_id
-
- - assert:
- that:
- 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:
- - name: Delete network
- meraki_network:
- auth_key: '{{auth_key}}'
- state: absent
- org_name: '{{ test_org_name }}'
- net_name: '{{ test_net_name }}'
- delegate_to: localhost
diff --git a/test/integration/targets/meraki_content_filtering/aliases b/test/integration/targets/meraki_content_filtering/aliases
deleted file mode 100644
index ad7ccf7ada..0000000000
--- a/test/integration/targets/meraki_content_filtering/aliases
+++ /dev/null
@@ -1 +0,0 @@
-unsupported
diff --git a/test/integration/targets/meraki_content_filtering/meraki_config_template/aliases b/test/integration/targets/meraki_content_filtering/meraki_config_template/aliases
deleted file mode 100644
index ad7ccf7ada..0000000000
--- a/test/integration/targets/meraki_content_filtering/meraki_config_template/aliases
+++ /dev/null
@@ -1 +0,0 @@
-unsupported
diff --git a/test/integration/targets/meraki_content_filtering/meraki_config_template/tasks/main.yml b/test/integration/targets/meraki_content_filtering/meraki_config_template/tasks/main.yml
deleted file mode 100644
index 4bec7d21de..0000000000
--- a/test/integration/targets/meraki_content_filtering/meraki_config_template/tasks/main.yml
+++ /dev/null
@@ -1,117 +0,0 @@
-# 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: Use an invalid domain
- meraki_config_template:
- auth_key: '{{ auth_key }}'
- host: marrrraki.com
- state: query
- org_name: DevTestOrg
- output_level: debug
- delegate_to: localhost
- register: invalid_domain
- ignore_errors: yes
-
- - name: Connection assertions
- assert:
- that:
- - '"Failed to connect to" in invalid_domain.msg'
-
- - name: Query all configuration templates
- meraki_config_template:
- auth_key: '{{auth_key}}'
- state: query
- org_name: DevTestOrg
- register: get_all
-
- - name: Delete non-existant configuration template
- meraki_config_template:
- auth_key: '{{auth_key}}'
- state: absent
- org_name: DevTestOrg
- config_template: DevConfigTemplateInvalid
- register: deleted
- ignore_errors: yes
-
- - assert:
- that:
- - '"No configuration template named" in deleted.msg'
-
- - name: Create a network
- meraki_network:
- auth_key: '{{auth_key}}'
- state: present
- org_name: '{{ test_org_name }}'
- net_name: '{{ test_net_name }}'
- type: appliance
- delegate_to: localhost
-
- - name: Bind a template to a network
- meraki_config_template:
- auth_key: '{{auth_key}}'
- state: present
- org_name: '{{ test_org_name }}'
- net_name: '{{ test_net_name }}'
- config_template: DevConfigTemplate
- register: bind
-
- - assert:
- that:
- bind.changed == True
-
- - name: Bind a template to a network when it's already bound
- meraki_config_template:
- auth_key: '{{auth_key}}'
- state: present
- org_name: '{{ test_org_name }}'
- net_name: '{{ test_net_name }}'
- config_template: DevConfigTemplate
- register: bind_invalid
- ignore_errors: yes
-
- - assert:
- that:
- - bind_invalid.changed == False
-
- - name: Unbind a template from a network
- meraki_config_template:
- auth_key: '{{auth_key}}'
- state: absent
- org_name: '{{ test_org_name }}'
- net_name: '{{ test_net_name }}'
- config_template: DevConfigTemplate
- register: unbind
-
- - assert:
- that:
- unbind.changed == True
-
- - name: Unbind a template from a network when it's not bound
- meraki_config_template:
- auth_key: '{{auth_key}}'
- state: absent
- org_name: '{{ test_org_name }}'
- net_name: '{{ test_net_name }}'
- config_template: DevConfigTemplate
- register: unbind_invalid
-
- - assert:
- that:
- unbind_invalid.changed == False
-
- always:
- - name: Delete network
- meraki_network:
- auth_key: '{{auth_key}}'
- state: absent
- org_name: '{{ test_org_name }}'
- net_name: '{{ test_net_name }}'
- delegate_to: localhost \ No newline at end of file
diff --git a/test/integration/targets/meraki_content_filtering/tasks/main.yml b/test/integration/targets/meraki_content_filtering/tasks/main.yml
deleted file mode 100644
index 92cf19d2ad..0000000000
--- a/test/integration/targets/meraki_content_filtering/tasks/main.yml
+++ /dev/null
@@ -1,247 +0,0 @@
-# Test code for the Meraki Content Filteringmodule
-# Copyright: (c) 2019, 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 network
- meraki_network:
- auth_key: '{{ auth_key }}'
- state: present
- org_name: '{{test_org_name}}'
- net_name: '{{test_net_name}}'
- type: appliance
- timezone: America/Chicago
- delegate_to: localhost
- register: create_net_appliance
-
- - name: Test net_name and id exclusivity
- meraki_content_filtering:
- auth_key: '{{auth_key}}'
- org_name: '{{test_org_name}}'
- net_name: '{{test_net_name}}'
- net_id: 12345
- state: present
- allowed_urls:
- - "http://www.ansible.com/*"
- register: net_exclusive
- ignore_errors: yes
-
- - assert:
- that:
- - 'net_exclusive.msg == "net_name and net_id are mutually exclusive"'
-
- - name: Set single allowed URL pattern with check mode
- meraki_content_filtering:
- auth_key: '{{auth_key}}'
- org_name: '{{test_org_name}}'
- net_name: '{{test_net_name}}'
- state: present
- allowed_urls:
- - "http://www.ansible.com/*"
- register: single_allowed_check
- check_mode: yes
-
- - assert:
- that:
- - single_allowed_check.data.allowed_url_patterns | length == 1
- - single_allowed_check is changed
-
- - name: Set single allowed URL pattern
- meraki_content_filtering:
- auth_key: '{{auth_key}}'
- org_name: '{{test_org_name}}'
- net_name: '{{test_net_name}}'
- state: present
- allowed_urls:
- - "http://www.ansible.com/*"
- register: single_allowed
-
- - assert:
- that:
- - single_allowed.data.allowed_url_patterns | length == 1
-
- - name: Set single allowed URL pattern for idempotency with check mode
- meraki_content_filtering:
- auth_key: '{{auth_key}}'
- org_name: '{{test_org_name}}'
- net_name: '{{test_net_name}}'
- state: present
- allowed_urls:
- - "http://www.ansible.com/*"
- register: single_allowed_idempotent_check
- check_mode: yes
-
- - debug:
- var: single_allowed_idempotent_check
-
- - assert:
- that:
- - single_allowed_idempotent_check is not changed
- - single_allowed.data.allowed_url_patterns | length == 1
-
- - name: Set single allowed URL pattern for idempotency
- meraki_content_filtering:
- auth_key: '{{auth_key}}'
- org_name: '{{test_org_name}}'
- net_name: '{{test_net_name}}'
- state: present
- allowed_urls:
- - "http://www.ansible.com/*"
- register: single_allowed_idempotent
-
- - debug:
- var: single_allowed_idempotent
-
- - assert:
- that:
- - single_allowed_idempotent.changed == False
- - single_allowed_idempotent.data is defined
-
- - name: Set single blocked URL pattern
- meraki_content_filtering:
- auth_key: '{{auth_key}}'
- org_name: '{{test_org_name}}'
- net_name: '{{test_net_name}}'
- state: present
- blocked_urls:
- - "http://www.ansible.com/*"
- register: single_blocked
-
- - debug:
- var: single_blocked
-
- - assert:
- that:
- - single_blocked.data.blocked_url_patterns | length == 1
-
- - name: Set two allowed URL pattern
- meraki_content_filtering:
- auth_key: '{{auth_key}}'
- org_name: '{{test_org_name}}'
- net_name: '{{test_net_name}}'
- state: present
- allowed_urls:
- - "http://www.ansible.com/*"
- - "http://www.redhat.com"
- register: two_allowed
-
- - debug:
- var: two_allowed
-
- - assert:
- that:
- - two_allowed.changed == True
- - two_allowed.data.allowed_url_patterns | length == 2
-
- - name: Set blocked URL category
- meraki_content_filtering:
- auth_key: '{{auth_key}}'
- org_name: '{{test_org_name}}'
- net_name: '{{test_net_name}}'
- state: present
- category_list_size: full list
- blocked_categories:
- - "Adult and Pornography"
- register: blocked_category
-
- - debug:
- var: blocked_category
-
- - assert:
- that:
- - blocked_category.changed == True
- - blocked_category.data.blocked_url_categories | length == 1
- - blocked_category.data.url_category_list_size == "fullList"
-
- - name: Set blocked URL category with top sites
- meraki_content_filtering:
- auth_key: '{{auth_key}}'
- org_name: '{{test_org_name}}'
- net_name: '{{test_net_name}}'
- state: present
- category_list_size: top sites
- blocked_categories:
- - "Adult and Pornography"
- register: blocked_category
-
- - debug:
- var: blocked_category
-
- - assert:
- that:
- - blocked_category.changed == True
- - blocked_category.data.blocked_url_categories | length == 1
- - blocked_category.data.url_category_list_size == "topSites"
-
- - name: Query all content filtering information
- meraki_content_filtering:
- auth_key: '{{auth_key}}'
- org_name: '{{test_org_name}}'
- net_name: '{{test_net_name}}'
- state: query
- delegate_to: localhost
- register: query_all
-
- - debug:
- var: query_all
-
- - name: Query all content filtering assertion
- assert:
- that:
- - query_all.data.categories is defined
- - query_all.data.policy is defined
-
- - name: Query categories
- meraki_content_filtering:
- auth_key: '{{auth_key}}'
- org_name: '{{test_org_name}}'
- net_name: '{{test_net_name}}'
- state: query
- subset: categories
- delegate_to: localhost
- register: query_categories
-
- - debug:
- var: query_categories
-
- - name: Query categories assertion
- assert:
- that:
- - query_categories.data is defined
-
- - name: Query content filtering policies
- meraki_content_filtering:
- auth_key: '{{auth_key}}'
- org_name: '{{test_org_name}}'
- net_name: '{{test_net_name}}'
- subset: policy
- state: query
- delegate_to: localhost
- register: query_policy
-
- - debug:
- var: query_policy
-
- - name: Query contnet filtering policy assertion
- assert:
- that:
- - query_policy.data is defined
-
- always:
- - name: Reset policies
- meraki_content_filtering:
- auth_key: '{{auth_key}}'
- org_name: '{{test_org_name}}'
- net_name: '{{test_net_name}}'
- state: present
- category_list_size: full list
- allowed_urls:
- -
- blocked_urls:
- -
diff --git a/test/integration/targets/meraki_device/aliases b/test/integration/targets/meraki_device/aliases
deleted file mode 100644
index 89aea537d1..0000000000
--- a/test/integration/targets/meraki_device/aliases
+++ /dev/null
@@ -1 +0,0 @@
-unsupported \ No newline at end of file
diff --git a/test/integration/targets/meraki_device/tasks/main.yml b/test/integration/targets/meraki_device/tasks/main.yml
deleted file mode 100644
index e0a973ab9b..0000000000
--- a/test/integration/targets/meraki_device/tasks/main.yml
+++ /dev/null
@@ -1,215 +0,0 @@
----
-- block:
- # This is commented out because a device cannot be unclaimed via API
- # - name: Claim a device into an organization
- # meraki_device:
- # auth_key: '{{auth_key}}'
- # org_name: '{{test_org_name}}'
- # serial: '{{serial}}'
- # state: present
- # delegate_to: localhost
- # register: claim_device_org
-
- # - assert:
- # that:
- # - claim_device_org.changed == true
-
- - name: Query status of all devices in an organization
- meraki_device:
- auth_key: '{{auth_key}}'
- org_name: '{{test_org_name}}'
- state: query
- delegate_to: localhost
- register: query_device_org
-
- - debug:
- msg: '{{query_device_org}}'
-
- - name: Claim a device into a network
- meraki_device:
- auth_key: '{{auth_key}}'
- org_name: '{{test_org_name}}'
- net_name: '{{test_net_name}}'
- serial: '{{serial}}'
- state: present
- delegate_to: localhost
- register: claim_device
-
- - debug:
- msg: '{{claim_device}}'
-
- - assert:
- that:
- - claim_device.changed == true
-
- - name: Query all devices in one network by network ID
- meraki_device:
- auth_key: '{{auth_key}}'
- org_name: '{{test_org_name}}'
- net_id: '{{test_net_id}}'
- state: query
- delegate_to: localhost
- register: query_one_net_id
-
- - debug:
- msg: '{{query_one_net_id}}'
-
- - name: Query all devices in one network
- meraki_device:
- auth_key: '{{auth_key}}'
- org_name: '{{test_org_name}}'
- net_name: '{{test_net_name}}'
- state: query
- delegate_to: localhost
- register: query_one_net
-
- - debug:
- msg: '{{query_one_net}}'
-
- - name: Query device by serial
- meraki_device:
- auth_key: '{{auth_key}}'
- org_name: '{{test_org_name}}'
- serial: '{{serial}}'
- state: query
- delegate_to: localhost
- register: query_serial_no_net
-
- - debug:
- msg: '{{query_serial_no_net}}'
-
- - name: Query device by serial
- meraki_device:
- auth_key: '{{auth_key}}'
- org_name: '{{test_org_name}}'
- net_name: '{{test_net_name}}'
- serial: '{{serial}}'
- state: query
- delegate_to: localhost
- register: query_serial
-
- - debug:
- msg: '{{query_serial}}'
-
- - assert:
- that:
- - query_serial.changed == False
-
- - name: Query uplink information for a device
- meraki_device:
- auth_key: '{{auth_key}}'
- org_name: '{{test_org_name}}'
- net_name: '{{test_net_name}}'
- serial_uplink: '{{serial}}'
- state: query
- delegate_to: localhost
- register: query_serial_uplink
-
- - debug:
- msg: '{{query_serial_uplink}}'
-
- - name: Query LLDP/CDP information about a device
- meraki_device:
- auth_key: '{{auth_key}}'
- org_name: '{{test_org_name}}'
- net_name: '{{test_net_name}}'
- serial_lldp_cdp: '{{serial}}'
- lldp_cdp_timespan: 6000
- state: query
- delegate_to: localhost
- register: query_serial_lldp_cdp
-
- - debug:
- msg: '{{query_serial_lldp_cdp}}'
-
- - name: Query a device by hostname
- meraki_device:
- auth_key: '{{auth_key}}'
- org_name: '{{test_org_name}}'
- net_name: '{{test_net_name}}'
- hostname: test-hostname
- state: query
- delegate_to: localhost
- register: query_hostname
-
- - debug:
- msg: '{{query_hostname}}'
-
- - name: Query a device by model
- meraki_device:
- auth_key: '{{auth_key}}'
- org_name: '{{test_org_name}}'
- net_name: '{{test_net_name}}'
- model: MR26
- state: query
- delegate_to: localhost
- register: query_model
-
- - debug:
- msg: '{{query_model}}'
-
- - name: Update a device
- meraki_device:
- auth_key: '{{auth_key}}'
- org_name: '{{test_org_name}}'
- net_name: '{{test_net_name}}'
- serial: '{{serial}}'
- name: mr26
- address: 1060 W. Addison St., Chicago, IL
- lat: 41.948038
- lng: -87.65568
- tags: recently-added
- state: present
- move_map_marker: True
- note: Test device notes
- delegate_to: localhost
- register: update_device
-
- - assert:
- that:
- - update_device.changed == true
- - update_device.data.0.notes == "Test device notes"
- - '"1060 W. Addison St., Chicago, IL" in update_device.data.0.address'
-
- - name: Update a device with idempotency
- meraki_device:
- auth_key: '{{auth_key}}'
- org_name: '{{test_org_name}}'
- net_name: '{{test_net_name}}'
- serial: '{{serial}}'
- name: mr26
- address: 1060 W. Addison St., Chicago, IL
- lat: 41.948038
- lng: -87.65568
- tags: recently-added
- state: present
- move_map_marker: True
- note: Test device notes
- delegate_to: localhost
- register: update_device_idempotent
-
- - debug:
- msg: '{{update_device_idempotent}}'
-
- - assert:
- that:
- - update_device_idempotent.changed == False
- - update_device_idempotent.data is defined
-
- always:
- - name: Remove a device from a network
- meraki_device:
- auth_key: '{{auth_key}}'
- org_name: '{{test_org_name}}'
- net_name: '{{test_net_name}}'
- serial: '{{serial}}'
- state: absent
- delegate_to: localhost
- register: delete_device
-
- - debug:
- msg: '{{delete_device}}'
-
- - assert:
- that:
- - delete_device.changed == true \ No newline at end of file
diff --git a/test/integration/targets/meraki_firewalled_services/aliases b/test/integration/targets/meraki_firewalled_services/aliases
deleted file mode 100644
index ad7ccf7ada..0000000000
--- a/test/integration/targets/meraki_firewalled_services/aliases
+++ /dev/null
@@ -1 +0,0 @@
-unsupported
diff --git a/test/integration/targets/meraki_firewalled_services/tasks/main.yml b/test/integration/targets/meraki_firewalled_services/tasks/main.yml
deleted file mode 100644
index 60aa04a963..0000000000
--- a/test/integration/targets/meraki_firewalled_services/tasks/main.yml
+++ /dev/null
@@ -1,7 +0,0 @@
-# Test code for the Meraki Firewalled Services 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: Run test cases
- include: tests.yml ansible_connection=local
diff --git a/test/integration/targets/meraki_firewalled_services/tasks/tests.yml b/test/integration/targets/meraki_firewalled_services/tasks/tests.yml
deleted file mode 100644
index ec23edf221..0000000000
--- a/test/integration/targets/meraki_firewalled_services/tasks/tests.yml
+++ /dev/null
@@ -1,196 +0,0 @@
-# Test code for the Meraki modules
-# Copyright: (c) 2019, Kevin Breit (@kbreit)
-
-# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
----
-- block:
- - name: Create network
- meraki_network:
- auth_key: '{{ auth_key }}'
- state: present
- org_name: '{{test_org_name}}'
- net_name: IntTestNetworkAppliance
- type: appliance
- register: create
-
- - set_fact:
- net_id: create.data.id
-
- - name: Set icmp service to blocked with check mode
- meraki_firewalled_services:
- auth_key: '{{ auth_key }}'
- state: present
- org_name: '{{test_org_name}}'
- net_name: IntTestNetworkAppliance
- service: ICMP
- access: blocked
- register: icmp_blocked_check
- check_mode: yes
-
- - debug:
- var: icmp_blocked_check
-
- - assert:
- that:
- - icmp_blocked_check.data is defined
- - icmp_blocked_check is changed
-
- - name: Set icmp service to blocked
- meraki_firewalled_services:
- auth_key: '{{ auth_key }}'
- state: present
- org_name: '{{test_org_name}}'
- net_name: IntTestNetworkAppliance
- service: ICMP
- access: blocked
- register: icmp_blocked
-
- - debug:
- var: icmp_blocked
-
- - assert:
- that:
- - icmp_blocked.data is defined
- - icmp_blocked is changed
-
- - name: Set icmp service to blocked with idempotency
- meraki_firewalled_services:
- auth_key: '{{ auth_key }}'
- state: present
- org_name: '{{test_org_name}}'
- net_name: IntTestNetworkAppliance
- service: ICMP
- access: blocked
- register: icmp_blocked_idempotent
-
- - debug:
- var: icmp_blocked_idempotent
-
- - assert:
- that:
- - icmp_blocked_idempotent.data is defined
- - icmp_blocked_idempotent is not changed
-
- - name: Set icmp service to restricted with check mode
- meraki_firewalled_services:
- auth_key: '{{ auth_key }}'
- state: present
- org_name: '{{test_org_name}}'
- net_name: IntTestNetworkAppliance
- service: web
- access: restricted
- allowed_ips:
- - 192.0.1.1
- - 192.0.1.2
- check_mode: yes
- register: web_restricted_check
-
- - debug:
- var: web_restricted_check
-
- - assert:
- that:
- - web_restricted_check.data is defined
- - web_restricted_check is changed
-
- - name: Set icmp service to restricted
- meraki_firewalled_services:
- auth_key: '{{ auth_key }}'
- state: present
- org_name: '{{test_org_name}}'
- net_name: IntTestNetworkAppliance
- service: web
- access: restricted
- allowed_ips:
- - 192.0.1.1
- - 192.0.1.2
- register: web_restricted
-
- - debug:
- var: web_restricted
-
- - assert:
- that:
- - web_restricted.data is defined
- - web_restricted is changed
-
- - name: Set icmp service to restricted with idempotency
- meraki_firewalled_services:
- auth_key: '{{ auth_key }}'
- state: present
- org_name: '{{test_org_name}}'
- net_name: IntTestNetworkAppliance
- service: web
- access: restricted
- allowed_ips:
- - 192.0.1.1
- - 192.0.1.2
- register: web_restricted_idempotent
-
- - debug:
- var: web_restricted_idempotent
-
- - assert:
- that:
- - web_restricted_idempotent.data is defined
- - web_restricted_idempotent is not changed
-
- - name: Test error for access restricted and allowed_ips
- meraki_firewalled_services:
- auth_key: '{{ auth_key }}'
- state: present
- org_name: '{{test_org_name}}'
- net_name: IntTestNetworkAppliance
- service: web
- access: unrestricted
- allowed_ips:
- - 192.0.1.1
- - 192.0.1.2
- register: access_error
- ignore_errors: yes
-
- - assert:
- that:
- - 'access_error.msg == "allowed_ips is only allowed when access is restricted."'
-
- - name: Query appliance services
- meraki_firewalled_services:
- auth_key: '{{ auth_key }}'
- state: query
- org_name: '{{test_org_name}}'
- net_name: IntTestNetworkAppliance
- register: query_appliance
-
- - debug:
- var: query_appliance
-
- - assert:
- that:
- - query_appliance.data is defined
-
- - name: Query services
- meraki_firewalled_services:
- auth_key: '{{ auth_key }}'
- state: query
- org_name: '{{test_org_name}}'
- net_name: IntTestNetworkAppliance
- service: ICMP
- register: query_service
-
- - debug:
- var: query_service
-
- - assert:
- that:
- - query_service.data is defined
-
-#############################################################################
-# Tear down starts here
-#############################################################################
- always:
- - name: Delete all networks
- meraki_network:
- auth_key: '{{ auth_key }}'
- state: absent
- org_name: '{{test_org_name}}'
- net_name: IntTestNetworkAppliance
diff --git a/test/integration/targets/meraki_malware/aliases b/test/integration/targets/meraki_malware/aliases
deleted file mode 100644
index ad7ccf7ada..0000000000
--- a/test/integration/targets/meraki_malware/aliases
+++ /dev/null
@@ -1 +0,0 @@
-unsupported
diff --git a/test/integration/targets/meraki_malware/tasks/main.yml b/test/integration/targets/meraki_malware/tasks/main.yml
deleted file mode 100644
index b387479deb..0000000000
--- a/test/integration/targets/meraki_malware/tasks/main.yml
+++ /dev/null
@@ -1,247 +0,0 @@
-# Test code for the Meraki VLAN 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 test network
- meraki_network:
- auth_key: '{{auth_key}}'
- state: present
- org_name: '{{test_org_name}}'
- net_name: '{{test_net_name}} - Malware'
- type: appliance
- delegate_to: localhost
- register: net
-
- - set_fact:
- net_id: '{{net.data.id}}'
-
- - name: Enable malware protection with check mode
- meraki_malware:
- auth_key: '{{auth_key}}'
- state: present
- org_name: '{{test_org_name}}'
- net_name: '{{test_net_name}} - Malware'
- mode: enabled
- delegate_to: localhost
- check_mode: yes
- register: get_malware_check
-
- - assert:
- that:
- - get_malware_check is changed
- - get_malware_check.data is defined
-
- - name: Enable malware protection
- meraki_malware:
- auth_key: '{{auth_key}}'
- state: present
- org_name: '{{test_org_name}}'
- net_name: '{{test_net_name}} - Malware'
- mode: enabled
- delegate_to: localhost
- register: get_malware
-
- - debug:
- var: get_malware
-
- - assert:
- that:
- - get_malware is changed
- - get_malware.data.mode is defined
-
- - name: Enable malware protection with idempotency
- meraki_malware:
- auth_key: '{{auth_key}}'
- state: present
- org_name: '{{test_org_name}}'
- net_name: '{{test_net_name}} - Malware'
- mode: enabled
- delegate_to: localhost
- register: get_malware_idempotent
-
- - debug:
- var: get_malware_idempotent
-
- - assert:
- that:
- - get_malware_idempotent is not changed
- - get_malware_idempotent.data is defined
-
- - name: Test error when mode is not set
- meraki_malware:
- auth_key: '{{auth_key}}'
- state: present
- org_name: '{{test_org_name}}'
- net_name: '{{test_net_name}} - Malware'
- allowed_files:
- - sha256: e82c5f7d75004727e1f3b94426b9a11c8bc4c312a9170ac9a73abace40aef503
- comment: random zip
- delegate_to: localhost
- register: test_mode_err
- ignore_errors: yes
-
- - assert:
- that:
- - test_mode_err.msg == "mode must be set when allowed_files or allowed_urls is set."
-
- - name: Set whitelisted file with check mode
- meraki_malware:
- auth_key: '{{auth_key}}'
- state: present
- org_name: '{{test_org_name}}'
- net_name: '{{test_net_name}} - Malware'
- mode: enabled
- allowed_files:
- - sha256: e82c5f7d75004727e1f3b94426b9a11c8bc4c312a9170ac9a73abace40aef503
- comment: random zip
- delegate_to: localhost
- check_mode: yes
- register: set_file_check
-
- - debug:
- var:
- set_file_check
-
- - assert:
- that:
- - set_file_check is changed
- - set_file_check.data is defined
-
- - name: Set whitelisted file
- meraki_malware:
- auth_key: '{{auth_key}}'
- state: present
- org_name: '{{test_org_name}}'
- net_id: '{{net_id}}'
- mode: enabled
- allowed_files:
- - sha256: e82c5f7d75004727e1f3b94426b9a11c8bc4c312a9170ac9a73abace40aef503
- comment: random zip
- delegate_to: localhost
- register: set_file
-
- - debug:
- var: set_file
-
- - assert:
- that:
- - set_file is changed
- - set_file.data.mode is defined
-
- - name: Set whitelisted file with idempotency
- meraki_malware:
- auth_key: '{{auth_key}}'
- state: present
- org_name: '{{test_org_name}}'
- net_name: '{{test_net_name}} - Malware'
- mode: enabled
- allowed_files:
- - sha256: e82c5f7d75004727e1f3b94426b9a11c8bc4c312a9170ac9a73abace40aef503
- comment: random zip
- delegate_to: localhost
- register: set_file_idempotent
-
- - debug:
- var: set_file_idempotent
-
- - assert:
- that:
- - set_file_idempotent is not changed
- - set_file_idempotent.data is defined
-
- - name: Set whitelisted url with check mode
- meraki_malware:
- auth_key: '{{auth_key}}'
- state: present
- org_name: '{{test_org_name}}'
- net_name: '{{test_net_name}} - Malware'
- mode: enabled
- allowed_urls:
- - url: www.google.com
- comment: Google
- delegate_to: localhost
- check_mode: yes
- register: set_url_check
-
- - debug:
- var:
- set_url_check
-
- - assert:
- that:
- - set_url_check is changed
- - set_url_check.data is defined
-
- - name: Set whitelisted url
- meraki_malware:
- auth_key: '{{auth_key}}'
- state: present
- org_name: '{{test_org_name}}'
- net_name: '{{test_net_name}} - Malware'
- mode: enabled
- allowed_urls:
- - url: www.google.com
- comment: Google
- delegate_to: localhost
- register: set_url
-
- - debug:
- var: set_url
-
- - assert:
- that:
- - set_url is changed
- - set_url.data.mode is defined
-
- - name: Set whitelisted url with idempotency
- meraki_malware:
- auth_key: '{{auth_key}}'
- state: present
- org_name: '{{test_org_name}}'
- net_name: '{{test_net_name}} - Malware'
- mode: enabled
- allowed_urls:
- - url: www.google.com
- comment: Google
- delegate_to: localhost
- register: set_url_idempotent
-
- - debug:
- var: set_url_idempotent
-
- - assert:
- that:
- - set_url_idempotent is not changed
- - set_url_idempotent.data is defined
-
- - name: Get malware settings
- meraki_malware:
- auth_key: '{{auth_key}}'
- state: query
- org_name: '{{test_org_name}}'
- net_name: '{{test_net_name}} - Malware'
- delegate_to: localhost
- register: get_malware
-
- - assert:
- that:
- - get_malware.data is defined
-
- #############################################################################
- # Tear down starts here
- #############################################################################
- always:
- - name: Delete test network
- meraki_network:
- auth_key: '{{auth_key}}'
- state: absent
- org_name: '{{test_org_name}}'
- net_name: '{{test_net_name}} - Malware'
- delegate_to: localhost
diff --git a/test/integration/targets/meraki_mr_l3_firewall/aliases b/test/integration/targets/meraki_mr_l3_firewall/aliases
deleted file mode 100644
index ad7ccf7ada..0000000000
--- a/test/integration/targets/meraki_mr_l3_firewall/aliases
+++ /dev/null
@@ -1 +0,0 @@
-unsupported
diff --git a/test/integration/targets/meraki_mr_l3_firewall/tasks/main.yml b/test/integration/targets/meraki_mr_l3_firewall/tasks/main.yml
deleted file mode 100644
index 75a110b285..0000000000
--- a/test/integration/targets/meraki_mr_l3_firewall/tasks/main.yml
+++ /dev/null
@@ -1,100 +0,0 @@
-# Test code for the Meraki modules
-# 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: Create wireless network
- meraki_network:
- auth_key: '{{ auth_key }}'
- state: present
- org_name: '{{test_org_name}}'
- net_name: TestNetWireless
- type: wireless
- delegate_to: localhost
- register: new_net
-
- - set_fact:
- net: '{{new_net.data.id}}'
-
- - name: Create single firewall rule
- meraki_mr_l3_firewall:
- auth_key: '{{ auth_key }}'
- state: present
- org_name: '{{test_org_name}}'
- net_id: '{{net}}'
- number: 1
- rules:
- - comment: Integration test rule
- policy: allow
- protocol: tcp
- dest_port: 80
- dest_cidr: 192.0.2.0/24
- allow_lan_access: no
- delegate_to: localhost
- register: create_one
-
- - debug:
- msg: '{{create_one}}'
-
- - assert:
- that:
- - create_one.data.0.comment == 'Integration test rule'
- - create_one.data.1.policy == 'deny'
- - create_one.data is defined
-
- - name: Enable local LAN access
- meraki_mr_l3_firewall:
- auth_key: '{{ auth_key }}'
- state: present
- org_name: '{{test_org_name}}'
- net_id: '{{net}}'
- number: 1
- rules:
- allow_lan_access: yes
- delegate_to: localhost
- register: enable_lan
-
- - assert:
- that:
- - enable_lan.data.1.policy == 'allow'
-
- - name: Query firewall rules
- meraki_mr_l3_firewall:
- auth_key: '{{ auth_key }}'
- state: query
- org_name: '{{test_org_name}}'
- net_id: '{{net}}'
- number: 1
- delegate_to: localhost
- register: query
-
- - debug:
- msg: '{{query}}'
-
- - assert:
- that:
- - query.data.1.comment == 'Wireless clients accessing LAN'
- - query.data.2.comment == 'Default rule'
- - query.changed == False
-
-############################################################################
-# Tear down starts here
-############################################################################
- always:
- - name: Delete wireless SSID
- meraki_ssid:
- auth_key: '{{ auth_key }}'
- state: absent
- org_name: '{{test_org_name}}'
- net_id: '{{net}}'
- number: 1
- delegate_to: localhost
-
- - name: Delete wireless network
- meraki_network:
- auth_key: '{{ auth_key }}'
- state: absent
- org_name: '{{test_org_name}}'
- net_id: '{{net}}'
- delegate_to: localhost
diff --git a/test/integration/targets/meraki_mx_l3_firewall/aliases b/test/integration/targets/meraki_mx_l3_firewall/aliases
deleted file mode 100644
index ad7ccf7ada..0000000000
--- a/test/integration/targets/meraki_mx_l3_firewall/aliases
+++ /dev/null
@@ -1 +0,0 @@
-unsupported
diff --git a/test/integration/targets/meraki_mx_l3_firewall/tasks/main.yml b/test/integration/targets/meraki_mx_l3_firewall/tasks/main.yml
deleted file mode 100644
index cc70f9788c..0000000000
--- a/test/integration/targets/meraki_mx_l3_firewall/tasks/main.yml
+++ /dev/null
@@ -1,203 +0,0 @@
-# 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 network
- meraki_network:
- auth_key: '{{ auth_key }}'
- org_name: '{{test_org_name}}'
- net_name: TestNetAppliance
- state: present
- type: appliance
- delegate_to: localhost
-
- - name: Query firewall rules
- meraki_mx_l3_firewall:
- auth_key: '{{ auth_key }}'
- org_name: '{{test_org_name}}'
- net_name: TestNetAppliance
- state: query
- delegate_to: localhost
- register: query
-
- - assert:
- that:
- - query.data|length == 1
-
- - name: Set one firewall rule
- meraki_mx_l3_firewall:
- auth_key: '{{ auth_key }}'
- org_name: '{{test_org_name}}'
- net_name: TestNetAppliance
- state: present
- rules:
- - comment: Deny to documentation address
- src_port: any
- src_cidr: any
- dest_port: 80,443
- dest_cidr: 192.0.1.1/32
- protocol: tcp
- policy: deny
- delegate_to: localhost
- register: create_one
-
- - debug:
- var: create_one
-
- - assert:
- that:
- - create_one.data|length == 2
- - create_one.data.0.dest_cidr == '192.0.1.1/32'
- - create_one.data.0.protocol == 'tcp'
- - create_one.data.0.policy == 'deny'
- - create_one.changed == True
- - create_one.data is defined
-
- - name: Check for idempotency
- meraki_mx_l3_firewall:
- auth_key: '{{ auth_key }}'
- org_name: '{{test_org_name}}'
- net_name: TestNetAppliance
- state: present
- rules:
- - comment: Deny to documentation address
- src_port: any
- src_cidr: any
- dest_port: 80,443
- dest_cidr: 192.0.1.1/32
- protocol: tcp
- policy: deny
- delegate_to: localhost
- register: create_one_idempotent
-
- - debug:
- msg: '{{create_one_idempotent}}'
-
- - assert:
- that:
- - create_one_idempotent.changed == False
- - create_one_idempotent.data is defined
-
- - name: Create syslog in network
- meraki_syslog:
- auth_key: '{{ auth_key }}'
- org_name: '{{test_org_name}}'
- net_name: TestNetAppliance
- state: present
- servers:
- - host: 192.0.2.10
- port: 514
- roles:
- - Appliance event log
- - Flows
- delegate_to: localhost
-
- - name: Enable syslog for default rule
- meraki_mx_l3_firewall:
- auth_key: '{{ auth_key }}'
- org_name: '{{test_org_name}}'
- net_name: TestNetAppliance
- state: present
- rules:
- - comment: Deny to documentation address
- src_port: any
- src_cidr: any
- dest_port: 80,443
- dest_cidr: 192.0.1.1/32
- protocol: tcp
- policy: deny
- syslog_default_rule: yes
- delegate_to: localhost
- register: default_syslog
-
- - debug:
- msg: '{{default_syslog}}'
-
- - assert:
- that:
- - default_syslog.data is defined
-
- - name: Query firewall rules
- meraki_mx_l3_firewall:
- auth_key: '{{ auth_key }}'
- org_name: '{{test_org_name}}'
- net_name: TestNetAppliance
- state: query
- delegate_to: localhost
- register: query
-
- - debug:
- msg: '{{query.data.1}}'
-
- - assert:
- that:
- - query.data.1.syslog_enabled == True
- - default_syslog.changed == True
-
- - name: Disable syslog for default rule
- meraki_mx_l3_firewall:
- auth_key: '{{ auth_key }}'
- org_name: '{{test_org_name}}'
- net_name: TestNetAppliance
- state: present
- rules:
- - comment: Deny to documentation address
- src_port: any
- src_cidr: any
- dest_port: 80,443
- dest_cidr: 192.0.1.1/32
- protocol: tcp
- policy: deny
- syslog_default_rule: no
- delegate_to: localhost
- register: disable_syslog
-
- - debug:
- msg: '{{disable_syslog}}'
-
- - assert:
- that:
- - disable_syslog.data is defined
-
- - name: Query firewall rules
- meraki_mx_l3_firewall:
- auth_key: '{{ auth_key }}'
- org_name: '{{test_org_name}}'
- net_name: TestNetAppliance
- state: query
- delegate_to: localhost
- register: query
-
- - debug:
- msg: '{{query.data.1}}'
-
- - assert:
- that:
- - query.data.1.syslog_enabled == False
- - disable_syslog.changed == True
-
- always:
- - name: Delete all firewall rules
- meraki_mx_l3_firewall:
- auth_key: '{{ auth_key }}'
- org_name: '{{test_org_name}}'
- net_name: TestNetAppliance
- state: present
- rules: []
- delegate_to: localhost
- register: delete_all
-
- - name: Delete network
- meraki_network:
- auth_key: '{{ auth_key }}'
- org_name: '{{test_org_name}}'
- net_name: TestNetAppliance
- state: absent
- delegate_to: localhost
diff --git a/test/integration/targets/meraki_mx_l7_firewall/aliases b/test/integration/targets/meraki_mx_l7_firewall/aliases
deleted file mode 100644
index 06fe32bc66..0000000000
--- a/test/integration/targets/meraki_mx_l7_firewall/aliases
+++ /dev/null
@@ -1,2 +0,0 @@
-unsupported
-
diff --git a/test/integration/targets/meraki_mx_l7_firewall/tasks/main.yml b/test/integration/targets/meraki_mx_l7_firewall/tasks/main.yml
deleted file mode 100644
index bb4c6fc594..0000000000
--- a/test/integration/targets/meraki_mx_l7_firewall/tasks/main.yml
+++ /dev/null
@@ -1,7 +0,0 @@
-# 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)
----
-- name: Run test cases
- include: tests.yml ansible_connection=local \ No newline at end of file
diff --git a/test/integration/targets/meraki_mx_l7_firewall/tasks/tests.yml b/test/integration/targets/meraki_mx_l7_firewall/tasks/tests.yml
deleted file mode 100644
index 72adef560e..0000000000
--- a/test/integration/targets/meraki_mx_l7_firewall/tasks/tests.yml
+++ /dev/null
@@ -1,494 +0,0 @@
-# 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 network
- meraki_network:
- auth_key: '{{ auth_key }}'
- org_name: '{{test_org_name}}'
- net_name: TestNetAppliance
- state: present
- type: appliance
-
- - name: Query firewall rules
- meraki_mx_l7_firewall:
- auth_key: '{{ auth_key }}'
- org_name: '{{test_org_name}}'
- net_name: TestNetAppliance
- state: query
- register: query
-
- - debug:
- var: query
-
- - assert:
- that:
- - query.data is defined
-
- - name: Query firewall application categories
- meraki_mx_l7_firewall:
- auth_key: '{{ auth_key }}'
- org_name: '{{test_org_name}}'
- net_name: TestNetAppliance
- state: query
- categories: yes
- register: query_categories
-
- - assert:
- that:
- - query_categories.data is defined
-
- - name: Create firewall rule for IP range in check mode
- meraki_mx_l7_firewall:
- auth_key: '{{ auth_key }}'
- org_name: '{{test_org_name}}'
- net_name: TestNetAppliance
- state: present
- rules:
- - type: ip_range
- ip_range: 10.11.12.0/24
- register: create_ip_range_check
- check_mode: yes
-
- - debug:
- var: create_ip_range_check
-
- - assert:
- that:
- - create_ip_range_check is changed
-
- - name: Create firewall rule for IP range
- meraki_mx_l7_firewall:
- auth_key: '{{ auth_key }}'
- org_name: '{{test_org_name}}'
- net_name: TestNetAppliance
- state: present
- rules:
- - type: ip_range
- ip_range: 10.11.12.0/24
- register: create_ip_range
-
- - debug:
- var: create_ip_range
-
- - assert:
- that:
- - create_ip_range is changed
- - create_ip_range.data.rules | length == 1
-
- - name: Create firewall rule for IP range with idempotency with check mode
- meraki_mx_l7_firewall:
- auth_key: '{{ auth_key }}'
- org_name: '{{test_org_name}}'
- net_name: TestNetAppliance
- state: present
- rules:
- - type: ip_range
- ip_range: 10.11.12.0/24
- register: create_ip_range_idempotent_check
- check_mode: yes
-
- - assert:
- that:
- - create_ip_range_idempotent_check is not changed
-
- - name: Create firewall rule for IP range with idempotency
- meraki_mx_l7_firewall:
- auth_key: '{{ auth_key }}'
- org_name: '{{test_org_name}}'
- net_name: TestNetAppliance
- state: present
- rules:
- - type: ip_range
- ip_range: 10.11.12.0/24
- register: create_ip_range_idempotent
-
- - assert:
- that:
- - create_ip_range_idempotent is not changed
-
- - name: Create firewall rule for IP and port
- meraki_mx_l7_firewall:
- auth_key: '{{ auth_key }}'
- org_name: '{{test_org_name}}'
- net_name: TestNetAppliance
- state: present
- rules:
- - type: ip_range
- ip_range: 10.11.12.1:23
- register: create_ip_range_port
-
- - debug:
- var: create_ip_range_port
-
- - assert:
- that:
- - create_ip_range_port is changed
-
- - name: Create firewall rule for IP range
- meraki_mx_l7_firewall:
- auth_key: '{{ auth_key }}'
- org_name: '{{test_org_name}}'
- net_name: TestNetAppliance
- state: present
- rules:
- - type: ip_range
- ip_range: 10.11.12.0/24
- register: create_ip_range
-
- - debug:
- var: create_ip_range
-
- - assert:
- that:
- - create_ip_range is changed
- - create_ip_range.data.rules | length == 1
-
- - name: Create firewall rule for IP range with idempotency with check mode
- meraki_mx_l7_firewall:
- auth_key: '{{ auth_key }}'
- org_name: '{{test_org_name}}'
- net_name: TestNetAppliance
- state: present
- rules:
- - type: ip_range
- ip_range: 10.11.12.0/24
- register: create_ip_range_idempotent_check
- check_mode: yes
-
- - assert:
- that:
- - create_ip_range_idempotent_check is not changed
-
- - name: Create firewall rule for IP range with idempotency
- meraki_mx_l7_firewall:
- auth_key: '{{ auth_key }}'
- org_name: '{{test_org_name}}'
- net_name: TestNetAppliance
- state: present
- rules:
- - type: ip_range
- ip_range: 10.11.12.0/24
- register: create_ip_range_idempotent
-
- - assert:
- that:
- - create_ip_range_idempotent is not changed
-
- - name: Create firewall rule for application
- meraki_mx_l7_firewall:
- auth_key: '{{ auth_key }}'
- org_name: '{{test_org_name}}'
- net_name: TestNetAppliance
- state: present
- rules:
- - type: application
- application:
- name: facebook
- register: application_rule
-
- - assert:
- that:
- - application_rule is changed
- - application_rule.data.rules is defined
-
- - name: Create firewall rule for application via ID
- meraki_mx_l7_firewall:
- auth_key: '{{ auth_key }}'
- org_name: '{{test_org_name}}'
- net_name: TestNetAppliance
- state: present
- rules:
- - type: application
- application:
- id: meraki:layer7/application/205
- register: application_rule_id
-
- - assert:
- that:
- - application_rule_id is changed
-
- - name: Create firewall rule for invalid application
- meraki_mx_l7_firewall:
- auth_key: '{{ auth_key }}'
- org_name: '{{test_org_name}}'
- net_name: TestNetAppliance
- state: present
- rules:
- - type: application
- application:
- name: ansible
- register: application_rule_invalid
- ignore_errors: yes
-
- - name: Create firewall rule for application category
- meraki_mx_l7_firewall:
- auth_key: '{{ auth_key }}'
- org_name: '{{test_org_name}}'
- net_name: TestNetAppliance
- state: present
- rules:
- - type: application_category
- application:
- name: Advertising
- register: application_category_rule
-
- - debug:
- var: application_category_rule
-
- - assert:
- that:
- - application_category_rule is changed
-
- - name: Create firewall rule for application category with ID and conflict
- meraki_mx_l7_firewall:
- auth_key: '{{ auth_key }}'
- org_name: '{{test_org_name}}'
- net_name: TestNetAppliance
- state: present
- rules:
- - type: application_category
- application:
- id: meraki:layer7/category/27
- register: application_category_rule_id_conflict
-
- - assert:
- that:
- - application_category_rule_id_conflict is not changed
-
- - name: Create firewall rule for application category with ID
- meraki_mx_l7_firewall:
- auth_key: '{{ auth_key }}'
- org_name: '{{test_org_name}}'
- net_name: TestNetAppliance
- state: present
- rules:
- - type: application_category
- application:
- id: meraki:layer7/category/24
- register: application_category_rule_id
-
- - assert:
- that:
- - application_category_rule_id is changed
-
- - name: Create firewall rule for host
- meraki_mx_l7_firewall:
- auth_key: '{{ auth_key }}'
- org_name: '{{test_org_name}}'
- net_name: TestNetAppliance
- state: present
- rules:
- - type: host
- host: asdf.com
- register: host_rule
-
- - assert:
- that:
- - host_rule is changed
-
- - name: Create firewall rule for port
- meraki_mx_l7_firewall:
- auth_key: '{{ auth_key }}'
- org_name: '{{test_org_name}}'
- net_name: TestNetAppliance
- state: present
- rules:
- - type: port
- port: 1234
- register: port_rule
-
- - assert:
- that:
- - port_rule is changed
-
- - name: Create firewall rule for blacklisted countries
- meraki_mx_l7_firewall:
- auth_key: '{{ auth_key }}'
- org_name: '{{test_org_name}}'
- net_name: TestNetAppliance
- state: present
- rules:
- - type: blacklisted_countries
- countries:
- - CA
- - AX
- register: blacklist_countries
-
- - assert:
- that:
- - blacklist_countries is changed
-
- - name: Create firewall rule for whitelisted countries
- meraki_mx_l7_firewall:
- auth_key: '{{ auth_key }}'
- org_name: '{{test_org_name}}'
- net_name: TestNetAppliance
- state: present
- rules:
- - type: whitelisted_countries
- countries:
- - US
- - FR
- register: whitelist_countries
-
- - assert:
- that:
- - whitelist_countries is changed
-
- - name: Create firewall rule for whitelisted countries with idempotency
- meraki_mx_l7_firewall:
- auth_key: '{{ auth_key }}'
- org_name: '{{test_org_name}}'
- net_name: TestNetAppliance
- state: present
- rules:
- - type: whitelisted_countries
- countries:
- - US
- - FR
- register: whitelist_countries_idempotent
-
- - assert:
- that:
- - whitelist_countries_idempotent is not changed
-
- - name: Create multiple firewall rules
- meraki_mx_l7_firewall:
- auth_key: '{{ auth_key }}'
- org_name: '{{test_org_name}}'
- net_name: TestNetAppliance
- state: present
- rules:
- - type: application_category
- application:
- id: meraki:layer7/category/27
- - type: blacklisted_countries
- countries:
- - CN
- - policy: deny
- type: port
- port: 8080
- register: multiple_rules
-
- - debug:
- var: multiple_rules
-
- - assert:
- that:
- - multiple_rules.data.rules | length == 3
- - multiple_rules is changed
-
- #########################################
- ## Tests for argument completeness ##
- #########################################
-
- - name: Test whitelisted_countries incomplete arguments
- meraki_mx_l7_firewall:
- auth_key: '{{ auth_key }}'
- org_name: '{{test_org_name}}'
- net_name: TestNetAppliance
- state: present
- rules:
- - type: whitelisted_countries
- register: error_whitelist
- ignore_errors: yes
-
- - assert:
- that:
- - 'error_whitelist.msg == "countries argument is required when type is whitelisted_countries."'
-
- - name: Test blacklisted_countries incomplete arguments
- meraki_mx_l7_firewall:
- auth_key: '{{ auth_key }}'
- org_name: '{{test_org_name}}'
- net_name: TestNetAppliance
- state: present
- rules:
- - type: blacklisted_countries
- register: error_blacklist
- ignore_errors: yes
-
- - assert:
- that:
- - 'error_blacklist.msg == "countries argument is required when type is blacklisted_countries."'
-
- - name: Test application_category incomplete arguments
- meraki_mx_l7_firewall:
- auth_key: '{{ auth_key }}'
- org_name: '{{test_org_name}}'
- net_name: TestNetAppliance
- state: present
- rules:
- - type: application_category
- register: error_app_cat
- ignore_errors: yes
-
- - assert:
- that:
- - 'error_app_cat.msg == "application argument is required when type is application_category."'
-
- - name: Test application incomplete arguments
- meraki_mx_l7_firewall:
- auth_key: '{{ auth_key }}'
- org_name: '{{test_org_name}}'
- net_name: TestNetAppliance
- state: present
- rules:
- - type: application
- register: error_app_cat
- ignore_errors: yes
-
- - assert:
- that:
- - 'error_app_cat.msg == "application argument is required when type is application."'
-
- - name: Test host incomplete arguments
- meraki_mx_l7_firewall:
- auth_key: '{{ auth_key }}'
- org_name: '{{test_org_name}}'
- net_name: TestNetAppliance
- state: present
- rules:
- - type: host
- register: error_app_cat
- ignore_errors: yes
-
- - assert:
- that:
- - 'error_app_cat.msg == "host argument is required when type is host."'
-
- - name: Test port incomplete arguments
- meraki_mx_l7_firewall:
- auth_key: '{{ auth_key }}'
- org_name: '{{test_org_name}}'
- net_name: TestNetAppliance
- state: present
- rules:
- - type: port
- register: error_app_cat
- ignore_errors: yes
-
- - assert:
- that:
- - 'error_app_cat.msg == "port argument is required when type is port."'
-
- #################
- ## Cleanup ##
- #################
-
- # always:
- # - name: Delete network
- # meraki_network:
- # auth_key: '{{ auth_key }}'
- # org_name: '{{test_org_name}}'
- # net_name: TestNetAppliance
- # state: absent
- # delegate_to: localhost
diff --git a/test/integration/targets/meraki_nat/tasks/main.yml b/test/integration/targets/meraki_nat/tasks/main.yml
deleted file mode 100644
index 721a93007b..0000000000
--- a/test/integration/targets/meraki_nat/tasks/main.yml
+++ /dev/null
@@ -1,7 +0,0 @@
-# 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)
----
-- name: Run test cases
- include: tests.yml ansible_connection=local
diff --git a/test/integration/targets/meraki_nat/tasks/tests.yml b/test/integration/targets/meraki_nat/tasks/tests.yml
deleted file mode 100644
index 11193d135e..0000000000
--- a/test/integration/targets/meraki_nat/tasks/tests.yml
+++ /dev/null
@@ -1,363 +0,0 @@
-# Test code for the Meraki NAT module
-# Copyright: (c) 2019, Kevin Breit (@kbreit)
-
-# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
----
-- block:
- - name: Create test network
- meraki_network:
- auth_key: '{{auth_key}}'
- org_name: '{{test_org_name}}'
- net_name: '{{test_net_name}}'
- state: present
- type: appliance
-
- - name: Create 1:1 rule with check mode
- meraki_nat:
- auth_key: '{{auth_key}}'
- org_name: '{{test_org_name}}'
- net_name: '{{test_net_name}}'
- state: present
- one_to_one:
- - name: Service behind NAT
- public_ip: 1.2.1.2
- lan_ip: 192.168.128.1
- uplink: internet1
- allowed_inbound:
- - protocol: tcp
- destination_ports:
- - 80
- allowed_ips:
- - 10.10.10.10
- register: create_one_one_check
- check_mode: yes
-
- - debug:
- var: create_one_one_check
-
- - assert:
- that:
- - create_one_one_check is changed
-
- - name: Create 1:1 rule
- meraki_nat:
- auth_key: '{{auth_key}}'
- org_name: '{{test_org_name}}'
- net_name: '{{test_net_name}}'
- state: present
- one_to_one:
- - name: Service behind NAT
- public_ip: 1.2.1.2
- lan_ip: 192.168.128.1
- uplink: internet1
- allowed_inbound:
- - protocol: tcp
- destination_ports:
- - 80
- allowed_ips:
- - 10.10.10.10
- register: create_one_one
-
- - debug:
- var: create_one_one
-
- - assert:
- that:
- - create_one_one is changed
-
- - name: Create 1:1 rule with idempotency
- meraki_nat:
- auth_key: '{{auth_key}}'
- org_name: '{{test_org_name}}'
- net_name: '{{test_net_name}}'
- state: present
- one_to_one:
- - name: Service behind NAT
- public_ip: 1.2.1.2
- lan_ip: 192.168.128.1
- uplink: internet1
- allowed_inbound:
- - protocol: tcp
- destination_ports:
- - 80
- allowed_ips:
- - 10.10.10.10
- register: create_one_one_idempotent
-
- - debug:
- var: create_one_one_idempotent
-
- - assert:
- that:
- - create_one_one_idempotent is not changed
-
- - name: Create 1:many rule with check mode
- meraki_nat:
- auth_key: '{{auth_key}}'
- org_name: '{{test_org_name}}'
- net_name: '{{test_net_name}}'
- state: present
- one_to_many:
- - public_ip: 1.1.1.1
- uplink: internet1
- port_rules:
- - name: Test rule
- protocol: tcp
- public_port: 10
- local_ip: 192.168.128.1
- local_port: 11
- allowed_ips:
- - any
- register: create_one_many_check
- check_mode: yes
-
- - debug:
- var: create_one_many_check
-
- - assert:
- that:
- - create_one_many_check is changed
-
- - name: Create 1:many rule
- meraki_nat:
- auth_key: '{{auth_key}}'
- org_name: '{{test_org_name}}'
- net_name: '{{test_net_name}}'
- state: present
- one_to_many:
- - public_ip: 1.1.1.1
- uplink: internet1
- port_rules:
- - name: Test rule
- protocol: tcp
- public_port: 10
- local_ip: 192.168.128.1
- local_port: 11
- allowed_ips:
- - any
- register: create_one_many
-
- - debug:
- var: create_one_many
-
- - assert:
- that:
- - create_one_many is changed
-
- - name: Create 1:many rule with idempotency
- meraki_nat:
- auth_key: '{{auth_key}}'
- org_name: '{{test_org_name}}'
- net_name: '{{test_net_name}}'
- state: present
- one_to_many:
- - public_ip: 1.1.1.1
- uplink: internet1
- port_rules:
- - name: Test rule
- protocol: tcp
- public_port: 10
- local_ip: 192.168.128.1
- local_port: 11
- allowed_ips:
- - any
- register: create_one_many_idempotent
-
- - debug:
- var: create_one_many_idempotent
-
- - assert:
- that:
- - create_one_many_idempotent is not changed
-
- - name: Create port forwarding rule with check mode
- meraki_nat:
- auth_key: '{{auth_key}}'
- org_name: '{{test_org_name}}'
- net_name: '{{test_net_name}}'
- state: present
- port_forwarding:
- - name: Test map
- lan_ip: 192.168.128.1
- uplink: both
- protocol: tcp
- allowed_ips:
- - 1.1.1.1
- public_port: 10
- local_port: 11
- register: create_pf_check
- check_mode: yes
-
- - debug:
- var: create_pf_check
-
- - assert:
- that:
- - create_pf_check is changed
-
- - name: Create port forwarding rule
- meraki_nat:
- auth_key: '{{auth_key}}'
- org_name: '{{test_org_name}}'
- net_name: '{{test_net_name}}'
- state: present
- port_forwarding:
- - name: Test map
- lan_ip: 192.168.128.1
- uplink: both
- protocol: tcp
- allowed_ips:
- - 1.1.1.1
- public_port: 10
- local_port: 11
- register: create_pf
-
- - debug:
- var: create_pf
-
- - assert:
- that:
- - create_pf is changed
-
- - name: Create port forwarding rule with idempotency
- meraki_nat:
- auth_key: '{{auth_key}}'
- org_name: '{{test_org_name}}'
- net_name: '{{test_net_name}}'
- state: present
- port_forwarding:
- - name: Test map
- lan_ip: 192.168.128.1
- uplink: both
- protocol: tcp
- allowed_ips:
- - 1.1.1.1
- public_port: 10
- local_port: 11
- register: create_pf_idempotent
-
- - debug:
- var: create_pf_idempotent
-
- - assert:
- that:
- - create_pf_idempotent is not changed
- - create_pf_idempotent.data.port_forwarding is defined
-
- - name: Create multiple rules
- meraki_nat:
- auth_key: '{{auth_key}}'
- org_name: '{{test_org_name}}'
- net_name: '{{test_net_name}}'
- state: present
- port_forwarding:
- - name: Test map
- lan_ip: 192.168.128.1
- uplink: both
- protocol: tcp
- allowed_ips:
- - 1.1.1.2
- public_port: 10
- local_port: 11
- one_to_many:
- - public_ip: 1.1.1.3
- uplink: internet1
- port_rules:
- - name: Test rule
- protocol: tcp
- public_port: 10
- local_ip: 192.168.128.1
- local_port: 11
- allowed_ips:
- - any
- register: create_multiple
-
- - debug:
- var: create_multiple
-
- - assert:
- that:
- - create_multiple is changed
- - create_multiple.data.one_to_many is defined
- - create_multiple.data.port_forwarding is defined
-
- - assert:
- that:
- - create_multiple is changed
- - create_multiple.data.one_to_many is defined
- - create_multiple.data.port_forwarding is defined
- - create_multiple.diff.before.one_to_many is defined
- - create_multiple.diff.before.port_forwarding is defined
- - create_multiple.diff.after.one_to_many is defined
- - create_multiple.diff.after.port_forwarding is defined
-
- - name: Query all NAT rules
- meraki_nat:
- auth_key: '{{auth_key}}'
- org_name: '{{test_org_name}}'
- net_name: '{{test_net_name}}'
- state: query
- subset: all
- register: query_all
-
- - debug:
- var: query_all
-
- - name: Query 1:1 NAT rules
- meraki_nat:
- auth_key: '{{auth_key}}'
- org_name: '{{test_org_name}}'
- net_name: '{{test_net_name}}'
- state: query
- subset: '1:1'
- register: query_1to1
-
- - debug:
- var: query_1to1
-
- - name: Query 1:many NAT rules
- meraki_nat:
- auth_key: '{{auth_key}}'
- org_name: '{{test_org_name}}'
- net_name: '{{test_net_name}}'
- state: query
- subset: '1:many'
- register: query_1tomany
-
- - debug:
- var: query_1tomany
-
- - name: Query port forwarding rules
- meraki_nat:
- auth_key: '{{auth_key}}'
- org_name: '{{test_org_name}}'
- net_name: '{{test_net_name}}'
- state: query
- subset: port_forwarding
- register: query_pf
-
- - debug:
- var: query_pf
-
- - name: Query multiple rules
- meraki_nat:
- auth_key: '{{auth_key}}'
- org_name: '{{test_org_name}}'
- net_name: '{{test_net_name}}'
- state: query
- subset:
- - '1:1'
- - '1:many'
- register: query_multiple
-
- - debug:
- var: query_multiple
-
- always:
- - name: Delete test network
- meraki_network:
- auth_key: '{{auth_key}}'
- org_name: '{{test_org_name}}'
- net_name: '{{test_net_name}}'
- state: absent
- \ No newline at end of file
diff --git a/test/integration/targets/meraki_network/aliases b/test/integration/targets/meraki_network/aliases
deleted file mode 100644
index ad7ccf7ada..0000000000
--- a/test/integration/targets/meraki_network/aliases
+++ /dev/null
@@ -1 +0,0 @@
-unsupported
diff --git a/test/integration/targets/meraki_network/tasks/main.yml b/test/integration/targets/meraki_network/tasks/main.yml
deleted file mode 100644
index c81c7f9ab1..0000000000
--- a/test/integration/targets/meraki_network/tasks/main.yml
+++ /dev/null
@@ -1,402 +0,0 @@
-# Test code for the Meraki modules
-# 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: Create network without type
- meraki_network:
- auth_key: '{{ auth_key }}'
- state: present
- org_name: '{{test_org_name}}'
- net_name: IntTestNetwork
- timezone: America/Chicago
- delegate_to: localhost
- register: create_net_no_type
- ignore_errors: yes
-
- - assert:
- that:
- - create_net_no_type.msg == 'type parameter is required when creating a network.'
-
- - name: Create network without organization
- meraki_network:
- auth_key: '{{ auth_key }}'
- state: present
- net_name: IntTestNetwork
- timezone: America/Chicago
- delegate_to: localhost
- register: create_net_no_org
- ignore_errors: yes
-
- - name: Create network with type switch
- meraki_network:
- auth_key: '{{ auth_key }}'
- state: present
- org_name: '{{test_org_name}}'
- net_name: IntTestNetworkSwitch
- type: switch
- timezone: America/Chicago
- delegate_to: localhost
- register: create_net_switch
-
- - name: Create network with type switch by org ID
- meraki_network:
- auth_key: '{{ auth_key }}'
- state: present
- org_id: '{{test_org_id}}'
- net_name: IntTestNetworkSwitchOrgID
- type: switch
- timezone: America/Chicago
- delegate_to: localhost
- register: create_net_switch_org_id
-
- - name: Create network with type appliance and no timezone
- meraki_network:
- auth_key: '{{ auth_key }}'
- state: present
- org_name: '{{test_org_name}}'
- net_name: IntTestNetworkAppliance
- type: appliance
- delegate_to: localhost
- register: create_net_appliance_no_tz
-
- - name: Enable VLAN support on appliance network
- meraki_network:
- auth_key: '{{ auth_key }}'
- state: present
- org_name: '{{ test_org_name }}'
- net_name: IntTestNetworkAppliance
- enable_vlans: yes
- delegate_to: localhost
- register: enable_vlan
-
- - assert:
- that:
- - enable_vlan.data.enabled == True
-
- - name: Enable VLAN support on appliance network with idempotency
- meraki_network:
- auth_key: '{{ auth_key }}'
- state: present
- org_name: '{{ test_org_name }}'
- net_name: IntTestNetworkAppliance
- enable_vlans: yes
- delegate_to: localhost
- register: enable_vlan_idempotent
-
- - debug:
- var: enable_vlan_idempotent
-
- - assert:
- that:
- - enable_vlan_idempotent is not changed
- - enable_vlan_idempotent.data is defined
-
- - name: Disable VLAN support on appliance network
- meraki_network:
- auth_key: '{{ auth_key }}'
- state: present
- org_name: '{{ test_org_name }}'
- net_name: IntTestNetworkAppliance
- enable_vlans: no
- delegate_to: localhost
- register: disable_vlan
-
- - assert:
- that:
- - disable_vlan.data.enabled == False
-
- - name: Disable VLAN support on appliance network with idempotency
- meraki_network:
- auth_key: '{{ auth_key }}'
- state: present
- org_name: '{{ test_org_name }}'
- net_name: IntTestNetworkAppliance
- enable_vlans: no
- delegate_to: localhost
- register: disable_vlan_idempotent
-
- - assert:
- that:
- - disable_vlan_idempotent is not changed
- - disable_vlan_idempotent.data is defined
-
- - name: Create network with type wireless and disable my.meraki.com
- meraki_network:
- auth_key: '{{ auth_key }}'
- state: present
- org_name: '{{test_org_name}}'
- net_name: IntTestNetworkWireless
- type: wireless
- timezone: America/Chicago
- disable_my_meraki: yes
- delegate_to: localhost
- register: create_net_wireless
-
- - name: Create network with type wireless, disable my.meraki.com, and check for idempotency
- meraki_network:
- auth_key: '{{ auth_key }}'
- state: present
- org_name: '{{test_org_name}}'
- net_name: IntTestNetworkWireless
- type: wireless
- timezone: America/Chicago
- disable_my_meraki: yes
- delegate_to: localhost
- register: create_net_wireless_idempotent
-
- - assert:
- that:
- - create_net_wireless_idempotent.data is defined
-
- - name: Create network with type combined and disable my.meraki.com
- meraki_network:
- auth_key: '{{ auth_key }}'
- state: present
- org_name: '{{ test_org_name }}'
- net_name: IntTestNetworkCombined
- type:
- - appliance
- - switch
- timezone: America/Chicago
- enable_my_meraki: no
- delegate_to: localhost
- register: create_net_combined
-
- - name: Reenable my.meraki.com
- meraki_network:
- auth_key: '{{ auth_key }}'
- state: present
- org_name: '{{test_org_name}}'
- net_name: IntTestNetworkCombined
- enable_my_meraki: yes
- delegate_to: localhost
- register: enable_meraki_com
-
- - name: Disable my.meraki.com for next test
- meraki_network:
- auth_key: '{{ auth_key }}'
- state: present
- org_name: '{{test_org_name}}'
- net_name: IntTestNetworkCombined
- enable_my_meraki: no
- delegate_to: localhost
-
- - name: Enable remote status page
- meraki_network:
- auth_key: '{{ auth_key }}'
- state: present
- org_name: '{{test_org_name}}'
- net_name: IntTestNetworkCombined
- enable_remote_status_page: yes
- delegate_to: localhost
- register: disable_remote_status
-
- - debug:
- msg: '{{disable_remote_status}}'
-
- - assert:
- that:
- - disable_remote_status.data.disable_remote_status_page == False
-
- - name: Disable remote status page
- meraki_network:
- auth_key: '{{ auth_key }}'
- state: present
- org_name: '{{test_org_name}}'
- net_name: IntTestNetworkCombined
- enable_remote_status_page: no
- delegate_to: localhost
- register: enable_remote_status
-
- - debug:
- msg: '{{enable_remote_status}}'
-
- - assert:
- that:
- - enable_remote_status.data.disable_remote_status_page == True
-
- - name: Test status pages are mutually exclusive when on
- meraki_network:
- auth_key: '{{ auth_key }}'
- state: present
- org_name: '{{test_org_name}}'
- net_name: IntTestNetworkCombined
- enable_my_meraki: yes
- enable_remote_status_page: no
- delegate_to: localhost
- register: status_exclusivity
- ignore_errors: yes
-
- - assert:
- that:
- - '"must be true when setting" in status_exclusivity.msg'
-
- - name: Create network with one tag
- meraki_network:
- auth_key: '{{ auth_key }}'
- state: present
- org_name: '{{test_org_name}}'
- net_name: IntTestNetworkTag
- type: switch
- timezone: America/Chicago
- tags: first_tag
- delegate_to: localhost
- register: create_net_tag
-
- - name: Create network with two tags
- meraki_network:
- auth_key: '{{ auth_key }}'
- state: present
- org_name: '{{test_org_name}}'
- net_name: IntTestNetworkTags
- type: switch
- timezone: America/Chicago
- tags:
- - first_tag
- - second_tag
- delegate_to: localhost
- register: create_net_tags
-
- - set_fact:
- tag_net_id: '{{create_net_tags.data.id}}'
-
- - name: Modify network by net_id
- meraki_network:
- auth_key: '{{ auth_key }}'
- state: present
- org_name: '{{test_org_name}}'
- net_id: '{{tag_net_id}}'
- type: switch
- timezone: America/Chicago
- tags:
- - first_tag
- - second_tag
- - third_tag
- delegate_to: localhost
- register: create_net_modified
-
- - name: Modify network with idempotency
- meraki_network:
- auth_key: '{{ auth_key }}'
- state: present
- org_name: '{{test_org_name}}'
- net_name: IntTestNetworkTags
- type: switch
- timezone: America/Chicago
- tags:
- - first_tag
- - second_tag
- - third_tag
- delegate_to: localhost
- register: create_net_modified_idempotent
-
- - assert:
- that:
- - create_net_modified_idempotent.data is defined
-
- - name: Present assertions
- assert:
- that:
- - create_net_combined.data.type == 'combined'
- - create_net_combined.data.disable_my_meraki_com == True
- - enable_meraki_com.data.disable_my_meraki_com == False
- - '"org_name or org_id parameters are required" in create_net_no_org.msg'
- - '"IntTestNetworkAppliance" in create_net_appliance_no_tz.data.name'
- - create_net_appliance_no_tz.changed == True
- - '"IntTestNetworkSwitch" in create_net_switch.data.name'
- - '"IntTestNetworkSwitchOrgID" in create_net_switch_org_id.data.name'
- - '"IntTestNetworkWireless" in create_net_wireless.data.name'
- - create_net_wireless.data.disable_my_meraki_com == True
- - create_net_wireless_idempotent.changed == False
- - create_net_wireless_idempotent.data is defined
- - '"first_tag" in create_net_tag.data.tags'
- - '"second_tag" in create_net_tags.data.tags'
- - '"third_tag" in create_net_modified.data.tags'
- - create_net_modified.changed == True
- - create_net_modified_idempotent.changed == False
- - create_net_modified_idempotent.data is defined
-
- - name: Query all networks
- meraki_network:
- auth_key: '{{ auth_key }}'
- state: query
- org_name: '{{test_org_name}}'
- delegate_to: localhost
- register: net_query_all
-
- - name: Query a configuration template
- meraki_network:
- auth_key: '{{auth_key}}'
- state: query
- org_name: '{{test_org_name}}'
- net_name: '{{test_template_name}}'
- delegate_to: localhost
- register: query_config_template
-
- - name: Query one network
- meraki_network:
- auth_key: '{{ auth_key }}'
- state: query
- org_name: '{{test_org_name}}'
- net_name: IntTestNetworkSwitch
- delegate_to: localhost
- register: net_query_one
-
- - name: Query assertions
- assert:
- that:
- - 'net_query_one.data.name == "IntTestNetworkSwitch"'
- - 'query_config_template.data.name == "{{ test_template_name }}"'
-
-#############################################################################
-# Tear down starts here
-#############################################################################
- always:
- - name: Delete network without org
- meraki_network:
- auth_key: '{{ auth_key }}'
- state: absent
- net_name: IntTestNetworkSwitch
- delegate_to: localhost
- register: delete_all_no_org
- ignore_errors: yes
-
- - name: Delete network by org ID
- meraki_network:
- auth_key: '{{ auth_key }}'
- state: absent
- org_id: '{{test_org_id}}'
- net_name: IntTestNetworkSwitchOrgID
- delegate_to: localhost
- register: delete_net_org_id
-
- - name: Query after delete with org ID
- meraki_network:
- auth_key: '{{ auth_key }}'
- state: query
- org_name: '{{test_org_name}}'
- delegate_to: localhost
- register: query_deleted_org_id
-
- - name: Delete all networks
- meraki_network:
- auth_key: '{{ auth_key }}'
- state: absent
- org_name: '{{test_org_name}}'
- net_name: '{{ item }}'
- delegate_to: localhost
- register: delete_all
- ignore_errors: yes
- loop:
- - IntTestNetworkSwitch
- - IntTestNetworkWireless
- - IntTestNetworkAppliance
- - IntTestNetworkCombined
- - IntTestNetworkTag
- - IntTestNetworkTags
-
- - assert:
- that:
- - 'delete_all_no_org.msg == "org_name or org_id parameters are required"'
diff --git a/test/integration/targets/meraki_organization/aliases b/test/integration/targets/meraki_organization/aliases
deleted file mode 100644
index ad7ccf7ada..0000000000
--- a/test/integration/targets/meraki_organization/aliases
+++ /dev/null
@@ -1 +0,0 @@
-unsupported
diff --git a/test/integration/targets/meraki_organization/tasks/main.yml b/test/integration/targets/meraki_organization/tasks/main.yml
deleted file mode 100644
index e7ad65b811..0000000000
--- a/test/integration/targets/meraki_organization/tasks/main.yml
+++ /dev/null
@@ -1,8 +0,0 @@
-# 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)
----
-- 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
deleted file mode 100644
index 75ba93c6b9..0000000000
--- a/test/integration/targets/meraki_organization/tasks/tests.yml
+++ /dev/null
@@ -1,127 +0,0 @@
-# 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
diff --git a/test/integration/targets/meraki_snmp/aliases b/test/integration/targets/meraki_snmp/aliases
deleted file mode 100644
index ad7ccf7ada..0000000000
--- a/test/integration/targets/meraki_snmp/aliases
+++ /dev/null
@@ -1 +0,0 @@
-unsupported
diff --git a/test/integration/targets/meraki_snmp/tasks/main.yml b/test/integration/targets/meraki_snmp/tasks/main.yml
deleted file mode 100644
index d914dd0f64..0000000000
--- a/test/integration/targets/meraki_snmp/tasks/main.yml
+++ /dev/null
@@ -1,306 +0,0 @@
-# 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 SNMP network
- meraki_network:
- auth_key: '{{auth_key}}'
- org_name: '{{test_org_name}}'
- net_name: '{{test_net_name}}'
- state: present
- type: appliance
- delegate_to: localhost
- register: new_net
-
- - set_fact:
- net_id: new_net.data.id
-
- - name: Query all SNMP settings
- meraki_snmp:
- auth_key: '{{auth_key}}'
- org_name: '{{test_org_name}}'
- state: query
- delegate_to: localhost
- register: snmp_query
-
- - debug:
- msg: '{{snmp_query}}'
-
- - name: Enable SNMPv2c
- meraki_snmp:
- auth_key: '{{auth_key}}'
- org_name: '{{test_org_name}}'
- state: present
- v2c_enabled: true
- delegate_to: localhost
- register: snmp_v2_enable
-
- - debug:
- msg: '{{snmp_v2_enable}}'
-
- - assert:
- that:
- - snmp_v2_enable.data.v2_community_string is defined
- - snmp_v2_enable.data.v2c_enabled == true
-
- - name: Disable SNMPv2c
- meraki_snmp:
- auth_key: '{{auth_key}}'
- org_name: '{{test_org_name}}'
- state: present
- v2c_enabled: False
- delegate_to: localhost
- register: snmp_v2_disable
-
- - assert:
- that:
- - snmp_v2_disable.data.v2_community_string is not defined
- - snmp_v2_disable.data.v2c_enabled == False
-
- - name: Enable SNMPv2c with org_id
- meraki_snmp:
- auth_key: '{{auth_key}}'
- org_id: '{{test_org_id}}'
- state: present
- v2c_enabled: true
- delegate_to: localhost
- register: snmp_v2_enable_id
-
- - debug:
- msg: '{{snmp_v2_enable_id}}'
-
- - assert:
- that:
- - snmp_v2_enable_id.data.v2_community_string is defined
- - snmp_v2_enable_id.data.v2c_enabled == true
-
- - name: Disable SNMPv2c with org_id
- meraki_snmp:
- auth_key: '{{auth_key}}'
- org_id: '{{test_org_id}}'
- state: present
- v2c_enabled: False
- delegate_to: localhost
- register: snmp_v2_disable_id
-
- - assert:
- that:
- - snmp_v2_disable_id.data.v2_community_string is not defined
- - snmp_v2_disable_id.data.v2c_enabled == False
-
- - name: Enable SNMPv3 with check mode
- meraki_snmp:
- auth_key: '{{auth_key}}'
- org_name: '{{test_org_name}}'
- state: present
- v3_enabled: true
- v3_auth_mode: SHA
- v3_auth_pass: ansiblepass
- v3_priv_mode: AES128
- v3_priv_pass: ansiblepass
- delegate_to: localhost
- check_mode: yes
- register: snmp_v3_enable_check
-
- - assert:
- that:
- - snmp_v3_enable_check.data.v3_enabled == True
- - snmp_v3_enable_check.changed == True
-
- - name: Enable SNMPv3
- meraki_snmp:
- auth_key: '{{auth_key}}'
- org_name: '{{test_org_name}}'
- state: present
- v3_enabled: true
- v3_auth_mode: SHA
- v3_auth_pass: ansiblepass
- v3_priv_mode: AES128
- v3_priv_pass: ansiblepass
- delegate_to: localhost
- register: snmp_v3_enable
-
- - assert:
- that:
- - snmp_v3_enable.data.v3_enabled == True
- - snmp_v3_enable.changed == True
-
- - name: Check for idempotency
- meraki_snmp:
- auth_key: '{{auth_key}}'
- org_name: '{{test_org_name}}'
- state: present
- v3_enabled: true
- v3_auth_mode: SHA
- v3_auth_pass: ansiblepass
- v3_priv_mode: AES128
- v3_priv_pass: ansiblepass
- delegate_to: localhost
- register: snmp_idempotent
-
- - debug:
- msg: '{{snmp_idempotent}}'
-
- - assert:
- that:
- - snmp_idempotent.changed == False
- - snmp_idempotent.data is defined
-
- - name: Add peer IPs
- meraki_snmp:
- auth_key: '{{auth_key}}'
- org_name: '{{test_org_name}}'
- state: present
- v3_enabled: true
- v3_auth_mode: SHA
- v3_auth_pass: ansiblepass
- v3_priv_mode: AES128
- v3_priv_pass: ansiblepass
- peer_ips: 1.1.1.1;2.2.2.2
- delegate_to: localhost
- register: peers
-
- - debug:
- msg: '{{peers}}'
-
- - assert:
- that:
- - peers.data.peer_ips is defined
-
- - name: Add invalid peer IPs
- meraki_snmp:
- auth_key: '{{auth_key}}'
- org_name: '{{test_org_name}}'
- state: present
- peer_ips: 1.1.1.1 2.2.2.2
- delegate_to: localhost
- register: invalid_peers
- ignore_errors: yes
-
- - assert:
- that:
- '"Peer IP addresses are semi-colon delimited." in invalid_peers.msg'
-
- - name: Set short password
- meraki_snmp:
- auth_key: '{{auth_key}}'
- org_name: '{{test_org_name}}'
- state: present
- v3_enabled: true
- v3_auth_mode: SHA
- v3_auth_pass: ansible
- v3_priv_mode: AES128
- v3_priv_pass: ansible
- peer_ips: 1.1.1.1;2.2.2.2
- delegate_to: localhost
- register: short_password
- ignore_errors: yes
-
- - debug:
- msg: '{{short_password}}'
-
- - assert:
- that:
- - '"at least 8" in short_password.msg'
-
- - name: Set network access type to community string
- meraki_snmp:
- auth_key: '{{auth_key}}'
- org_name: '{{test_org_name}}'
- net_name: '{{test_net_name}}'
- state: present
- access: community
- community_string: abc123
- delegate_to: localhost
- register: set_net_community
-
- - debug:
- var: set_net_community
-
- - assert:
- that:
- - set_net_community is changed
- - set_net_community.data is defined
-
- - name: Set network access type to username
- meraki_snmp:
- auth_key: '{{auth_key}}'
- org_name: '{{test_org_name}}'
- net_name: '{{test_net_name}}'
- state: present
- access: users
- users:
- - username: ansibleuser
- passphrase: ansiblepass
- delegate_to: localhost
- register: set_net_user
-
- - debug:
- var: set_net_user
-
- - assert:
- that:
- - set_net_user is changed
- - set_net_user.data is defined
-
- - name: Set network access type to none
- meraki_snmp:
- auth_key: '{{auth_key}}'
- org_name: '{{test_org_name}}'
- net_name: '{{test_net_name}}'
- state: present
- access: none
- delegate_to: localhost
- register: set_net_none
-
- - debug:
- var: set_net_none
-
- - assert:
- that:
- - set_net_none is changed
- - set_net_none.data is defined
-
- - name: Query network SNMP settings
- meraki_snmp:
- auth_key: '{{auth_key}}'
- org_name: '{{test_org_name}}'
- net_name: '{{test_net_name}}'
- state: query
- delegate_to: localhost
- register: get_net
-
- - debug:
- var: get_net
-
- - assert:
- that:
- - get_net.data is defined
-
- always:
- - name: Disable SNMPv3
- meraki_snmp:
- auth_key: '{{auth_key}}'
- org_name: '{{test_org_name}}'
- state: present
- v3_enabled: no
- v3_auth_mode: SHA
- v3_auth_pass: ansiblepass
- v3_priv_mode: AES128
- v3_priv_pass: ansiblepass
- delegate_to: localhost
-
- - name: Delete SNMP network
- meraki_network:
- auth_key: '{{auth_key}}'
- org_name: '{{test_org_name}}'
- net_name: '{{test_net_name}}'
- state: absent
- delegate_to: localhost
diff --git a/test/integration/targets/meraki_ssid/aliases b/test/integration/targets/meraki_ssid/aliases
deleted file mode 100644
index ad7ccf7ada..0000000000
--- a/test/integration/targets/meraki_ssid/aliases
+++ /dev/null
@@ -1 +0,0 @@
-unsupported
diff --git a/test/integration/targets/meraki_ssid/tasks/main.yml b/test/integration/targets/meraki_ssid/tasks/main.yml
deleted file mode 100644
index 66291766cf..0000000000
--- a/test/integration/targets/meraki_ssid/tasks/main.yml
+++ /dev/null
@@ -1,408 +0,0 @@
-# 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)
----
-- block:
- - name: Test an API key is provided
- fail:
- msg: Please define an API key
- when: auth_key is not defined
-
- - 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
-
- - 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
- - enable_name_ssid_idempotent.data is defined
-
- - 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: Query one SSID with number
- meraki_ssid:
- auth_key: '{{auth_key}}'
- state: query
- org_name: '{{test_org_name}}'
- net_name: TestNetSSID
- number: 1
- delegate_to: localhost
- register: query_one_number
-
- - debug:
- msg: '{{query_one_number}}'
-
- - assert:
- that:
- - query_one_number.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 VLAN arg spec
- meraki_ssid:
- auth_key: '{{auth_key}}'
- state: present
- org_name: '{{test_org_name}}'
- net_name: TestNetSSID
- number: 1
- use_vlan_tagging: yes
- ip_assignment_mode: Bridge mode
- default_vlan_id: 1
- ap_tags_vlan_ids:
- - tags: wifi
- vlan_id: 2
- delegate_to: localhost
- register: set_vlan_arg
-
- - debug:
- var: set_vlan_arg
-
- - assert:
- that: set_vlan_arg is changed
-
- - name: Set VLAN arg spec
- meraki_ssid:
- auth_key: '{{auth_key}}'
- state: present
- org_name: '{{test_org_name}}'
- net_name: TestNetSSID
- number: 1
- use_vlan_tagging: yes
- ip_assignment_mode: Bridge mode
- default_vlan_id: 1
- ap_tags_vlan_ids:
- - tags: wifi
- vlan_id: 2
- delegate_to: localhost
- register: set_vlan_arg_idempotent
-
- - debug:
- var: set_vlan_arg_idempotent
-
- - assert:
- that: set_vlan_arg_idempotent is not changed
-
-
- - 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.auth_mode == 'psk'
- - psk.data.encryption_mode == 'wpa'
- - psk.data.wpa_encryption_mode == 'WPA2 only'
-
- - name: Set PSK with idempotency
- 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_idempotent
-
- - debug:
- msg: '{{ psk_idempotent }}'
-
- - assert:
- that:
- - psk_idempotent is not changed
-
- - 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.splash_page == '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.radius_servers.0.host == '192.0.1.200'
-
- - name: Configure RADIUS servers with idempotency
- 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_idempotent
-
- - debug:
- var: set_radius_server_idempotent
-
- - assert:
- that:
- - set_radius_server_idempotent is not changed
-
- #################
- # Error testing #
- #################
- - 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: Error for PSK and RADIUS servers
- meraki_ssid:
- auth_key: '{{auth_key}}'
- state: present
- org_name: '{{test_org_name}}'
- net_name: TestNetSSID
- name: AnsibleSSID
- auth_mode: psk
- radius_servers:
- - host: 192.0.1.200
- port: 1234
- secret: abc98765
- delegate_to: localhost
- register: err_radius_server_psk
- ignore_errors: yes
-
- - debug:
- var: err_radius_server_psk
-
- - assert:
- that:
- - 'err_radius_server_psk.msg == "radius_servers requires auth_mode to be open-with-radius or 8021x-radius"'
-
- - name: Set VLAN arg without default VLAN error
- meraki_ssid:
- auth_key: '{{auth_key}}'
- state: present
- org_name: '{{test_org_name}}'
- net_name: TestNetSSID
- number: 1
- use_vlan_tagging: yes
- ip_assignment_mode: Bridge mode
- ap_tags_vlan_ids:
- - tags: wifi
- vlan_id: 2
- delegate_to: localhost
- register: set_vlan_arg_err
- ignore_errors: yes
-
- - debug:
- var: set_vlan_arg_err
-
- - assert:
- that:
- - 'set_vlan_arg_err.msg == "default_vlan_id is required when use_vlan_tagging is True"'
-
- always:
- - 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}}'
diff --git a/test/integration/targets/meraki_static_route/aliases b/test/integration/targets/meraki_static_route/aliases
deleted file mode 100644
index ad7ccf7ada..0000000000
--- a/test/integration/targets/meraki_static_route/aliases
+++ /dev/null
@@ -1 +0,0 @@
-unsupported
diff --git a/test/integration/targets/meraki_static_route/tasks/main.yml b/test/integration/targets/meraki_static_route/tasks/main.yml
deleted file mode 100644
index 10ba31eab9..0000000000
--- a/test/integration/targets/meraki_static_route/tasks/main.yml
+++ /dev/null
@@ -1,170 +0,0 @@
-# Test code for the Meraki modules
-# 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: Create appliance network
- meraki_network:
- auth_key: '{{ auth_key }}'
- state: present
- org_name: '{{test_org_name}}'
- net_name: IntTestNetwork
- timezone: America/Chicago
- type: appliance
- delegate_to: localhost
- register: net
-
- - set_fact:
- net_id: '{{net.data.id}}'
-
- - name: Initialize static route id list
- set_fact:
- route_ids: []
-
- - name: Create static_route
- meraki_static_route:
- auth_key: '{{auth_key}}'
- state: present
- org_name: '{{test_org_name}}'
- net_name: IntTestNetwork
- name: Test Route
- subnet: 192.0.1.0/24
- gateway_ip: 192.168.128.1
- delegate_to: localhost
- register: create_route
-
- - set_fact:
- route_ids: "{{ route_ids + [create_route.data.id] }}"
-
- - name: Create second static_route
- meraki_static_route:
- auth_key: '{{auth_key}}'
- state: present
- org_name: '{{test_org_name}}'
- net_name: IntTestNetwork
- name: Test Route 2
- subnet: 192.0.2.0/24
- gateway_ip: 192.168.128.1
- delegate_to: localhost
- register: second_create
-
- - set_fact:
- route_ids: "{{ route_ids + [second_create.data.id] }}"
-
- - assert:
- that:
- - create_route.changed == True
- - create_route.data.id is defined
-
- - name: Update static route
- meraki_static_route:
- auth_key: '{{auth_key}}'
- state: present
- org_name: '{{test_org_name}}'
- net_name: IntTestNetwork
- route_id: '{{create_route.data.id}}'
- subnet: 192.0.3.0/24
- enabled: yes
- delegate_to: localhost
- register: update
-
- - assert:
- that:
- - update.data.subnet == "192.0.3.0/24"
-
- - name: Query static routes
- meraki_static_route:
- auth_key: '{{auth_key}}'
- state: query
- org_name: '{{test_org_name}}'
- net_name: IntTestNetwork
- delegate_to: localhost
- register: query_all
-
- - debug:
- var: query_all
-
- - assert:
- that:
- - query_all.data | length >= 2
-
- - name: Update static route with idempotency
- meraki_static_route:
- auth_key: '{{auth_key}}'
- state: present
- org_name: '{{test_org_name}}'
- net_name: IntTestNetwork
- route_id: '{{create_route.data.id}}'
- name: Test Route
- gateway_ip: 192.168.128.1
- subnet: 192.0.3.0/24
- enabled: yes
- delegate_to: localhost
- register: update_idempotent
-
- - assert:
- that:
- - update_idempotent.changed == False
- - update_idempotent.data is defined
-
- - name: Update static route with fixed IP assignment and reservation
- meraki_static_route:
- auth_key: '{{auth_key}}'
- state: present
- org_name: '{{test_org_name}}'
- net_name: IntTestNetwork
- route_id: '{{create_route.data.id}}'
- fixed_ip_assignments:
- - mac: aa:bb:cc:dd:ee:ff
- ip: 192.0.3.11
- name: WebServer
- reserved_ip_ranges:
- - start: 192.168.3.2
- end: 192.168.3.10
- comment: Printers
- delegate_to: localhost
- register: fixed_ip
-
- - debug:
- var: fixed_ip
-
- - assert:
- that:
- - fixed_ip.data.fixedIpAssignments | length == 1
- - fixed_ip.data.reservedIpRanges | length == 1
-
-
- - name: Query single static route
- meraki_static_route:
- auth_key: '{{auth_key}}'
- state: query
- org_name: '{{test_org_name}}'
- net_name: IntTestNetwork
- route_id: '{{create_route.data.id}}'
- delegate_to: localhost
- register: query_one
-
- - assert:
- that:
- - query_one.data.name == "Test Route"
-
- - name: Delete static routes
- meraki_static_route:
- auth_key: '{{auth_key}}'
- state: absent
- org_name: '{{test_org_name}}'
- net_name: IntTestNetwork
- route_id: '{{item}}'
- delegate_to: localhost
- loop: '{{route_ids}}'
- register: delete_all
-
- always:
- - name: Delete appliance network
- meraki_network:
- auth_key: '{{ auth_key }}'
- state: absent
- org_name: '{{test_org_name}}'
- net_name: IntTestNetwork
- delegate_to: localhost
diff --git a/test/integration/targets/meraki_switchport/aliases b/test/integration/targets/meraki_switchport/aliases
deleted file mode 100644
index ad7ccf7ada..0000000000
--- a/test/integration/targets/meraki_switchport/aliases
+++ /dev/null
@@ -1 +0,0 @@
-unsupported
diff --git a/test/integration/targets/meraki_switchport/tasks/main.yml b/test/integration/targets/meraki_switchport/tasks/main.yml
deleted file mode 100644
index 8146f2845c..0000000000
--- a/test/integration/targets/meraki_switchport/tasks/main.yml
+++ /dev/null
@@ -1,297 +0,0 @@
-# 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)
----
-- name: Test an API key is provided
- fail:
- msg: Please define an API key
- when: auth_key is not defined
-
-- name: Query all switchports
- meraki_switchport:
- auth_key: '{{auth_key}}'
- state: query
- serial: Q2HP-2C6E-GTLD
- delegate_to: localhost
- register: query_all
-
-- debug:
- msg: '{{query_all}}'
-
-- name: Query one switchport
- meraki_switchport:
- auth_key: '{{auth_key}}'
- state: query
- serial: Q2HP-2C6E-GTLD
- number: 1
- delegate_to: localhost
- register: query_one
-
-- debug:
- msg: '{{query_one}}'
-
-- name: Enable switchport
- meraki_switchport:
- auth_key: '{{auth_key}}'
- state: present
- serial: Q2HP-2C6E-GTLD
- number: 7
- enabled: true
- delegate_to: localhost
- register: update_port_true
-
-- debug:
- msg: '{{update_port_true}}'
-
-- assert:
- that:
- - update_port_true.data.enabled == True
-
-- name: Disable switchport
- meraki_switchport:
- auth_key: '{{auth_key}}'
- state: present
- serial: Q2HP-2C6E-GTLD
- number: 7
- enabled: false
- delegate_to: localhost
- register: update_port_false
-
-- debug:
- msg: '{{update_port_false}}'
-
-- assert:
- that:
- - update_port_false.data.enabled == False
-
-
-- name: Name switchport
- meraki_switchport:
- auth_key: '{{auth_key}}'
- state: present
- serial: Q2HP-2C6E-GTLD
- number: 7
- name: Test Port
- delegate_to: localhost
- register: update_port_name
-
-- debug:
- msg: '{{update_port_name}}'
-
-- assert:
- that:
- - update_port_name.data.name == 'Test Port'
-
-- name: Configure access port
- meraki_switchport:
- auth_key: '{{auth_key}}'
- state: present
- serial: Q2HP-2C6E-GTLD
- number: 7
- enabled: true
- name: Test Port
- tags: desktop
- type: access
- vlan: 10
- delegate_to: localhost
- register: update_access_port
-
-- debug:
- msg: '{{update_access_port}}'
-
-- assert:
- that:
- - update_access_port.data.vlan == 10
-
-- name: Configure port as trunk
- meraki_switchport:
- auth_key: '{{auth_key}}'
- state: present
- serial: Q2HP-2C6E-GTLD
- number: 8
- enabled: true
- name: Test Port
- type: trunk
- vlan: 10
- allowed_vlans: 10, 100, 200
- delegate_to: localhost
-
-- name: Convert trunk port to access
- meraki_switchport:
- auth_key: '{{auth_key}}'
- state: present
- serial: Q2HP-2C6E-GTLD
- number: 8
- enabled: true
- name: Test Port
- type: access
- vlan: 10
- delegate_to: localhost
-
-- name: Test converted port for idempotency
- meraki_switchport:
- auth_key: '{{auth_key}}'
- state: present
- serial: Q2HP-2C6E-GTLD
- number: 8
- enabled: true
- name: Test Port
- type: access
- vlan: 10
- delegate_to: localhost
- register: convert_idempotent
-
-- assert:
- that:
- - convert_idempotent.changed == False
-
-- name: Configure access port with voice VLAN
- meraki_switchport:
- auth_key: '{{auth_key}}'
- state: present
- serial: Q2HP-2C6E-GTLD
- number: 7
- enabled: true
- name: Test Port
- tags: desktop
- type: access
- vlan: 10
- voice_vlan: 11
- delegate_to: localhost
- register: update_port_vvlan
-
-- debug:
- msg: '{{update_port_vvlan}}'
-
-- assert:
- that:
- - update_port_vvlan.data.voice_vlan == 11
- - update_port_vvlan.changed == True
-
-- name: Check access port for idempotenty
- meraki_switchport:
- auth_key: '{{auth_key}}'
- state: present
- serial: Q2HP-2C6E-GTLD
- number: 7
- enabled: true
- name: Test Port
- tags: desktop
- type: access
- vlan: 10
- voice_vlan: 11
- delegate_to: localhost
- register: update_port_access_idempotent
-
-- debug:
- msg: '{{update_port_access_idempotent}}'
-
-- assert:
- that:
- - update_port_access_idempotent.changed == False
- - update_port_access_idempotent.data is defined
-
-- name: Configure trunk port
- meraki_switchport:
- auth_key: '{{auth_key}}'
- state: present
- serial: Q2HP-2C6E-GTLD
- number: 7
- enabled: true
- name: Server port
- tags: server
- type: trunk
- allowed_vlans: all
- vlan: 8
- delegate_to: localhost
- register: update_trunk
-
-- debug:
- msg: '{{update_trunk}}'
-
-- assert:
- that:
- - update_trunk.data.tags == 'server'
- - update_trunk.data.type == 'trunk'
- - update_trunk.data.allowed_vlans == 'all'
-
-- name: Configure trunk port with specific VLANs
- meraki_switchport:
- auth_key: '{{auth_key}}'
- state: present
- serial: Q2HP-2C6E-GTLD
- number: 7
- enabled: true
- name: Server port
- tags: server
- type: trunk
- vlan: 8
- allowed_vlans:
- - 10
- - 15
- - 20
- delegate_to: localhost
- register: update_trunk
-
-- debug:
- msg: '{{update_trunk}}'
-
-- assert:
- that:
- - update_trunk.data.tags == 'server'
- - update_trunk.data.type == 'trunk'
- - update_trunk.data.allowed_vlans == '8,10,15,20'
-
-- name: Configure trunk port with specific VLANs and native VLAN
- meraki_switchport:
- auth_key: '{{auth_key}}'
- state: present
- serial: Q2HP-2C6E-GTLD
- number: 7
- enabled: true
- name: Server port
- tags: server
- type: trunk
- vlan: 2
- allowed_vlans:
- - 10
- - 15
- - 20
- delegate_to: localhost
- register: update_trunk
-
-- debug:
- msg: '{{update_trunk}}'
-
-- assert:
- that:
- - update_trunk.data.tags == 'server'
- - update_trunk.data.type == 'trunk'
- - update_trunk.data.allowed_vlans == '2,10,15,20'
-
-- name: Check for idempotency on trunk port
- meraki_switchport:
- auth_key: '{{auth_key}}'
- state: present
- serial: Q2HP-2C6E-GTLD
- number: 7
- enabled: true
- name: Server port
- tags: server
- type: trunk
- vlan: 2
- allowed_vlans:
- - 10
- - 15
- - 20
- delegate_to: localhost
- register: update_trunk_idempotent
-
-- debug:
- msg: '{{update_trunk_idempotent}}'
-
-- assert:
- that:
- - update_trunk_idempotent.changed == False
- - update_trunk_idempotent.data is defined
diff --git a/test/integration/targets/meraki_syslog/tasks/main.yml b/test/integration/targets/meraki_syslog/tasks/main.yml
deleted file mode 100644
index e2fdd6c8db..0000000000
--- a/test/integration/targets/meraki_syslog/tasks/main.yml
+++ /dev/null
@@ -1,169 +0,0 @@
-# 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
-
- - set_fact:
- syslog_test_net_name: 'syslog_{{test_net_name}}'
-
- - name: Create network with type appliance and no timezone
- meraki_network:
- auth_key: '{{ auth_key }}'
- state: present
- org_name: '{{test_org_name}}'
- net_name: '{{test_net_name}}'
- type: appliance
- delegate_to: localhost
- register: new_net
-
- - set_fact:
- net_id: '{{new_net.data.id}}'
-
- - name: Query syslog settings
- meraki_syslog:
- auth_key: '{{auth_key}}'
- org_name: '{{test_org_name}}'
- net_name: '{{test_net_name}}'
- state: query
- delegate_to: localhost
- register: query_all
-
- - debug:
- msg: '{{query_all}}'
-
- - name: Set syslog server
- meraki_syslog:
- auth_key: '{{auth_key}}'
- org_name: '{{test_org_name}}'
- net_name: '{{test_net_name}}'
- state: present
- servers:
- - host: 192.0.1.2
- port: 514
- roles:
- - Appliance event log
- delegate_to: localhost
- register: create_server
-
- - debug:
- msg: '{{create_server.data}}'
-
- - assert:
- that:
- - create_server['data'][0]['host'] == "192.0.1.2"
-
- - name: Set syslog server with idempotency
- meraki_syslog:
- auth_key: '{{auth_key}}'
- org_name: '{{test_org_name}}'
- net_name: '{{test_net_name}}'
- state: present
- servers:
- - host: 192.0.1.2
- port: 514
- roles:
- - Appliance event log
- delegate_to: localhost
- register: create_server_idempotency
-
- - debug:
- msg: '{{create_server_idempotency}}'
-
- - assert:
- that:
- - create_server_idempotency.changed == False
- - create_server_idempotency.data is defined
-
- - name: Set multiple syslog servers
- meraki_syslog:
- auth_key: '{{auth_key}}'
- org_name: '{{test_org_name}}'
- net_id: '{{net_id}}'
- state: present
- servers:
- - host: 192.0.1.3
- port: 514
- roles:
- - Appliance event log
- - host: 192.0.1.4
- port: 514
- roles:
- - Appliance Event log
- - Flows
- - host: 192.0.1.5
- port: 514
- roles:
- - Flows
- delegate_to: localhost
- register: create_multiple_servers
-
- - debug:
- msg: '{{create_multiple_servers}}'
-
- - assert:
- that:
- - create_multiple_servers['data'][0]['host'] == "192.0.1.3"
- - create_multiple_servers['data'][1]['host'] == "192.0.1.4"
- - create_multiple_servers['data'][2]['host'] == "192.0.1.5"
- - create_multiple_servers['data'] | length == 3
-
- - name: Create syslog server with bad name
- meraki_syslog:
- auth_key: '{{auth_key}}'
- org_name: '{{test_org_name}}'
- net_name: '{{test_net_name}}'
- state: present
- servers:
- - host: 192.0.1.6
- port: 514
- roles:
- - Invalid role
- delegate_to: localhost
- register: invalid_role
- ignore_errors: yes
-
- # - debug:
- # msg: '{{invalid_role.body.errors.0}}'
-
- - assert:
- that:
- - '"Please select at least one valid role" in invalid_role.body.errors.0'
-
- - name: Add role to existing syslog server # Adding doesn't work, just creation
- meraki_syslog:
- auth_key: '{{auth_key}}'
- org_name: '{{test_org_name}}'
- net_name: '{{test_net_name}}'
- state: present
- servers:
- - host: 192.0.1.2
- port: 514
- roles:
- - flows
- delegate_to: localhost
- register: add_role
-
- - debug:
- msg: '{{add_role.data.0.roles}}'
-
- - assert:
- that:
- - add_role.data.0.roles.0 == 'Flows'
- # - add_role.data.0.roles | length == 2
-
- always:
- - name: Delete syslog test network
- meraki_network:
- auth_key: '{{ auth_key }}'
- state: absent
- org_name: '{{test_org_name}}'
- net_name: '{{test_net_name}}'
- delegate_to: localhost
- register: delete_all
- ignore_errors: yes
diff --git a/test/integration/targets/meraki_vlan/aliases b/test/integration/targets/meraki_vlan/aliases
deleted file mode 100644
index ad7ccf7ada..0000000000
--- a/test/integration/targets/meraki_vlan/aliases
+++ /dev/null
@@ -1 +0,0 @@
-unsupported
diff --git a/test/integration/targets/meraki_vlan/tasks/main.yml b/test/integration/targets/meraki_vlan/tasks/main.yml
deleted file mode 100644
index 0f3cd233a8..0000000000
--- a/test/integration/targets/meraki_vlan/tasks/main.yml
+++ /dev/null
@@ -1,412 +0,0 @@
-# Test code for the Meraki VLAN 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: Test play without auth_key
- meraki_network:
- state: present
- org_name: '{{test_org_name}}'
- net_name: '{{test_net_name}}'
- type: appliance
- delegate_to: localhost
- ignore_errors: yes
- register: no_key
-
- - assert:
- that:
- - '"missing required arguments" in no_key.msg'
-
- - name: Create test network
- meraki_network:
- auth_key: '{{auth_key}}'
- state: present
- org_name: '{{test_org_name}}'
- net_name: '{{test_net_name}}'
- type: appliance
- delegate_to: localhost
-
- - name: Enable VLANs on network
- meraki_network:
- auth_key: '{{auth_key}}'
- state: present
- org_name: '{{test_org_name}}'
- net_name: '{{test_net_name}}'
- 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}}'
- 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
- environment:
- ANSIBLE_MERAKI_FORMAT: camelcase
-
- - debug:
- msg: '{{create_vlan}}'
-
- - assert:
- that:
- - create_vlan.data.id == 2
- - create_vlan.changed == True
- - create_vlan.data.networkId is defined
-
- - name: Update VLAN with 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_check
- check_mode: yes
-
- - debug:
- var: update_vlan_check
-
- - assert:
- that:
- - update_vlan_check is changed
-
- - name: Update VLAN
- 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
-
- - debug:
- msg: '{{update_vlan}}'
-
- - assert:
- that:
- - update_vlan.data.appliance_ip == '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}}'
- 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
-
- - debug:
- msg: '{{update_vlan_idempotent}}'
-
- - assert:
- that:
- - update_vlan_idempotent.changed == False
- - update_vlan_idempotent.data is defined
-
- - name: Add IP assignments and reserved IP ranges
- 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
- - mac: "12:34:56:78:90:12"
- ip: 192.168.250.11
- name: another_fixed_ip
- reserved_ip_range:
- - start: 192.168.250.10
- end: 192.168.250.20
- comment: reserved_range
- - start: 192.168.250.100
- end: 192.168.250.120
- comment: reserved_range_high
- dns_nameservers: opendns
- delegate_to: localhost
- register: update_vlan_add_ip
-
- - debug:
- msg: '{{update_vlan_add_ip}}'
-
- - assert:
- that:
- - update_vlan_add_ip.changed == True
- - update_vlan_add_ip.data.fixed_ip_assignments | length == 2
- - update_vlan_add_ip.data.reserved_ip_ranges | length == 2
-
- - name: Remove IP assignments and reserved IP ranges
- 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_remove_ip
-
- - debug:
- msg: '{{update_vlan_remove_ip}}'
-
- - assert:
- that:
- - update_vlan_remove_ip.changed == True
- - update_vlan_remove_ip.data.fixed_ip_assignments | length == 1
- - update_vlan_remove_ip.data.reserved_ip_ranges | length == 1
-
- - name: Update VLAN with idempotency
- 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
-
- - debug:
- msg: '{{update_vlan_idempotent}}'
-
- - assert:
- that:
- - update_vlan_idempotent.changed == False
- - update_vlan_idempotent.data is defined
-
- - name: Update VLAN with list of DNS entries
- 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: 1.1.1.1;8.8.8.8
- delegate_to: localhost
- register: update_vlan_dns_list
-
- - debug:
- msg: '{{update_vlan_dns_list}}'
-
- - assert:
- that:
- - '"1.1.1.1" in update_vlan_dns_list.data.dns_nameservers'
- - update_vlan_dns_list.changed == True
-
- - name: Query all VLANs in network
- meraki_vlan:
- auth_key: '{{ auth_key }}'
- org_name: '{{test_org_name}}'
- net_name: '{{test_net_name}}'
- state: query
- delegate_to: localhost
- register: query_vlans
-
- - debug:
- msg: '{{query_vlans}}'
-
- - assert:
- that:
- - query_vlans.data | length >= 2
- - query_vlans.data.1.id == 2
- - query_vlans.changed == False
-
- - name: Query single VLAN
- meraki_vlan:
- auth_key: '{{ auth_key }}'
- org_name: '{{test_org_name}}'
- net_name: '{{test_net_name}}'
- vlan_id: 2
- state: query
- output_level: debug
- delegate_to: localhost
- register: query_vlan
-
- - debug:
- msg: '{{query_vlan}}'
-
- - assert:
- that:
- - query_vlan.data.id == 2
- - query_vlan.changed == False
-
- always:
- #############################################################################
- # 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}}'
- state: absent
- org_name: '{{test_org_name}}'
- net_name: '{{test_net_name}}'
- vlan_id: 2
- delegate_to: localhost
- register: delete_vlan
-
- - debug:
- msg: '{{delete_vlan}}'
-
- - name: Delete test network
- meraki_network:
- auth_key: '{{auth_key}}'
- state: absent
- org_name: '{{test_org_name}}'
- net_name: '{{test_net_name}}'
- delegate_to: localhost
diff --git a/test/integration/targets/meraki_webhook/aliases b/test/integration/targets/meraki_webhook/aliases
deleted file mode 100644
index ad7ccf7ada..0000000000
--- a/test/integration/targets/meraki_webhook/aliases
+++ /dev/null
@@ -1 +0,0 @@
-unsupported
diff --git a/test/integration/targets/meraki_webhook/tasks/main.yml b/test/integration/targets/meraki_webhook/tasks/main.yml
deleted file mode 100644
index f671fc9287..0000000000
--- a/test/integration/targets/meraki_webhook/tasks/main.yml
+++ /dev/null
@@ -1,7 +0,0 @@
-# Test code for the Meraki Webhooks 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: Run test cases
- include: tests.yml ansible_connection=local
diff --git a/test/integration/targets/meraki_webhook/tasks/tests.yml b/test/integration/targets/meraki_webhook/tasks/tests.yml
deleted file mode 100644
index c16caba0cc..0000000000
--- a/test/integration/targets/meraki_webhook/tasks/tests.yml
+++ /dev/null
@@ -1,273 +0,0 @@
-# Test code for the Meraki Webhook module
-# Copyright: (c) 2019, 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 test network
- meraki_network:
- auth_key: '{{auth_key}}'
- state: present
- org_name: '{{test_org_name}}'
- net_name: '{{test_net_name}}'
- type: appliance
-
- - name: Create webhook with check mode
- meraki_webhook:
- auth_key: '{{auth_key}}'
- state: present
- org_name: '{{test_org_name}}'
- net_name: '{{test_net_name}}'
- name: Test_Hook
- url: https://webhook.site/8eb5b76f-b167-4cb8-9fc4-42621b724244
- shared_secret: shhhdonttellanyone
- check_mode: yes
- register: create_one_check
-
- - debug:
- var: create_one_check
-
- - assert:
- that:
- - create_one_check is changed
- - create_one_check.data is defined
-
- - name: Create webhook
- meraki_webhook:
- auth_key: '{{auth_key}}'
- state: present
- org_name: '{{test_org_name}}'
- net_name: '{{test_net_name}}'
- name: Test_Hook
- url: https://webhook.site/8eb5b76f-b167-4cb8-9fc4-42621b724244
- shared_secret: shhhdonttellanyone
- register: create_one
-
- - debug:
- var: create_one
-
- - assert:
- that:
- - create_one is changed
- - create_one.data is defined
-
- - set_fact:
- webhook_id: '{{create_one.data.id}}'
-
- - name: Query one webhook
- meraki_webhook:
- auth_key: '{{auth_key}}'
- state: query
- org_name: '{{test_org_name}}'
- net_name: '{{test_net_name}}'
- name: Test_Hook
- register: query_one
-
- - debug:
- var: query_one
-
- - assert:
- that:
- - query_one.data is defined
-
- - name: Query one webhook with id
- meraki_webhook:
- auth_key: '{{auth_key}}'
- state: query
- org_name: '{{test_org_name}}'
- net_name: '{{test_net_name}}'
- webhook_id: '{{webhook_id}}'
- register: query_one_id
-
- - debug:
- var: query_one_id
-
- - assert:
- that:
- - query_one_id.data is defined
-
- - name: Update webhook with check mode
- meraki_webhook:
- auth_key: '{{auth_key}}'
- state: present
- org_name: '{{test_org_name}}'
- net_name: '{{test_net_name}}'
- name: Test_Hook
- url: https://webhook.site/8eb5b76f-b167-4cb8-9fc4-42621b724244
- shared_secret: shhhdonttellanyonehere
- check_mode: yes
- register: update_check
-
- - assert:
- that:
- - update_check is changed
- - update_check.data is defined
-
- - name: Update webhook
- meraki_webhook:
- auth_key: '{{auth_key}}'
- state: present
- org_name: '{{test_org_name}}'
- net_name: '{{test_net_name}}'
- name: Test_Hook
- url: https://webhook.site/8eb5b76f-b167-4cb8-9fc4-42621b724244
- shared_secret: shhhdonttellanyonehere
- register: update
-
- - debug:
- var: update
-
- - assert:
- that:
- - update is changed
- - update.data is defined
-
- - name: Update webhook with idempotency
- meraki_webhook:
- auth_key: '{{auth_key}}'
- state: present
- org_name: '{{test_org_name}}'
- net_name: '{{test_net_name}}'
- name: Test_Hook
- url: https://webhook.site/8eb5b76f-b167-4cb8-9fc4-42621b724244
- shared_secret: shhhdonttellanyonehere
- register: update_idempotent
-
- - debug:
- var: update_idempotent
-
- - assert:
- that:
- - update_idempotent is not changed
- - update_idempotent.data is defined
-
- - name: Update webhook with id
- meraki_webhook:
- auth_key: '{{auth_key}}'
- state: present
- org_name: '{{test_org_name}}'
- net_name: '{{test_net_name}}'
- webhook_id: '{{webhook_id}}'
- name: Test_Hook
- url: https://webhook.site/8eb5b76f-b167-4cb8-9fc4-42621b724244
- shared_secret: shhhdonttellanyonehereid
- register: update_id
-
- - debug:
- var: update_id
-
- - assert:
- that:
- - update_id is changed
- - update_id.data is defined
-
- - name: Test webhook
- meraki_webhook:
- auth_key: '{{auth_key}}'
- state: present
- org_name: '{{test_org_name}}'
- net_name: '{{test_net_name}}'
- test: test
- url: https://webhook.site/8eb5b76f-b167-4cb8-9fc4-42621b724244
- register: webhook_test
-
- - debug:
- var: webhook_test
-
- - set_fact:
- test_id: '{{webhook_test.data.id}}'
-
- - name: Get webhook status
- meraki_webhook:
- auth_key: '{{auth_key}}'
- state: present
- org_name: '{{test_org_name}}'
- net_name: '{{test_net_name}}'
- test: status
- test_id: '{{test_id}}'
- register: webhook_test_status
-
- - debug:
- var: webhook_test_status
-
- - assert:
- that:
- - webhook_test_status.data is defined
-
- - name: Query all webhooks
- meraki_webhook:
- auth_key: '{{auth_key}}'
- state: query
- org_name: '{{test_org_name}}'
- net_name: '{{test_net_name}}'
- register: query_all
-
- - debug:
- var: query_all
-
- - name: Delete webhook invalid webhook
- meraki_webhook:
- auth_key: '{{auth_key}}'
- state: absent
- org_name: '{{test_org_name}}'
- net_name: '{{test_net_name}}'
- name: Test_Hook_Invalid
- check_mode: yes
- register: delete_invalid
- ignore_errors: yes
-
- - debug:
- var: delete_invalid
-
- - assert:
- that:
- - 'delete_invalid.msg == "There is no webhook with the name Test_Hook_Invalid"'
-
- - name: Delete webhook in check mode
- meraki_webhook:
- auth_key: '{{auth_key}}'
- state: absent
- org_name: '{{test_org_name}}'
- net_name: '{{test_net_name}}'
- name: Test_Hook
- check_mode: yes
- register: delete_check
-
- - debug:
- var: delete_check
-
- - assert:
- that:
- - delete_check is changed
-
- - name: Delete webhook
- meraki_webhook:
- auth_key: '{{auth_key}}'
- state: absent
- org_name: '{{test_org_name}}'
- net_name: '{{test_net_name}}'
- name: Test_Hook
- register: delete
-
- - debug:
- var: delete
-
- - assert:
- that:
- - delete is changed
-
- always:
- #############################################################################
- # Tear down starts here
- #############################################################################
- - name: Delete test network
- meraki_network:
- auth_key: '{{auth_key}}'
- state: absent
- org_name: '{{test_org_name}}'
- net_name: '{{test_net_name}}'
diff --git a/test/sanity/ignore.txt b/test/sanity/ignore.txt
index 3543cd0fb2..bec92ee02d 100644
--- a/test/sanity/ignore.txt
+++ b/test/sanity/ignore.txt
@@ -100,8 +100,6 @@ lib/ansible/module_utils/network/junos/facts/legacy/base.py future-import-boiler
lib/ansible/module_utils/network/junos/facts/legacy/base.py metaclass-boilerplate
lib/ansible/module_utils/network/junos/junos.py future-import-boilerplate
lib/ansible/module_utils/network/junos/junos.py metaclass-boilerplate
-lib/ansible/module_utils/network/meraki/meraki.py future-import-boilerplate
-lib/ansible/module_utils/network/meraki/meraki.py metaclass-boilerplate
lib/ansible/module_utils/network/nxos/argspec/facts/facts.py future-import-boilerplate
lib/ansible/module_utils/network/nxos/argspec/facts/facts.py metaclass-boilerplate
lib/ansible/module_utils/network/nxos/facts/facts.py future-import-boilerplate
@@ -1960,42 +1958,6 @@ lib/ansible/modules/network/junos/junos_vrf.py validate-modules:missing-suboptio
lib/ansible/modules/network/junos/junos_vrf.py validate-modules:parameter-list-no-elements
lib/ansible/modules/network/junos/junos_vrf.py validate-modules:parameter-type-not-in-doc
lib/ansible/modules/network/junos/junos_vrf.py validate-modules:undocumented-parameter
-lib/ansible/modules/network/meraki/meraki_admin.py validate-modules:parameter-type-not-in-doc
-lib/ansible/modules/network/meraki/meraki_config_template.py validate-modules:parameter-type-not-in-doc
-lib/ansible/modules/network/meraki/meraki_content_filtering.py validate-modules:parameter-list-no-elements
-lib/ansible/modules/network/meraki/meraki_firewalled_services.py validate-modules:doc-elements-mismatch
-lib/ansible/modules/network/meraki/meraki_malware.py validate-modules:doc-elements-mismatch
-lib/ansible/modules/network/meraki/meraki_malware.py validate-modules:parameter-type-not-in-doc
-lib/ansible/modules/network/meraki/meraki_mr_l3_firewall.py validate-modules:doc-elements-mismatch
-lib/ansible/modules/network/meraki/meraki_mr_l3_firewall.py validate-modules:doc-type-does-not-match-spec
-lib/ansible/modules/network/meraki/meraki_mx_l3_firewall.py validate-modules:doc-elements-mismatch
-lib/ansible/modules/network/meraki/meraki_mx_l3_firewall.py validate-modules:parameter-type-not-in-doc
-lib/ansible/modules/network/meraki/meraki_mx_l7_firewall.py pylint:ansible-bad-function
-lib/ansible/modules/network/meraki/meraki_mx_l7_firewall.py validate-modules:doc-elements-mismatch
-lib/ansible/modules/network/meraki/meraki_mx_l7_firewall.py validate-modules:nonexistent-parameter-documented
-lib/ansible/modules/network/meraki/meraki_mx_l7_firewall.py validate-modules:parameter-list-no-elements
-lib/ansible/modules/network/meraki/meraki_mx_l7_firewall.py validate-modules:parameter-type-not-in-doc
-lib/ansible/modules/network/meraki/meraki_nat.py validate-modules:doc-elements-mismatch
-lib/ansible/modules/network/meraki/meraki_nat.py validate-modules:invalid-ansiblemodule-schema
-lib/ansible/modules/network/meraki/meraki_nat.py validate-modules:parameter-list-no-elements
-lib/ansible/modules/network/meraki/meraki_network.py validate-modules:parameter-list-no-elements
-lib/ansible/modules/network/meraki/meraki_network.py validate-modules:parameter-type-not-in-doc
-lib/ansible/modules/network/meraki/meraki_organization.py validate-modules:parameter-type-not-in-doc
-lib/ansible/modules/network/meraki/meraki_snmp.py validate-modules:invalid-ansiblemodule-schema
-lib/ansible/modules/network/meraki/meraki_snmp.py validate-modules:parameter-list-no-elements
-lib/ansible/modules/network/meraki/meraki_ssid.py validate-modules:doc-elements-mismatch
-lib/ansible/modules/network/meraki/meraki_ssid.py validate-modules:doc-required-mismatch
-lib/ansible/modules/network/meraki/meraki_ssid.py validate-modules:parameter-list-no-elements
-lib/ansible/modules/network/meraki/meraki_static_route.py validate-modules:doc-elements-mismatch
-lib/ansible/modules/network/meraki/meraki_switchport.py validate-modules:doc-required-mismatch
-lib/ansible/modules/network/meraki/meraki_switchport.py validate-modules:parameter-list-no-elements
-lib/ansible/modules/network/meraki/meraki_switchport.py validate-modules:parameter-type-not-in-doc
-lib/ansible/modules/network/meraki/meraki_syslog.py validate-modules:doc-elements-mismatch
-lib/ansible/modules/network/meraki/meraki_syslog.py validate-modules:parameter-list-no-elements
-lib/ansible/modules/network/meraki/meraki_vlan.py validate-modules:doc-elements-mismatch
-lib/ansible/modules/network/meraki/meraki_vlan.py validate-modules:missing-suboption-docs
-lib/ansible/modules/network/meraki/meraki_vlan.py validate-modules:parameter-type-not-in-doc
-lib/ansible/modules/network/meraki/meraki_vlan.py validate-modules:undocumented-parameter
lib/ansible/modules/network/nxos/_nxos_interface.py validate-modules:doc-choices-do-not-match-spec
lib/ansible/modules/network/nxos/_nxos_interface.py validate-modules:doc-default-does-not-match-spec
lib/ansible/modules/network/nxos/_nxos_interface.py validate-modules:doc-default-incompatible-type
@@ -2925,8 +2887,6 @@ lib/ansible/plugins/doc_fragments/inventory_cache.py future-import-boilerplate
lib/ansible/plugins/doc_fragments/inventory_cache.py metaclass-boilerplate
lib/ansible/plugins/doc_fragments/junos.py future-import-boilerplate
lib/ansible/plugins/doc_fragments/junos.py metaclass-boilerplate
-lib/ansible/plugins/doc_fragments/meraki.py future-import-boilerplate
-lib/ansible/plugins/doc_fragments/meraki.py metaclass-boilerplate
lib/ansible/plugins/doc_fragments/nxos.py future-import-boilerplate
lib/ansible/plugins/doc_fragments/nxos.py metaclass-boilerplate
lib/ansible/plugins/doc_fragments/openstack.py future-import-boilerplate
diff --git a/test/units/module_utils/network/meraki/fixtures/orgs.json b/test/units/module_utils/network/meraki/fixtures/orgs.json
deleted file mode 100644
index 087db0f244..0000000000
--- a/test/units/module_utils/network/meraki/fixtures/orgs.json
+++ /dev/null
@@ -1,6 +0,0 @@
-[
- {
- "id": 2930418,
- "name": "My organization"
- }
-] \ No newline at end of file
diff --git a/test/units/module_utils/network/meraki/test_meraki.py b/test/units/module_utils/network/meraki/test_meraki.py
deleted file mode 100644
index 62d0d42fb3..0000000000
--- a/test/units/module_utils/network/meraki/test_meraki.py
+++ /dev/null
@@ -1,160 +0,0 @@
-# -*- coding: utf-8 -*-
-
-# Copyright 2019 Kevin Breit <kevin.breit@kevinbreit.net>
-
-# This file is part of Ansible by Red Hat
-#
-# Ansible is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# Ansible is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with Ansible. If not, see <http://www.gnu.org/licenses/>.
-
-from __future__ import (absolute_import, division, print_function)
-__metaclass__ = type
-
-import json
-import os
-import pytest
-
-from units.compat import unittest, mock
-from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils.network.meraki.meraki import MerakiModule, meraki_argument_spec, HTTPError, RateLimitException
-from ansible.module_utils.six import PY2, PY3
-from ansible.module_utils._text import to_native, to_bytes
-from units.modules.utils import set_module_args
-
-fixture_path = os.path.join(os.path.dirname(__file__), 'fixtures')
-fixture_data = {}
-testcase_data = {
- "params": {'orgs': ['orgs.json'],
- }
-}
-
-
-def load_fixture(name):
- path = os.path.join(fixture_path, name)
-
- if path in fixture_data:
- return fixture_data[path]
-
- with open(path) as f:
- data = f.read()
-
- # try:
- data = json.loads(data)
- # except Exception:
- # pass
-
- fixture_data[path] = data
- return data
-
-
-@pytest.fixture(scope="module")
-def module():
- argument_spec = meraki_argument_spec()
- set_module_args({'auth_key': 'abc123',
- })
- module = AnsibleModule(argument_spec=argument_spec,
- supports_check_mode=False)
- return MerakiModule(module)
-
-
-def mocked_fetch_url(*args, **kwargs):
- print(args)
- if args[1] == 'https://api.meraki.com/api/v0/404':
- info = {'status': 404,
- 'msg': '404 - Page is missing',
- 'url': 'https://api.meraki.com/api/v0/404',
- }
- info['body'] = '404'
- elif args[1] == 'https://api.meraki.com/api/v0/429':
- info = {'status': 429,
- 'msg': '429 - Rate limit hit',
- 'url': 'https://api.meraki.com/api/v0/429',
- }
- info['body'] = '429'
- return (None, info)
-
-
-def mocked_fetch_url_rate_success(module, *args, **kwargs):
- if module.retry_count == 5:
- info = {'status': 200,
- 'url': 'https://api.meraki.com/api/organization',
- }
- resp = {'body': 'Succeeded'}
- else:
- info = {'status': 429,
- 'msg': '429 - Rate limit hit',
- 'url': 'https://api.meraki.com/api/v0/429',
- }
- info['body'] = '429'
- return (resp, info)
-
-
-def mocked_fail_json(*args, **kwargs):
- pass
-
-
-def mocked_sleep(*args, **kwargs):
- pass
-
-
-def test_fetch_url_404(module, mocker):
- url = '404'
- mocker.patch('ansible.module_utils.network.meraki.meraki.fetch_url', side_effect=mocked_fetch_url)
- mocker.patch('ansible.module_utils.network.meraki.meraki.MerakiModule.fail_json', side_effect=mocked_fail_json)
- with pytest.raises(HTTPError):
- data = module.request(url, method='GET')
- assert module.status == 404
-
-
-def test_fetch_url_429(module, mocker):
- url = '429'
- mocker.patch('ansible.module_utils.network.meraki.meraki.fetch_url', side_effect=mocked_fetch_url)
- mocker.patch('ansible.module_utils.network.meraki.meraki.MerakiModule.fail_json', side_effect=mocked_fail_json)
- mocker.patch('time.sleep', return_value=None)
- with pytest.raises(RateLimitException):
- data = module.request(url, method='GET')
- assert module.status == 429
-
-
-def test_fetch_url_429_success(module, mocker):
- url = '429'
- mocker.patch('ansible.module_utils.network.meraki.meraki.fetch_url', side_effect=mocked_fetch_url_rate_success)
- mocker.patch('ansible.module_utils.network.meraki.meraki.MerakiModule.fail_json', side_effect=mocked_fail_json)
- mocker.patch('time.sleep', return_value=None)
- # assert module.status == 200
-
-
-def test_define_protocol_https(module):
- module.params['use_https'] = True
- module.define_protocol()
- testdata = module.params['protocol']
- assert testdata == 'https'
-
-
-def test_define_protocol_http(module):
- module.params['use_https'] = False
- module.define_protocol()
- testdata = module.params['protocol']
- assert testdata == 'http'
-
-
-def test_is_org_valid_org_name(module):
- data = load_fixture('orgs.json')
- org_count = module.is_org_valid(data, org_name="My organization")
- assert org_count == 1
-
-
-def test_is_org_valid_org_id(module):
- data = load_fixture('orgs.json')
- org_count = module.is_org_valid(data, org_id=2930418)
- assert org_count == 1