diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-18 05:52:35 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-18 05:52:35 +0000 |
commit | 7fec0b69a082aaeec72fee0612766aa42f6b1b4d (patch) | |
tree | efb569b86ca4da888717f5433e757145fa322e08 /ansible_collections/cisco/meraki/plugins/action | |
parent | Releasing progress-linux version 7.7.0+dfsg-3~progress7.99u1. (diff) | |
download | ansible-7fec0b69a082aaeec72fee0612766aa42f6b1b4d.tar.xz ansible-7fec0b69a082aaeec72fee0612766aa42f6b1b4d.zip |
Merging upstream version 9.4.0+dfsg.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'ansible_collections/cisco/meraki/plugins/action')
429 files changed, 65575 insertions, 0 deletions
diff --git a/ansible_collections/cisco/meraki/plugins/action/administered_identities_me_info.py b/ansible_collections/cisco/meraki/plugins/action/administered_identities_me_info.py new file mode 100644 index 000000000..fac892d30 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/administered_identities_me_info.py @@ -0,0 +1,86 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_all(self, params): + new_object = {} + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="administered", + function='getAdministeredIdentitiesMe', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/devices.py b/ansible_collections/cisco/meraki/plugins/action/devices.py new file mode 100644 index 000000000..df0edfd10 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/devices.py @@ -0,0 +1,337 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or +# https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, + meraki_compare_equality, + get_dict_result, +) +from ansible_collections.cisco.meraki.plugins.plugin_utils.exceptions import ( + InconsistentParameters, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + state=dict(type="str", default="present", choices=["present"]), + name=dict(type="str"), + tags=dict(type="list"), + lat=dict(type="float"), + lng=dict(type="float"), + address=dict(type="str"), + notes=dict(type="str"), + moveMapMarker=dict(type="bool"), + switchProfileId=dict(type="str"), + floorPlanId=dict(type="str"), + mac=dict(type="str"), + serial=dict(type="str"), + organizationId=dict(type="str"), +)) + +required_if = [ + ("state", "present", ["name", "organizationId", "serial"], True), +] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class Devices(object): + def __init__(self, params, meraki): + self.meraki = meraki + self.new_object = dict( + name=params.get("name"), + tags=params.get("tags"), + lat=params.get("lat"), + lng=params.get("lng"), + address=params.get("address"), + notes=params.get("notes"), + moveMapMarker=params.get("moveMapMarker"), + switchProfileId=params.get("switchProfileId"), + floorPlanId=params.get("floorPlanId"), + mac=params.get("mac"), + serial=params.get("serial"), + organization_id=params.get("organizationId"), + ) + + def get_all_params(self, name=None, id=None): + new_object_params = {} + if self.new_object.get('perPage') is not None or self.new_object.get('per_page') is not None: + new_object_params['perPage'] = self.new_object.get('perPage') or \ + self.new_object.get('per_page') + new_object_params['total_pages'] = -1 + if self.new_object.get('startingAfter') is not None or self.new_object.get('starting_after') is not None: + new_object_params['startingAfter'] = self.new_object.get('startingAfter') or \ + self.new_object.get('starting_after') + if self.new_object.get('endingBefore') is not None or self.new_object.get('ending_before') is not None: + new_object_params['endingBefore'] = self.new_object.get('endingBefore') or \ + self.new_object.get('ending_before') + if self.new_object.get('configurationUpdatedAfter') is not None or self.new_object.get('configuration_updated_after') is not None: + new_object_params['configurationUpdatedAfter'] = self.new_object.get('configurationUpdatedAfter') or \ + self.new_object.get('configuration_updated_after') + if self.new_object.get('networkIds') is not None or self.new_object.get('network_ids') is not None: + new_object_params['networkIds'] = self.new_object.get('networkIds') or \ + self.new_object.get('network_ids') + if self.new_object.get('productTypes') is not None or self.new_object.get('product_types') is not None: + new_object_params['productTypes'] = self.new_object.get('productTypes') or \ + self.new_object.get('product_types') + if self.new_object.get('tags') is not None or self.new_object.get('tags') is not None: + new_object_params['tags'] = self.new_object.get('tags') + if self.new_object.get('tagsFilterType') is not None or self.new_object.get('tags_filter_type') is not None: + new_object_params['tagsFilterType'] = self.new_object.get('tagsFilterType') or \ + self.new_object.get('tags_filter_type') + new_object_params['name'] = name or self.new_object.get('name') + if self.new_object.get('mac') is not None or self.new_object.get('mac') is not None: + new_object_params['mac'] = self.new_object.get('mac') + if self.new_object.get('serial') is not None or self.new_object.get('serial') is not None: + new_object_params['serial'] = self.new_object.get('serial') + if self.new_object.get('model') is not None or self.new_object.get('model') is not None: + new_object_params['model'] = self.new_object.get('model') + if self.new_object.get('macs') is not None or self.new_object.get('macs') is not None: + new_object_params['macs'] = self.new_object.get('macs') + if self.new_object.get('serials') is not None or self.new_object.get('serials') is not None: + new_object_params['serials'] = self.new_object.get('serials') + if self.new_object.get('sensorMetrics') is not None or self.new_object.get('sensor_metrics') is not None: + new_object_params['sensorMetrics'] = self.new_object.get('sensorMetrics') or \ + self.new_object.get('sensor_metrics') + if self.new_object.get('sensorAlertProfileIds') is not None or self.new_object.get('sensor_alert_profile_ids') is not None: + new_object_params['sensorAlertProfileIds'] = self.new_object.get('sensorAlertProfileIds') or \ + self.new_object.get('sensor_alert_profile_ids') + if self.new_object.get('models') is not None or self.new_object.get('models') is not None: + new_object_params['models'] = self.new_object.get('models') + if self.new_object.get('organizationId') is not None or self.new_object.get('organization_id') is not None: + new_object_params['organizationId'] = self.new_object.get('organizationId') or \ + self.new_object.get('organization_id') + return new_object_params + + def get_params_by_id(self, name=None, id=None): + new_object_params = {} + if self.new_object.get('serial') is not None or self.new_object.get('serial') is not None: + new_object_params['serial'] = self.new_object.get('serial') + return new_object_params + + def update_by_id_params(self): + new_object_params = {} + if self.new_object.get('name') is not None or self.new_object.get('name') is not None: + new_object_params['name'] = self.new_object.get('name') or \ + self.new_object.get('name') + if self.new_object.get('tags') is not None or self.new_object.get('tags') is not None: + new_object_params['tags'] = self.new_object.get('tags') or \ + self.new_object.get('tags') + if self.new_object.get('lat') is not None or self.new_object.get('lat') is not None: + new_object_params['lat'] = self.new_object.get('lat') or \ + self.new_object.get('lat') + if self.new_object.get('lng') is not None or self.new_object.get('lng') is not None: + new_object_params['lng'] = self.new_object.get('lng') or \ + self.new_object.get('lng') + if self.new_object.get('address') is not None or self.new_object.get('address') is not None: + new_object_params['address'] = self.new_object.get('address') or \ + self.new_object.get('address') + if self.new_object.get('notes') is not None or self.new_object.get('notes') is not None: + new_object_params['notes'] = self.new_object.get('notes') or \ + self.new_object.get('notes') + if self.new_object.get('moveMapMarker') is not None or self.new_object.get('move_map_marker') is not None: + new_object_params['moveMapMarker'] = self.new_object.get( + 'moveMapMarker') + if self.new_object.get('switchProfileId') is not None or self.new_object.get('switch_profile_id') is not None: + new_object_params['switchProfileId'] = self.new_object.get('switchProfileId') or \ + self.new_object.get('switch_profile_id') + if self.new_object.get('floorPlanId') is not None or self.new_object.get('floor_plan_id') is not None: + new_object_params['floorPlanId'] = self.new_object.get('floorPlanId') or \ + self.new_object.get('floor_plan_id') + if self.new_object.get('mac') is not None or self.new_object.get('mac') is not None: + new_object_params['mac'] = self.new_object.get('mac') or \ + self.new_object.get('mac') + if self.new_object.get('serial') is not None or self.new_object.get('serial') is not None: + new_object_params['serial'] = self.new_object.get('serial') or \ + self.new_object.get('serial') + return new_object_params + + def get_object_by_name(self, name): + result = None + # NOTE: Does not have a get by name method, using get all + try: + items = self.meraki.exec_meraki( + family="organizations", + function="getOrganizationDevices", + params=self.get_all_params(name=name), + ) + if isinstance(items, dict): + if 'response' in items: + items = items.get('response') + result = get_dict_result(items, 'name', name) + if result is None: + result = items + except Exception as e: + print("Error: ", e) + result = None + return result + + def get_object_by_id(self, id): + result = None + try: + items = self.meraki.exec_meraki( + family="devices", + function="getDevice", + params=self.get_params_by_id() + ) + if isinstance(items, dict): + if 'response' in items: + items = items.get('response') + result = items + except Exception as e: + print("Error: ", e) + result = None + return result + + def exists(self): + prev_obj = None + id_exists = False + name_exists = False + o_id = self.new_object.get("id") + o_id = o_id or self.new_object.get( + "serial") or self.new_object.get("serial") + name = self.new_object.get("name") + orgID = self.new_object.get("organizationId") or self.new_object.get( + "organization_id") + print(name) + print(orgID) + if o_id: + prev_obj = self.get_object_by_id(o_id) + id_exists = prev_obj is not None and isinstance(prev_obj, dict) + if not id_exists and name and orgID: + prev_obj = self.get_object_by_name(name) + name_exists = prev_obj is not None and isinstance(prev_obj, dict) + if name_exists: + _id = prev_obj.get("id") + _id = _id or prev_obj.get("serial") + if id_exists and name_exists and o_id != _id: + raise InconsistentParameters( + "The 'id' and 'name' params don't refer to the same object") + if _id: + self.new_object.update(dict(id=_id)) + self.new_object.update(dict(serial=_id)) + if _id: + prev_obj = self.get_object_by_id(_id) + it_exists = prev_obj is not None and isinstance(prev_obj, dict) + return (it_exists, prev_obj) + + def requires_update(self, current_obj): + requested_obj = self.new_object + + obj_params = [ + ("name", "name"), + ("tags", "tags"), + ("lat", "lat"), + ("lng", "lng"), + ("address", "address"), + ("notes", "notes"), + ("moveMapMarker", "moveMapMarker"), + ("switchProfileId", "switchProfileId"), + ("floorPlanId", "floorPlanId"), + ("mac", "mac"), + ("serial", "serial"), + ("organizationId", "organizationId"), + ] + # Method 1. Params present in request (Ansible) obj are the same as the current (ISE) params + # If any does not have eq params, it requires update + return any(not meraki_compare_equality(current_obj.get(meraki_param), + requested_obj.get(ansible_param)) + for (meraki_param, ansible_param) in obj_params) + + def update(self): + id = self.new_object.get("id") + id = id or self.new_object.get("serial") + name = self.new_object.get("name") + result = None + if not id: + prev_obj_name = self.get_object_by_name(name) + id_ = None + if prev_obj_name: + id_ = prev_obj_name.get("id") + id_ = id_ or prev_obj_name.get("serial") + if id_: + self.new_object.update(dict(serial=id_)) + result = self.meraki.exec_meraki( + family="devices", + function="updateDevice", + params=self.update_by_id_params(), + op_modifies=True, + ) + return result + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = False + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + meraki = MERAKI(self._task.args) + obj = Devices(self._task.args, meraki) + + state = self._task.args.get("state") + + response = None + if state == "present": + (obj_exists, prev_obj) = obj.exists() + if obj_exists: + if obj.requires_update(prev_obj): + response = obj.update() + meraki.object_updated() + else: + response = prev_obj + meraki.object_already_present() + else: + meraki.fail_json( + "Object does not exists, plugin only has update") + + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/devices_appliance_performance_info.py b/ansible_collections/cisco/meraki/plugins/action/devices_appliance_performance_info.py new file mode 100644 index 000000000..495f8815a --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/devices_appliance_performance_info.py @@ -0,0 +1,90 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + serial=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_all(self, params): + new_object = {} + if params.get("serial") is not None: + new_object["serial"] = params.get( + "serial") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="appliance", + function='getDeviceAppliancePerformance', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/devices_appliance_uplinks_settings.py b/ansible_collections/cisco/meraki/plugins/action/devices_appliance_uplinks_settings.py new file mode 100644 index 000000000..83981ce8a --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/devices_appliance_uplinks_settings.py @@ -0,0 +1,199 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or +# https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, + meraki_compare_equality, + get_dict_result, +) +from ansible_collections.cisco.meraki.plugins.plugin_utils.exceptions import ( + InconsistentParameters, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + state=dict(type="str", default="present", choices=["present"]), + interfaces=dict(type="dict"), + serial=dict(type="str"), +)) + +required_if = [ + ("state", "present", ["serial"], True), +] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class DevicesApplianceUplinksSettings(object): + def __init__(self, params, meraki): + self.meraki = meraki + self.new_object = dict( + interfaces=params.get("interfaces"), + serial=params.get("serial"), + ) + + def get_all_params(self, name=None, id=None): + new_object_params = {} + if self.new_object.get('serial') is not None or self.new_object.get('serial') is not None: + new_object_params['serial'] = self.new_object.get('serial') + return new_object_params + + def update_all_params(self): + new_object_params = {} + if self.new_object.get('interfaces') is not None or self.new_object.get('interfaces') is not None: + new_object_params['interfaces'] = self.new_object.get('interfaces') or \ + self.new_object.get('interfaces') + if self.new_object.get('serial') is not None or self.new_object.get('serial') is not None: + new_object_params['serial'] = self.new_object.get('serial') or \ + self.new_object.get('serial') + return new_object_params + + def get_object_by_name(self, name): + result = None + # NOTE: Does not have a get by name method, using get all + try: + items = self.meraki.exec_meraki( + family="appliance", + function="getDeviceApplianceUplinksSettings", + params=self.get_all_params(name=name), + ) + if isinstance(items, dict): + if 'interfaces' in items: + items = items.get('interfaces') + result = get_dict_result(items, 'name', name) + if result is None: + result = items + except Exception as e: + print("Error: ", e) + result = None + return result + + def get_object_by_id(self, id): + result = None + # NOTE: Does not have a get by id method or it is in another action + return result + + def exists(self): + prev_obj = None + id_exists = False + name_exists = False + o_id = self.new_object.get("serial") + name = self.new_object.get("name") + if o_id: + prev_obj = self.get_object_by_name(o_id) + id_exists = prev_obj is not None and isinstance(prev_obj, dict) + if not id_exists and name: + prev_obj = self.get_object_by_name(name) + name_exists = prev_obj is not None and isinstance(prev_obj, dict) + if name_exists: + _id = prev_obj.get("id") + if id_exists and name_exists and o_id != _id: + raise InconsistentParameters( + "The 'id' and 'name' params don't refer to the same object") + if _id: + self.new_object.update(dict(id=_id)) + it_exists = prev_obj is not None and isinstance(prev_obj, dict) + return (it_exists, prev_obj) + + def requires_update(self, current_obj): + requested_obj = self.new_object + + obj_params = [ + ("interfaces", "interfaces"), + ("serial", "serial"), + ] + # Method 1. Params present in request (Ansible) obj are the same as the current (ISE) params + # If any does not have eq params, it requires update + return any(not meraki_compare_equality(current_obj.get(meraki_param), + requested_obj.get(ansible_param)) + for (meraki_param, ansible_param) in obj_params) + + def update(self): + id = self.new_object.get("id") + name = self.new_object.get("name") + result = None + result = self.meraki.exec_meraki( + family="appliance", + function="updateDeviceApplianceUplinksSettings", + params=self.update_all_params(), + op_modifies=True, + ) + return result + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = False + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + meraki = MERAKI(self._task.args) + obj = DevicesApplianceUplinksSettings(self._task.args, meraki) + + state = self._task.args.get("state") + + response = None + if state == "present": + (obj_exists, prev_obj) = obj.exists() + if obj_exists: + if obj.requires_update(prev_obj): + response = obj.update() + meraki.object_updated() + else: + response = prev_obj + meraki.object_already_present() + else: + meraki.fail_json( + "Object does not exists, plugin only has update") + + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/devices_appliance_uplinks_settings_info.py b/ansible_collections/cisco/meraki/plugins/action/devices_appliance_uplinks_settings_info.py new file mode 100644 index 000000000..e87b0a01e --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/devices_appliance_uplinks_settings_info.py @@ -0,0 +1,90 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + serial=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_all(self, params): + new_object = {} + if params.get("serial") is not None: + new_object["serial"] = params.get( + "serial") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="appliance", + function='getDeviceApplianceUplinksSettings', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/devices_appliance_vmx_authentication_token.py b/ansible_collections/cisco/meraki/plugins/action/devices_appliance_vmx_authentication_token.py new file mode 100644 index 000000000..47ef5b286 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/devices_appliance_vmx_authentication_token.py @@ -0,0 +1,87 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguements specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + serial=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = False + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_object(self, params): + new_object = dict( + serial=params.get("serial"), + ) + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="appliance", + function='createDeviceApplianceVmxAuthenticationToken', + op_modifies=True, + params=self.get_object(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/devices_blink_leds.py b/ansible_collections/cisco/meraki/plugins/action/devices_blink_leds.py new file mode 100644 index 000000000..d6e157172 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/devices_blink_leds.py @@ -0,0 +1,93 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguements specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + duration=dict(type="int"), + period=dict(type="int"), + duty=dict(type="int"), + serial=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = False + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_object(self, params): + new_object = dict( + duration=params.get("duration"), + period=params.get("period"), + duty=params.get("duty"), + serial=params.get("serial"), + ) + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="devices", + function='blinkDeviceLeds', + op_modifies=True, + params=self.get_object(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/devices_camera_analytics_live_info.py b/ansible_collections/cisco/meraki/plugins/action/devices_camera_analytics_live_info.py new file mode 100644 index 000000000..acece637a --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/devices_camera_analytics_live_info.py @@ -0,0 +1,90 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + serial=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_all(self, params): + new_object = {} + if params.get("serial") is not None: + new_object["serial"] = params.get( + "serial") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="camera", + function='getDeviceCameraAnalyticsLive', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/devices_camera_custom_analytics.py b/ansible_collections/cisco/meraki/plugins/action/devices_camera_custom_analytics.py new file mode 100644 index 000000000..92f3aa3ae --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/devices_camera_custom_analytics.py @@ -0,0 +1,210 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or +# https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, + meraki_compare_equality, + get_dict_result, +) +from ansible_collections.cisco.meraki.plugins.plugin_utils.exceptions import ( + InconsistentParameters, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + state=dict(type="str", default="present", choices=["present"]), + enabled=dict(type="bool"), + artifactId=dict(type="str"), + parameters=dict(type="list"), + serial=dict(type="str"), +)) + +required_if = [ + ("state", "present", ["serial"], True), +] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class DevicesCameraCustomAnalytics(object): + def __init__(self, params, meraki): + self.meraki = meraki + self.new_object = dict( + enabled=params.get("enabled"), + artifactId=params.get("artifactId"), + parameters=params.get("parameters"), + serial=params.get("serial"), + ) + + def get_all_params(self, name=None, id=None): + new_object_params = {} + if self.new_object.get('serial') is not None or self.new_object.get('serial') is not None: + new_object_params['serial'] = self.new_object.get('serial') + return new_object_params + + def update_all_params(self): + new_object_params = {} + if self.new_object.get('enabled') is not None or self.new_object.get('enabled') is not None: + new_object_params['enabled'] = self.new_object.get('enabled') + if self.new_object.get('artifactId') is not None or self.new_object.get('artifact_id') is not None: + new_object_params['artifactId'] = self.new_object.get('artifactId') or \ + self.new_object.get('artifact_id') + if self.new_object.get('parameters') is not None or self.new_object.get('parameters') is not None: + new_object_params['parameters'] = self.new_object.get('parameters') or \ + self.new_object.get('parameters') + if self.new_object.get('serial') is not None or self.new_object.get('serial') is not None: + new_object_params['serial'] = self.new_object.get('serial') or \ + self.new_object.get('serial') + return new_object_params + + def get_object_by_name(self, name): + result = None + # NOTE: Does not have a get by name method, using get all + try: + items = self.meraki.exec_meraki( + family="camera", + function="getDeviceCameraCustomAnalytics", + params=self.get_all_params(name=name), + ) + if isinstance(items, dict): + if 'response' in items: + items = items.get('response') + result = get_dict_result(items, 'name', name) + if result is None: + result = items + except Exception as e: + print("Error: ", e) + result = None + return result + + def get_object_by_id(self, id): + result = None + # NOTE: Does not have a get by id method or it is in another action + return result + + def exists(self): + prev_obj = None + id_exists = False + name_exists = False + o_id = self.new_object.get("serial") + name = self.new_object.get("name") + if o_id: + prev_obj = self.get_object_by_name(o_id) + id_exists = prev_obj is not None and isinstance(prev_obj, dict) + if not id_exists and name: + prev_obj = self.get_object_by_name(name) + name_exists = prev_obj is not None and isinstance(prev_obj, dict) + if name_exists: + _id = prev_obj.get("id") + if id_exists and name_exists and o_id != _id: + raise InconsistentParameters( + "The 'id' and 'name' params don't refer to the same object") + if _id: + self.new_object.update(dict(id=_id)) + it_exists = prev_obj is not None and isinstance(prev_obj, dict) + return (it_exists, prev_obj) + + def requires_update(self, current_obj): + requested_obj = self.new_object + + obj_params = [ + ("enabled", "enabled"), + ("artifactId", "artifactId"), + ("parameters", "parameters"), + ("serial", "serial"), + ] + # Method 1. Params present in request (Ansible) obj are the same as the current (ISE) params + # If any does not have eq params, it requires update + return any(not meraki_compare_equality(current_obj.get(meraki_param), + requested_obj.get(ansible_param)) + for (meraki_param, ansible_param) in obj_params) + + def update(self): + id = self.new_object.get("id") + name = self.new_object.get("name") + result = None + result = self.meraki.exec_meraki( + family="camera", + function="updateDeviceCameraCustomAnalytics", + params=self.update_all_params(), + op_modifies=True, + ) + return result + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = False + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + meraki = MERAKI(self._task.args) + obj = DevicesCameraCustomAnalytics(self._task.args, meraki) + + state = self._task.args.get("state") + + response = None + if state == "present": + (obj_exists, prev_obj) = obj.exists() + if obj_exists: + if obj.requires_update(prev_obj): + response = obj.update() + meraki.object_updated() + else: + response = prev_obj + meraki.object_already_present() + else: + meraki.fail_json( + "Object does not exists, plugin only has update") + + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/devices_camera_custom_analytics_info.py b/ansible_collections/cisco/meraki/plugins/action/devices_camera_custom_analytics_info.py new file mode 100644 index 000000000..f9f5e3568 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/devices_camera_custom_analytics_info.py @@ -0,0 +1,90 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + serial=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_all(self, params): + new_object = {} + if params.get("serial") is not None: + new_object["serial"] = params.get( + "serial") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="camera", + function='getDeviceCameraCustomAnalytics', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/devices_camera_generate_snapshot.py b/ansible_collections/cisco/meraki/plugins/action/devices_camera_generate_snapshot.py new file mode 100644 index 000000000..8b7e68487 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/devices_camera_generate_snapshot.py @@ -0,0 +1,91 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguements specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + timestamp=dict(type="str"), + fullframe=dict(type="bool"), + serial=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = False + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_object(self, params): + new_object = dict( + timestamp=params.get("timestamp"), + fullframe=params.get("fullframe"), + serial=params.get("serial"), + ) + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="camera", + function='generateDeviceCameraSnapshot', + op_modifies=True, + params=self.get_object(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/devices_camera_quality_and_retention.py b/ansible_collections/cisco/meraki/plugins/action/devices_camera_quality_and_retention.py new file mode 100644 index 000000000..b7781783a --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/devices_camera_quality_and_retention.py @@ -0,0 +1,232 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or +# https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, + meraki_compare_equality, + get_dict_result, +) +from ansible_collections.cisco.meraki.plugins.plugin_utils.exceptions import ( + InconsistentParameters, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + state=dict(type="str", default="present", choices=["present"]), + profileId=dict(type="str"), + motionBasedRetentionEnabled=dict(type="bool"), + audioRecordingEnabled=dict(type="bool"), + restrictedBandwidthModeEnabled=dict(type="bool"), + quality=dict(type="str"), + resolution=dict(type="str"), + motionDetectorVersion=dict(type="int"), + serial=dict(type="str"), +)) + +required_if = [ + ("state", "present", ["serial"], True), +] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class DevicesCameraQualityAndRetention(object): + def __init__(self, params, meraki): + self.meraki = meraki + self.new_object = dict( + profileId=params.get("profileId"), + motionBasedRetentionEnabled=params.get("motionBasedRetentionEnabled"), + audioRecordingEnabled=params.get("audioRecordingEnabled"), + restrictedBandwidthModeEnabled=params.get("restrictedBandwidthModeEnabled"), + quality=params.get("quality"), + resolution=params.get("resolution"), + motionDetectorVersion=params.get("motionDetectorVersion"), + serial=params.get("serial"), + ) + + def get_all_params(self, name=None, id=None): + new_object_params = {} + if self.new_object.get('serial') is not None or self.new_object.get('serial') is not None: + new_object_params['serial'] = self.new_object.get('serial') + return new_object_params + + def update_all_params(self): + new_object_params = {} + if self.new_object.get('profileId') is not None or self.new_object.get('profile_id') is not None: + new_object_params['profileId'] = self.new_object.get('profileId') or \ + self.new_object.get('profile_id') + if self.new_object.get('motionBasedRetentionEnabled') is not None or self.new_object.get('motion_based_retention_enabled') is not None: + new_object_params['motionBasedRetentionEnabled'] = self.new_object.get('motionBasedRetentionEnabled') + if self.new_object.get('audioRecordingEnabled') is not None or self.new_object.get('audio_recording_enabled') is not None: + new_object_params['audioRecordingEnabled'] = self.new_object.get('audioRecordingEnabled') + if self.new_object.get('restrictedBandwidthModeEnabled') is not None or self.new_object.get('restricted_bandwidth_mode_enabled') is not None: + new_object_params['restrictedBandwidthModeEnabled'] = self.new_object.get('restrictedBandwidthModeEnabled') + if self.new_object.get('quality') is not None or self.new_object.get('quality') is not None: + new_object_params['quality'] = self.new_object.get('quality') or \ + self.new_object.get('quality') + if self.new_object.get('resolution') is not None or self.new_object.get('resolution') is not None: + new_object_params['resolution'] = self.new_object.get('resolution') or \ + self.new_object.get('resolution') + if self.new_object.get('motionDetectorVersion') is not None or self.new_object.get('motion_detector_version') is not None: + new_object_params['motionDetectorVersion'] = self.new_object.get('motionDetectorVersion') or \ + self.new_object.get('motion_detector_version') + if self.new_object.get('serial') is not None or self.new_object.get('serial') is not None: + new_object_params['serial'] = self.new_object.get('serial') or \ + self.new_object.get('serial') + return new_object_params + + def get_object_by_name(self, name): + result = None + # NOTE: Does not have a get by name method, using get all + try: + items = self.meraki.exec_meraki( + family="camera", + function="getDeviceCameraQualityAndRetention", + params=self.get_all_params(name=name), + ) + if isinstance(items, dict): + if 'response' in items: + items = items.get('response') + result = get_dict_result(items, 'name', name) + if result is None: + result = items + except Exception as e: + print("Error: ", e) + result = None + return result + + def get_object_by_id(self, id): + result = None + # NOTE: Does not have a get by id method or it is in another action + return result + + def exists(self): + prev_obj = None + id_exists = False + name_exists = False + o_id = self.new_object.get("serial") + name = self.new_object.get("name") + if o_id: + prev_obj = self.get_object_by_name(o_id) + id_exists = prev_obj is not None and isinstance(prev_obj, dict) + if not id_exists and name: + prev_obj = self.get_object_by_name(name) + name_exists = prev_obj is not None and isinstance(prev_obj, dict) + if name_exists: + _id = prev_obj.get("id") + if id_exists and name_exists and o_id != _id: + raise InconsistentParameters( + "The 'id' and 'name' params don't refer to the same object") + if _id: + self.new_object.update(dict(id=_id)) + it_exists = prev_obj is not None and isinstance(prev_obj, dict) + return (it_exists, prev_obj) + + def requires_update(self, current_obj): + requested_obj = self.new_object + + obj_params = [ + ("profileId", "profileId"), + ("motionBasedRetentionEnabled", "motionBasedRetentionEnabled"), + ("audioRecordingEnabled", "audioRecordingEnabled"), + ("restrictedBandwidthModeEnabled", "restrictedBandwidthModeEnabled"), + ("quality", "quality"), + ("resolution", "resolution"), + ("motionDetectorVersion", "motionDetectorVersion"), + ("serial", "serial"), + ] + # Method 1. Params present in request (Ansible) obj are the same as the current (ISE) params + # If any does not have eq params, it requires update + return any(not meraki_compare_equality(current_obj.get(meraki_param), + requested_obj.get(ansible_param)) + for (meraki_param, ansible_param) in obj_params) + + def update(self): + id = self.new_object.get("id") + name = self.new_object.get("name") + result = None + result = self.meraki.exec_meraki( + family="camera", + function="updateDeviceCameraQualityAndRetention", + params=self.update_all_params(), + op_modifies=True, + ) + return result + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = False + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + meraki = MERAKI(self._task.args) + obj = DevicesCameraQualityAndRetention(self._task.args, meraki) + + state = self._task.args.get("state") + + response = None + if state == "present": + (obj_exists, prev_obj) = obj.exists() + if obj_exists: + if obj.requires_update(prev_obj): + response = obj.update() + meraki.object_updated() + else: + response = prev_obj + meraki.object_already_present() + else: + meraki.fail_json( + "Object does not exists, plugin only has update") + + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/devices_camera_quality_and_retention_info.py b/ansible_collections/cisco/meraki/plugins/action/devices_camera_quality_and_retention_info.py new file mode 100644 index 000000000..bd72aab12 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/devices_camera_quality_and_retention_info.py @@ -0,0 +1,90 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + serial=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_all(self, params): + new_object = {} + if params.get("serial") is not None: + new_object["serial"] = params.get( + "serial") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="camera", + function='getDeviceCameraQualityAndRetention', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/devices_camera_sense.py b/ansible_collections/cisco/meraki/plugins/action/devices_camera_sense.py new file mode 100644 index 000000000..3cc8dca92 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/devices_camera_sense.py @@ -0,0 +1,216 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or +# https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, + meraki_compare_equality, + get_dict_result, +) +from ansible_collections.cisco.meraki.plugins.plugin_utils.exceptions import ( + InconsistentParameters, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + state=dict(type="str", default="present", choices=["present"]), + senseEnabled=dict(type="bool"), + mqttBrokerId=dict(type="str"), + audioDetection=dict(type="dict"), + detectionModelId=dict(type="str"), + serial=dict(type="str"), +)) + +required_if = [ + ("state", "present", ["serial"], True), +] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class DevicesCameraSense(object): + def __init__(self, params, meraki): + self.meraki = meraki + self.new_object = dict( + senseEnabled=params.get("senseEnabled"), + mqttBrokerId=params.get("mqttBrokerId"), + audioDetection=params.get("audioDetection"), + detectionModelId=params.get("detectionModelId"), + serial=params.get("serial"), + ) + + def get_all_params(self, name=None, id=None): + new_object_params = {} + if self.new_object.get('serial') is not None or self.new_object.get('serial') is not None: + new_object_params['serial'] = self.new_object.get('serial') + return new_object_params + + def update_all_params(self): + new_object_params = {} + if self.new_object.get('senseEnabled') is not None or self.new_object.get('sense_enabled') is not None: + new_object_params['senseEnabled'] = self.new_object.get('senseEnabled') + if self.new_object.get('mqttBrokerId') is not None or self.new_object.get('mqtt_broker_id') is not None: + new_object_params['mqttBrokerId'] = self.new_object.get('mqttBrokerId') or \ + self.new_object.get('mqtt_broker_id') + if self.new_object.get('audioDetection') is not None or self.new_object.get('audio_detection') is not None: + new_object_params['audioDetection'] = self.new_object.get('audioDetection') or \ + self.new_object.get('audio_detection') + if self.new_object.get('detectionModelId') is not None or self.new_object.get('detection_model_id') is not None: + new_object_params['detectionModelId'] = self.new_object.get('detectionModelId') or \ + self.new_object.get('detection_model_id') + if self.new_object.get('serial') is not None or self.new_object.get('serial') is not None: + new_object_params['serial'] = self.new_object.get('serial') or \ + self.new_object.get('serial') + return new_object_params + + def get_object_by_name(self, name): + result = None + # NOTE: Does not have a get by name method, using get all + try: + items = self.meraki.exec_meraki( + family="camera", + function="getDeviceCameraSense", + params=self.get_all_params(name=name), + ) + if isinstance(items, dict): + if 'response' in items: + items = items.get('response') + result = get_dict_result(items, 'name', name) + if result is None: + result = items + except Exception as e: + print("Error: ", e) + result = None + return result + + def get_object_by_id(self, id): + result = None + # NOTE: Does not have a get by id method or it is in another action + return result + + def exists(self): + prev_obj = None + id_exists = False + name_exists = False + o_id = self.new_object.get("serial") + name = self.new_object.get("name") + if o_id: + prev_obj = self.get_object_by_name(o_id) + id_exists = prev_obj is not None and isinstance(prev_obj, dict) + if not id_exists and name: + prev_obj = self.get_object_by_name(name) + name_exists = prev_obj is not None and isinstance(prev_obj, dict) + if name_exists: + _id = prev_obj.get("id") + if id_exists and name_exists and o_id != _id: + raise InconsistentParameters( + "The 'id' and 'name' params don't refer to the same object") + if _id: + self.new_object.update(dict(id=_id)) + it_exists = prev_obj is not None and isinstance(prev_obj, dict) + return (it_exists, prev_obj) + + def requires_update(self, current_obj): + requested_obj = self.new_object + + obj_params = [ + ("senseEnabled", "senseEnabled"), + ("mqttBrokerId", "mqttBrokerId"), + ("audioDetection", "audioDetection"), + ("detectionModelId", "detectionModelId"), + ("serial", "serial"), + ] + # Method 1. Params present in request (Ansible) obj are the same as the current (ISE) params + # If any does not have eq params, it requires update + return any(not meraki_compare_equality(current_obj.get(meraki_param), + requested_obj.get(ansible_param)) + for (meraki_param, ansible_param) in obj_params) + + def update(self): + id = self.new_object.get("id") + name = self.new_object.get("name") + result = None + result = self.meraki.exec_meraki( + family="camera", + function="updateDeviceCameraSense", + params=self.update_all_params(), + op_modifies=True, + ) + return result + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = False + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + meraki = MERAKI(self._task.args) + obj = DevicesCameraSense(self._task.args, meraki) + + state = self._task.args.get("state") + + response = None + if state == "present": + (obj_exists, prev_obj) = obj.exists() + if obj_exists: + if obj.requires_update(prev_obj): + response = obj.update() + meraki.object_updated() + else: + response = prev_obj + meraki.object_already_present() + else: + meraki.fail_json( + "Object does not exists, plugin only has update") + + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/devices_camera_sense_info.py b/ansible_collections/cisco/meraki/plugins/action/devices_camera_sense_info.py new file mode 100644 index 000000000..3feb07476 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/devices_camera_sense_info.py @@ -0,0 +1,90 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + serial=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_all(self, params): + new_object = {} + if params.get("serial") is not None: + new_object["serial"] = params.get( + "serial") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="camera", + function='getDeviceCameraSense', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/devices_camera_video_link_info.py b/ansible_collections/cisco/meraki/plugins/action/devices_camera_video_link_info.py new file mode 100644 index 000000000..a989e3b6f --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/devices_camera_video_link_info.py @@ -0,0 +1,94 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + serial=dict(type="str"), + timestamp=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_all(self, params): + new_object = {} + if params.get("serial") is not None: + new_object["serial"] = params.get( + "serial") + if params.get("timestamp") is not None: + new_object["timestamp"] = params.get( + "timestamp") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="camera", + function='getDeviceCameraVideoLink', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/devices_camera_video_settings.py b/ansible_collections/cisco/meraki/plugins/action/devices_camera_video_settings.py new file mode 100644 index 000000000..fdaddfba7 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/devices_camera_video_settings.py @@ -0,0 +1,198 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or +# https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, + meraki_compare_equality, + get_dict_result, +) +from ansible_collections.cisco.meraki.plugins.plugin_utils.exceptions import ( + InconsistentParameters, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + state=dict(type="str", default="present", choices=["present"]), + externalRtspEnabled=dict(type="bool"), + serial=dict(type="str"), +)) + +required_if = [ + ("state", "present", ["serial"], True), +] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class DevicesCameraVideoSettings(object): + def __init__(self, params, meraki): + self.meraki = meraki + self.new_object = dict( + externalRtspEnabled=params.get("externalRtspEnabled"), + serial=params.get("serial"), + ) + + def get_all_params(self, name=None, id=None): + new_object_params = {} + if self.new_object.get('serial') is not None or self.new_object.get('serial') is not None: + new_object_params['serial'] = self.new_object.get('serial') + return new_object_params + + def update_all_params(self): + new_object_params = {} + if self.new_object.get('externalRtspEnabled') is not None or self.new_object.get('external_rtsp_enabled') is not None: + new_object_params['externalRtspEnabled'] = self.new_object.get('externalRtspEnabled') + if self.new_object.get('serial') is not None or self.new_object.get('serial') is not None: + new_object_params['serial'] = self.new_object.get('serial') or \ + self.new_object.get('serial') + return new_object_params + + def get_object_by_name(self, name): + result = None + # NOTE: Does not have a get by name method, using get all + try: + items = self.meraki.exec_meraki( + family="camera", + function="getDeviceCameraVideoSettings", + params=self.get_all_params(name=name), + ) + if isinstance(items, dict): + if 'response' in items: + items = items.get('response') + result = get_dict_result(items, 'name', name) + if result is None: + result = items + except Exception as e: + print("Error: ", e) + result = None + return result + + def get_object_by_id(self, id): + result = None + # NOTE: Does not have a get by id method or it is in another action + return result + + def exists(self): + prev_obj = None + id_exists = False + name_exists = False + o_id = self.new_object.get("serial") + name = self.new_object.get("name") + if o_id: + prev_obj = self.get_object_by_name(o_id) + id_exists = prev_obj is not None and isinstance(prev_obj, dict) + if not id_exists and name: + prev_obj = self.get_object_by_name(name) + name_exists = prev_obj is not None and isinstance(prev_obj, dict) + if name_exists: + _id = prev_obj.get("id") + if id_exists and name_exists and o_id != _id: + raise InconsistentParameters( + "The 'id' and 'name' params don't refer to the same object") + if _id: + self.new_object.update(dict(id=_id)) + it_exists = prev_obj is not None and isinstance(prev_obj, dict) + return (it_exists, prev_obj) + + def requires_update(self, current_obj): + requested_obj = self.new_object + + obj_params = [ + ("externalRtspEnabled", "externalRtspEnabled"), + ("serial", "serial"), + ] + # Method 1. Params present in request (Ansible) obj are the same as the current (ISE) params + # If any does not have eq params, it requires update + return any(not meraki_compare_equality(current_obj.get(meraki_param), + requested_obj.get(ansible_param)) + for (meraki_param, ansible_param) in obj_params) + + def update(self): + id = self.new_object.get("id") + name = self.new_object.get("name") + result = None + result = self.meraki.exec_meraki( + family="camera", + function="updateDeviceCameraVideoSettings", + params=self.update_all_params(), + op_modifies=True, + ) + return result + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = False + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + meraki = MERAKI(self._task.args) + obj = DevicesCameraVideoSettings(self._task.args, meraki) + + state = self._task.args.get("state") + + response = None + if state == "present": + (obj_exists, prev_obj) = obj.exists() + if obj_exists: + if obj.requires_update(prev_obj): + response = obj.update() + meraki.object_updated() + else: + response = prev_obj + meraki.object_already_present() + else: + meraki.fail_json( + "Object does not exists, plugin only has update") + + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/devices_camera_video_settings_info.py b/ansible_collections/cisco/meraki/plugins/action/devices_camera_video_settings_info.py new file mode 100644 index 000000000..8f276bd0d --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/devices_camera_video_settings_info.py @@ -0,0 +1,90 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + serial=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_all(self, params): + new_object = {} + if params.get("serial") is not None: + new_object["serial"] = params.get( + "serial") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="camera", + function='getDeviceCameraVideoSettings', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/devices_camera_wireless_profiles.py b/ansible_collections/cisco/meraki/plugins/action/devices_camera_wireless_profiles.py new file mode 100644 index 000000000..8153293df --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/devices_camera_wireless_profiles.py @@ -0,0 +1,199 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or +# https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, + meraki_compare_equality, + get_dict_result, +) +from ansible_collections.cisco.meraki.plugins.plugin_utils.exceptions import ( + InconsistentParameters, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + state=dict(type="str", default="present", choices=["present"]), + ids=dict(type="dict"), + serial=dict(type="str"), +)) + +required_if = [ + ("state", "present", ["serial"], True), +] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class DevicesCameraWirelessProfiles(object): + def __init__(self, params, meraki): + self.meraki = meraki + self.new_object = dict( + ids=params.get("ids"), + serial=params.get("serial"), + ) + + def get_all_params(self, name=None, id=None): + new_object_params = {} + if self.new_object.get('serial') is not None or self.new_object.get('serial') is not None: + new_object_params['serial'] = self.new_object.get('serial') + return new_object_params + + def update_all_params(self): + new_object_params = {} + if self.new_object.get('ids') is not None or self.new_object.get('ids') is not None: + new_object_params['ids'] = self.new_object.get('ids') or \ + self.new_object.get('ids') + if self.new_object.get('serial') is not None or self.new_object.get('serial') is not None: + new_object_params['serial'] = self.new_object.get('serial') or \ + self.new_object.get('serial') + return new_object_params + + def get_object_by_name(self, name): + result = None + # NOTE: Does not have a get by name method, using get all + try: + items = self.meraki.exec_meraki( + family="camera", + function="getDeviceCameraWirelessProfiles", + params=self.get_all_params(name=name), + ) + if isinstance(items, dict): + if 'response' in items: + items = items.get('response') + result = get_dict_result(items, 'name', name) + if result is None: + result = items + except Exception as e: + print("Error: ", e) + result = None + return result + + def get_object_by_id(self, id): + result = None + # NOTE: Does not have a get by id method or it is in another action + return result + + def exists(self): + prev_obj = None + id_exists = False + name_exists = False + o_id = self.new_object.get("serial") + name = self.new_object.get("name") + if o_id: + prev_obj = self.get_object_by_name(o_id) + id_exists = prev_obj is not None and isinstance(prev_obj, dict) + if not id_exists and name: + prev_obj = self.get_object_by_name(name) + name_exists = prev_obj is not None and isinstance(prev_obj, dict) + if name_exists: + _id = prev_obj.get("id") + if id_exists and name_exists and o_id != _id: + raise InconsistentParameters( + "The 'id' and 'name' params don't refer to the same object") + if _id: + self.new_object.update(dict(id=_id)) + it_exists = prev_obj is not None and isinstance(prev_obj, dict) + return (it_exists, prev_obj) + + def requires_update(self, current_obj): + requested_obj = self.new_object + + obj_params = [ + ("ids", "ids"), + ("serial", "serial"), + ] + # Method 1. Params present in request (Ansible) obj are the same as the current (ISE) params + # If any does not have eq params, it requires update + return any(not meraki_compare_equality(current_obj.get(meraki_param), + requested_obj.get(ansible_param)) + for (meraki_param, ansible_param) in obj_params) + + def update(self): + id = self.new_object.get("id") + name = self.new_object.get("name") + result = None + result = self.meraki.exec_meraki( + family="camera", + function="updateDeviceCameraWirelessProfiles", + params=self.update_all_params(), + op_modifies=True, + ) + return result + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = False + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + meraki = MERAKI(self._task.args) + obj = DevicesCameraWirelessProfiles(self._task.args, meraki) + + state = self._task.args.get("state") + + response = None + if state == "present": + (obj_exists, prev_obj) = obj.exists() + if obj_exists: + if obj.requires_update(prev_obj): + response = obj.update() + meraki.object_updated() + else: + response = prev_obj + meraki.object_already_present() + else: + meraki.fail_json( + "Object does not exists, plugin only has update") + + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/devices_camera_wireless_profiles_info.py b/ansible_collections/cisco/meraki/plugins/action/devices_camera_wireless_profiles_info.py new file mode 100644 index 000000000..aba6b034a --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/devices_camera_wireless_profiles_info.py @@ -0,0 +1,90 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + serial=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_all(self, params): + new_object = {} + if params.get("serial") is not None: + new_object["serial"] = params.get( + "serial") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="camera", + function='getDeviceCameraWirelessProfiles', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/devices_cellular_gateway_lan.py b/ansible_collections/cisco/meraki/plugins/action/devices_cellular_gateway_lan.py new file mode 100644 index 000000000..ddb0b4d97 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/devices_cellular_gateway_lan.py @@ -0,0 +1,205 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or +# https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, + meraki_compare_equality, + get_dict_result, +) +from ansible_collections.cisco.meraki.plugins.plugin_utils.exceptions import ( + InconsistentParameters, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + state=dict(type="str", default="present", choices=["present"]), + reservedIpRanges=dict(type="list"), + fixedIpAssignments=dict(type="list"), + serial=dict(type="str"), +)) + +required_if = [ + ("state", "present", ["serial"], True), +] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class DevicesCellularGatewayLan(object): + def __init__(self, params, meraki): + self.meraki = meraki + self.new_object = dict( + reservedIpRanges=params.get("reservedIpRanges"), + fixedIpAssignments=params.get("fixedIpAssignments"), + serial=params.get("serial"), + ) + + def get_all_params(self, name=None, id=None): + new_object_params = {} + if self.new_object.get('serial') is not None or self.new_object.get('serial') is not None: + new_object_params['serial'] = self.new_object.get('serial') + return new_object_params + + def update_all_params(self): + new_object_params = {} + if self.new_object.get('reservedIpRanges') is not None or self.new_object.get('reserved_ip_ranges') is not None: + new_object_params['reservedIpRanges'] = self.new_object.get('reservedIpRanges') or \ + self.new_object.get('reserved_ip_ranges') + if self.new_object.get('fixedIpAssignments') is not None or self.new_object.get('fixed_ip_assignments') is not None: + new_object_params['fixedIpAssignments'] = self.new_object.get('fixedIpAssignments') or \ + self.new_object.get('fixed_ip_assignments') + if self.new_object.get('serial') is not None or self.new_object.get('serial') is not None: + new_object_params['serial'] = self.new_object.get('serial') or \ + self.new_object.get('serial') + return new_object_params + + def get_object_by_name(self, name): + result = None + # NOTE: Does not have a get by name method, using get all + try: + items = self.meraki.exec_meraki( + family="cellularGateway", + function="getDeviceCellularGatewayLan", + params=self.get_all_params(name=name), + ) + if isinstance(items, dict): + if 'response' in items: + items = items.get('response') + result = get_dict_result(items, 'name', name) + if result is None: + result = items + except Exception as e: + print("Error: ", e) + result = None + return result + + def get_object_by_id(self, id): + result = None + # NOTE: Does not have a get by id method or it is in another action + return result + + def exists(self): + prev_obj = None + id_exists = False + name_exists = False + o_id = self.new_object.get("serial") + name = self.new_object.get("name") + if o_id: + prev_obj = self.get_object_by_name(o_id) + id_exists = prev_obj is not None and isinstance(prev_obj, dict) + if not id_exists and name: + prev_obj = self.get_object_by_name(name) + name_exists = prev_obj is not None and isinstance(prev_obj, dict) + if name_exists: + _id = prev_obj.get("id") + if id_exists and name_exists and o_id != _id: + raise InconsistentParameters( + "The 'id' and 'name' params don't refer to the same object") + if _id: + self.new_object.update(dict(id=_id)) + it_exists = prev_obj is not None and isinstance(prev_obj, dict) + return (it_exists, prev_obj) + + def requires_update(self, current_obj): + requested_obj = self.new_object + + obj_params = [ + ("reservedIpRanges", "reservedIpRanges"), + ("fixedIpAssignments", "fixedIpAssignments"), + ("serial", "serial"), + ] + # Method 1. Params present in request (Ansible) obj are the same as the current (ISE) params + # If any does not have eq params, it requires update + return any(not meraki_compare_equality(current_obj.get(meraki_param), + requested_obj.get(ansible_param)) + for (meraki_param, ansible_param) in obj_params) + + def update(self): + id = self.new_object.get("id") + name = self.new_object.get("name") + result = None + result = self.meraki.exec_meraki( + family="cellularGateway", + function="updateDeviceCellularGatewayLan", + params=self.update_all_params(), + op_modifies=True, + ) + return result + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = False + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + meraki = MERAKI(self._task.args) + obj = DevicesCellularGatewayLan(self._task.args, meraki) + + state = self._task.args.get("state") + + response = None + if state == "present": + (obj_exists, prev_obj) = obj.exists() + if obj_exists: + if obj.requires_update(prev_obj): + response = obj.update() + meraki.object_updated() + else: + response = prev_obj + meraki.object_already_present() + else: + meraki.fail_json( + "Object does not exists, plugin only has update") + + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/devices_cellular_gateway_lan_info.py b/ansible_collections/cisco/meraki/plugins/action/devices_cellular_gateway_lan_info.py new file mode 100644 index 000000000..535c89985 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/devices_cellular_gateway_lan_info.py @@ -0,0 +1,90 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + serial=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_all(self, params): + new_object = {} + if params.get("serial") is not None: + new_object["serial"] = params.get( + "serial") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="cellularGateway", + function='getDeviceCellularGatewayLan', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/devices_cellular_gateway_port_forwarding_rules.py b/ansible_collections/cisco/meraki/plugins/action/devices_cellular_gateway_port_forwarding_rules.py new file mode 100644 index 000000000..59a6ddf66 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/devices_cellular_gateway_port_forwarding_rules.py @@ -0,0 +1,199 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or +# https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, + meraki_compare_equality, + get_dict_result, +) +from ansible_collections.cisco.meraki.plugins.plugin_utils.exceptions import ( + InconsistentParameters, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + state=dict(type="str", default="present", choices=["present"]), + rules=dict(type="list"), + serial=dict(type="str"), +)) + +required_if = [ + ("state", "present", ["serial"], True), +] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class DevicesCellularGatewayPortForwardingRules(object): + def __init__(self, params, meraki): + self.meraki = meraki + self.new_object = dict( + rules=params.get("rules"), + serial=params.get("serial"), + ) + + def get_all_params(self, name=None, id=None): + new_object_params = {} + if self.new_object.get('serial') is not None or self.new_object.get('serial') is not None: + new_object_params['serial'] = self.new_object.get('serial') + return new_object_params + + def update_all_params(self): + new_object_params = {} + if self.new_object.get('rules') is not None or self.new_object.get('rules') is not None: + new_object_params['rules'] = self.new_object.get('rules') or \ + self.new_object.get('rules') + if self.new_object.get('serial') is not None or self.new_object.get('serial') is not None: + new_object_params['serial'] = self.new_object.get('serial') or \ + self.new_object.get('serial') + return new_object_params + + def get_object_by_name(self, name): + result = None + # NOTE: Does not have a get by name method, using get all + try: + items = self.meraki.exec_meraki( + family="cellularGateway", + function="getDeviceCellularGatewayPortForwardingRules", + params=self.get_all_params(name=name), + ) + if isinstance(items, dict): + if 'response' in items: + items = items.get('response') + result = get_dict_result(items, 'name', name) + if result is None: + result = items + except Exception as e: + print("Error: ", e) + result = None + return result + + def get_object_by_id(self, id): + result = None + # NOTE: Does not have a get by id method or it is in another action + return result + + def exists(self): + prev_obj = None + id_exists = False + name_exists = False + o_id = self.new_object.get("serial") + name = self.new_object.get("name") + if o_id: + prev_obj = self.get_object_by_name(o_id) + id_exists = prev_obj is not None and isinstance(prev_obj, dict) + if not id_exists and name: + prev_obj = self.get_object_by_name(name) + name_exists = prev_obj is not None and isinstance(prev_obj, dict) + if name_exists: + _id = prev_obj.get("id") + if id_exists and name_exists and o_id != _id: + raise InconsistentParameters( + "The 'id' and 'name' params don't refer to the same object") + if _id: + self.new_object.update(dict(id=_id)) + it_exists = prev_obj is not None and isinstance(prev_obj, dict) + return (it_exists, prev_obj) + + def requires_update(self, current_obj): + requested_obj = self.new_object + + obj_params = [ + ("rules", "rules"), + ("serial", "serial"), + ] + # Method 1. Params present in request (Ansible) obj are the same as the current (ISE) params + # If any does not have eq params, it requires update + return any(not meraki_compare_equality(current_obj.get(meraki_param), + requested_obj.get(ansible_param)) + for (meraki_param, ansible_param) in obj_params) + + def update(self): + id = self.new_object.get("id") + name = self.new_object.get("name") + result = None + result = self.meraki.exec_meraki( + family="cellularGateway", + function="updateDeviceCellularGatewayPortForwardingRules", + params=self.update_all_params(), + op_modifies=True, + ) + return result + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = False + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + meraki = MERAKI(self._task.args) + obj = DevicesCellularGatewayPortForwardingRules(self._task.args, meraki) + + state = self._task.args.get("state") + + response = None + if state == "present": + (obj_exists, prev_obj) = obj.exists() + if obj_exists: + if obj.requires_update(prev_obj): + response = obj.update() + meraki.object_updated() + else: + response = prev_obj + meraki.object_already_present() + else: + meraki.fail_json( + "Object does not exists, plugin only has update") + + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/devices_cellular_gateway_port_forwarding_rules_info.py b/ansible_collections/cisco/meraki/plugins/action/devices_cellular_gateway_port_forwarding_rules_info.py new file mode 100644 index 000000000..b66c5a4d0 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/devices_cellular_gateway_port_forwarding_rules_info.py @@ -0,0 +1,90 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + serial=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_all(self, params): + new_object = {} + if params.get("serial") is not None: + new_object["serial"] = params.get( + "serial") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="cellularGateway", + function='getDeviceCellularGatewayPortForwardingRules', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/devices_cellular_sims.py b/ansible_collections/cisco/meraki/plugins/action/devices_cellular_sims.py new file mode 100644 index 000000000..93e187918 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/devices_cellular_sims.py @@ -0,0 +1,205 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or +# https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, + meraki_compare_equality, + get_dict_result, +) +from ansible_collections.cisco.meraki.plugins.plugin_utils.exceptions import ( + InconsistentParameters, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + state=dict(type="str", default="present", choices=["present"]), + sims=dict(type="list"), + simFailover=dict(type="dict"), + serial=dict(type="str"), +)) + +required_if = [ + ("state", "present", ["serial"], True), +] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class DevicesCellularSims(object): + def __init__(self, params, meraki): + self.meraki = meraki + self.new_object = dict( + sims=params.get("sims"), + simFailover=params.get("simFailover"), + serial=params.get("serial"), + ) + + def get_all_params(self, name=None, id=None): + new_object_params = {} + if self.new_object.get('serial') is not None or self.new_object.get('serial') is not None: + new_object_params['serial'] = self.new_object.get('serial') + return new_object_params + + def update_all_params(self): + new_object_params = {} + if self.new_object.get('sims') is not None or self.new_object.get('sims') is not None: + new_object_params['sims'] = self.new_object.get('sims') or \ + self.new_object.get('sims') + if self.new_object.get('simFailover') is not None or self.new_object.get('sim_failover') is not None: + new_object_params['simFailover'] = self.new_object.get('simFailover') or \ + self.new_object.get('sim_failover') + if self.new_object.get('serial') is not None or self.new_object.get('serial') is not None: + new_object_params['serial'] = self.new_object.get('serial') or \ + self.new_object.get('serial') + return new_object_params + + def get_object_by_name(self, name): + result = None + # NOTE: Does not have a get by name method, using get all + try: + items = self.meraki.exec_meraki( + family="devices", + function="getDeviceCellularSims", + params=self.get_all_params(name=name), + ) + if isinstance(items, dict): + if 'response' in items: + items = items.get('response') + result = get_dict_result(items, 'name', name) + if result is None: + result = items + except Exception as e: + print("Error: ", e) + result = None + return result + + def get_object_by_id(self, id): + result = None + # NOTE: Does not have a get by id method or it is in another action + return result + + def exists(self): + prev_obj = None + id_exists = False + name_exists = False + o_id = self.new_object.get("serial") + name = self.new_object.get("name") + if o_id: + prev_obj = self.get_object_by_name(o_id) + id_exists = prev_obj is not None and isinstance(prev_obj, dict) + if not id_exists and name: + prev_obj = self.get_object_by_name(name) + name_exists = prev_obj is not None and isinstance(prev_obj, dict) + if name_exists: + _id = prev_obj.get("id") + if id_exists and name_exists and o_id != _id: + raise InconsistentParameters( + "The 'id' and 'name' params don't refer to the same object") + if _id: + self.new_object.update(dict(id=_id)) + it_exists = prev_obj is not None and isinstance(prev_obj, dict) + return (it_exists, prev_obj) + + def requires_update(self, current_obj): + requested_obj = self.new_object + + obj_params = [ + ("sims", "sims"), + ("simFailover", "simFailover"), + ("serial", "serial"), + ] + # Method 1. Params present in request (Ansible) obj are the same as the current (ISE) params + # If any does not have eq params, it requires update + return any(not meraki_compare_equality(current_obj.get(meraki_param), + requested_obj.get(ansible_param)) + for (meraki_param, ansible_param) in obj_params) + + def update(self): + id = self.new_object.get("id") + name = self.new_object.get("name") + result = None + result = self.meraki.exec_meraki( + family="devices", + function="updateDeviceCellularSims", + params=self.update_all_params(), + op_modifies=True, + ) + return result + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = False + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + meraki = MERAKI(self._task.args) + obj = DevicesCellularSims(self._task.args, meraki) + + state = self._task.args.get("state") + + response = None + if state == "present": + (obj_exists, prev_obj) = obj.exists() + if obj_exists: + if obj.requires_update(prev_obj): + response = obj.update() + meraki.object_updated() + else: + response = prev_obj + meraki.object_already_present() + else: + meraki.fail_json( + "Object does not exists, plugin only has update") + + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/devices_cellular_sims_info.py b/ansible_collections/cisco/meraki/plugins/action/devices_cellular_sims_info.py new file mode 100644 index 000000000..6d487dbf2 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/devices_cellular_sims_info.py @@ -0,0 +1,90 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + serial=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_all(self, params): + new_object = {} + if params.get("serial") is not None: + new_object["serial"] = params.get( + "serial") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="devices", + function='getDeviceCellularSims', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/devices_info.py b/ansible_collections/cisco/meraki/plugins/action/devices_info.py new file mode 100644 index 000000000..658579b88 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/devices_info.py @@ -0,0 +1,182 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + serial=dict(type="str"), + organizationId=dict(type="str"), + perPage=dict(type="int"), + total_pages=dict(type="int"), + direction=dict(type="str"), + startingAfter=dict(type="str"), + endingBefore=dict(type="str"), + configurationUpdatedAfter=dict(type="str"), + networkIds=dict(type="list"), + productTypes=dict(type="list"), + tags=dict(type="list"), + tagsFilterType=dict(type="str"), + name=dict(type="str"), + mac=dict(type="str"), + model=dict(type="str"), + macs=dict(type="list"), + serials=dict(type="list"), + sensorMetrics=dict(type="list"), + sensorAlertProfileIds=dict(type="list"), + models=dict(type="list"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_object(self, params): + new_object = {} + if params.get("serial") is not None: + new_object["serial"] = params.get( + "serial") + return new_object + + def get_all(self, params): + new_object = {} + if params.get("organizationId") is not None: + new_object["organizationId"] = params.get( + "organizationId") + if params.get("perPage") is not None: + new_object["perPage"] = params.get( + "perPage") + new_object['total_pages'] = params.get( + "total_pages") or 1 + new_object['direction'] = params.get( + "direction") or "next" + if params.get("startingAfter") is not None: + new_object["startingAfter"] = params.get( + "startingAfter") + if params.get("endingBefore") is not None: + new_object["endingBefore"] = params.get( + "endingBefore") + if params.get("configurationUpdatedAfter") is not None: + new_object["configurationUpdatedAfter"] = params.get( + "configurationUpdatedAfter") + if params.get("networkIds") is not None: + new_object["networkIds"] = params.get( + "networkIds") + if params.get("productTypes") is not None: + new_object["productTypes"] = params.get( + "productTypes") + if params.get("tags") is not None: + new_object["tags"] = params.get( + "tags") + if params.get("tagsFilterType") is not None: + new_object["tagsFilterType"] = params.get( + "tagsFilterType") + if params.get("name") is not None: + new_object["name"] = params.get( + "name") + if params.get("mac") is not None: + new_object["mac"] = params.get( + "mac") + if params.get("serial") is not None: + new_object["serial"] = params.get( + "serial") + if params.get("model") is not None: + new_object["model"] = params.get( + "model") + if params.get("macs") is not None: + new_object["macs"] = params.get( + "macs") + if params.get("serials") is not None: + new_object["serials"] = params.get( + "serials") + if params.get("sensorMetrics") is not None: + new_object["sensorMetrics"] = params.get( + "sensorMetrics") + if params.get("sensorAlertProfileIds") is not None: + new_object["sensorAlertProfileIds"] = params.get( + "sensorAlertProfileIds") + if params.get("models") is not None: + new_object["models"] = params.get( + "models") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + id = self._task.args.get("serial") + if id: + response = meraki.exec_meraki( + family="devices", + function='getDevice', + params=self.get_object(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result + if not id: + response = meraki.exec_meraki( + family="organizations", + function='getOrganizationDevices', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/devices_live_tools_ping.py b/ansible_collections/cisco/meraki/plugins/action/devices_live_tools_ping.py new file mode 100644 index 000000000..ba5ef2d67 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/devices_live_tools_ping.py @@ -0,0 +1,205 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or +# https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, + meraki_compare_equality, +) +from ansible_collections.cisco.meraki.plugins.plugin_utils.exceptions import ( + InconsistentParameters, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + state=dict(type="str", default="present", choices=["present"]), + target=dict(type="str"), + count=dict(type="int"), + serial=dict(type="str"), + id=dict(type="str"), +)) + +required_if = [ + ("state", "present", ["id", "serial"], True), +] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class DevicesLiveToolsPing(object): + def __init__(self, params, meraki): + self.meraki = meraki + self.new_object = dict( + target=params.get("target"), + count=params.get("count"), + serial=params.get("serial"), + id=params.get("id"), + ) + + def get_params_by_id(self, name=None, id=None): + new_object_params = {} + if self.new_object.get('serial') is not None or self.new_object.get('serial') is not None: + new_object_params['serial'] = self.new_object.get('serial') + if self.new_object.get('id') is not None or self.new_object.get('id') is not None: + new_object_params['id'] = self.new_object.get('id') + return new_object_params + + def create_params(self): + new_object_params = {} + if self.new_object.get('target') is not None or self.new_object.get('target') is not None: + new_object_params['target'] = self.new_object.get('target') or \ + self.new_object.get('target') + if self.new_object.get('count') is not None or self.new_object.get('count') is not None: + new_object_params['count'] = self.new_object.get('count') or \ + self.new_object.get('count') + if self.new_object.get('serial') is not None or self.new_object.get('serial') is not None: + new_object_params['serial'] = self.new_object.get('serial') or \ + self.new_object.get('serial') + return new_object_params + + def get_object_by_name(self, name): + result = None + # NOTE: Does not have a get by name and get all + return result + + def get_object_by_id(self, id): + result = None + try: + items = self.meraki.exec_meraki( + family="devices", + function="getDeviceLiveToolsPing", + params={"id": id} + ) + if isinstance(items, dict): + if 'response' in items: + items = items.get('response') + result = items + except Exception as e: + print("Error: ", e) + result = None + return result + + def exists(self): + prev_obj = None + id_exists = False + name_exists = False + o_id = self.new_object.get("id") # review it + name = self.new_object.get("name") + if o_id: + prev_obj = self.get_object_by_id(o_id) + id_exists = prev_obj is not None and isinstance(prev_obj, dict) + if not id_exists and name: + prev_obj = self.get_object_by_name(name) + name_exists = prev_obj is not None and isinstance(prev_obj, dict) + if name_exists: + _id = prev_obj.get("id") + if id_exists and name_exists and o_id != _id: + raise InconsistentParameters( + "The 'id' and 'name' params don't refer to the same object") + if _id: + self.new_object.update(dict(id=_id)) + if _id: + prev_obj = self.get_object_by_id(_id) + it_exists = prev_obj is not None and isinstance(prev_obj, dict) + return (it_exists, prev_obj) + + def requires_update(self, current_obj): + requested_obj = self.new_object + + obj_params = [ + ("target", "target"), + ("count", "count"), + ("serial", "serial"), + ("id", "id"), + ] + # Method 1. Params present in request (Ansible) obj are the same as the current (ISE) params + # If any does not have eq params, it requires update + return any(not meraki_compare_equality(current_obj.get(meraki_param), + requested_obj.get(ansible_param)) + for (meraki_param, ansible_param) in obj_params) + + def create(self): + result = self.meraki.exec_meraki( + family="devices", + function="createDeviceLiveToolsPing", + params=self.create_params(), + op_modifies=True, + ) + return result + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = False + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + meraki = MERAKI(self._task.args) + obj = DevicesLiveToolsPing(self._task.args, meraki) + + state = self._task.args.get("state") + + response = None + if state == "present": + (obj_exists, prev_obj) = obj.exists() + if obj_exists: + if obj.requires_update(prev_obj): + response = prev_obj + meraki.object_present_and_different() + else: + response = prev_obj + meraki.object_already_present() + else: + response = obj.create() + meraki.object_created() + + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/devices_live_tools_ping_device.py b/ansible_collections/cisco/meraki/plugins/action/devices_live_tools_ping_device.py new file mode 100644 index 000000000..cb00a6c6b --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/devices_live_tools_ping_device.py @@ -0,0 +1,199 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or +# https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, + meraki_compare_equality, +) +from ansible_collections.cisco.meraki.plugins.plugin_utils.exceptions import ( + InconsistentParameters, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + state=dict(type="str", default="present", choices=["present"]), + count=dict(type="int"), + serial=dict(type="str"), + id=dict(type="str"), +)) + +required_if = [ + ("state", "present", ["id", "serial"], True), +] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class DevicesLiveToolsPingDevice(object): + def __init__(self, params, meraki): + self.meraki = meraki + self.new_object = dict( + count=params.get("count"), + serial=params.get("serial"), + id=params.get("id"), + ) + + def get_params_by_id(self, name=None, id=None): + new_object_params = {} + if self.new_object.get('serial') is not None or self.new_object.get('serial') is not None: + new_object_params['serial'] = self.new_object.get('serial') + if self.new_object.get('id') is not None or self.new_object.get('id') is not None: + new_object_params['id'] = self.new_object.get('id') + return new_object_params + + def create_params(self): + new_object_params = {} + if self.new_object.get('count') is not None or self.new_object.get('count') is not None: + new_object_params['count'] = self.new_object.get('count') or \ + self.new_object.get('count') + if self.new_object.get('serial') is not None or self.new_object.get('serial') is not None: + new_object_params['serial'] = self.new_object.get('serial') or \ + self.new_object.get('serial') + return new_object_params + + def get_object_by_name(self, name): + result = None + # NOTE: Does not have a get by name and get all + return result + + def get_object_by_id(self, id): + result = None + try: + items = self.meraki.exec_meraki( + family="devices", + function="getDeviceLiveToolsPingDevice", + params={"id": id} + ) + if isinstance(items, dict): + if 'response' in items: + items = items.get('response') + result = items + except Exception as e: + print("Error: ", e) + result = None + return result + + def exists(self): + prev_obj = None + id_exists = False + name_exists = False + o_id = self.new_object.get("id") # review it + name = self.new_object.get("serial") + if o_id: + prev_obj = self.get_object_by_id(o_id) + id_exists = prev_obj is not None and isinstance(prev_obj, dict) + if not id_exists and name: + prev_obj = self.get_object_by_name(name) + name_exists = prev_obj is not None and isinstance(prev_obj, dict) + if name_exists: + _id = prev_obj.get("id") + if id_exists and name_exists and o_id != _id: + raise InconsistentParameters( + "The 'id' and 'name' params don't refer to the same object") + if _id: + self.new_object.update(dict(id=_id)) + if _id: + prev_obj = self.get_object_by_id(_id) + it_exists = prev_obj is not None and isinstance(prev_obj, dict) + return (it_exists, prev_obj) + + def requires_update(self, current_obj): + requested_obj = self.new_object + + obj_params = [ + ("count", "count"), + ("serial", "serial"), + ("id", "id"), + ] + # Method 1. Params present in request (Ansible) obj are the same as the current (ISE) params + # If any does not have eq params, it requires update + return any(not meraki_compare_equality(current_obj.get(meraki_param), + requested_obj.get(ansible_param)) + for (meraki_param, ansible_param) in obj_params) + + def create(self): + result = self.meraki.exec_meraki( + family="devices", + function="createDeviceLiveToolsPingDevice", + params=self.create_params(), + op_modifies=True, + ) + return result + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = False + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + meraki = MERAKI(self._task.args) + obj = DevicesLiveToolsPingDevice(self._task.args, meraki) + + state = self._task.args.get("state") + + response = None + if state == "present": + (obj_exists, prev_obj) = obj.exists() + if obj_exists: + if obj.requires_update(prev_obj): + response = prev_obj + meraki.object_present_and_different() + else: + response = prev_obj + meraki.object_already_present() + else: + response = obj.create() + meraki.object_created() + + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/devices_live_tools_ping_device_info.py b/ansible_collections/cisco/meraki/plugins/action/devices_live_tools_ping_device_info.py new file mode 100644 index 000000000..b7f419ed1 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/devices_live_tools_ping_device_info.py @@ -0,0 +1,102 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + serial=dict(type="str"), + id=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_object(self, params): + new_object = {} + if params.get("serial") is not None: + new_object["serial"] = params.get( + "serial") + if params.get("id") is not None: + new_object["id"] = params.get( + "id") + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + id = self._task.args.get("id") + if id: + response = meraki.exec_meraki( + family="devices", + function='getDeviceLiveToolsPingDevice', + params=self.get_object(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result + if not id: + # NOTE: Does not have a get all method or it is in another action + response = None + meraki.object_modify_result(changed=False, result="Module does not have get all, check arguments of module") + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/devices_live_tools_ping_info.py b/ansible_collections/cisco/meraki/plugins/action/devices_live_tools_ping_info.py new file mode 100644 index 000000000..854466248 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/devices_live_tools_ping_info.py @@ -0,0 +1,102 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + serial=dict(type="str"), + id=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_object(self, params): + new_object = {} + if params.get("serial") is not None: + new_object["serial"] = params.get( + "serial") + if params.get("id") is not None: + new_object["id"] = params.get( + "id") + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + id = self._task.args.get("id") + if id: + response = meraki.exec_meraki( + family="devices", + function='getDeviceLiveToolsPing', + params=self.get_object(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result + if not id: + # NOTE: Does not have a get all method or it is in another action + response = None + meraki.object_modify_result(changed=False, result="Module does not have get all, check arguments of module") + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/devices_lldp_cdp_info.py b/ansible_collections/cisco/meraki/plugins/action/devices_lldp_cdp_info.py new file mode 100644 index 000000000..bd959b261 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/devices_lldp_cdp_info.py @@ -0,0 +1,90 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + serial=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_all(self, params): + new_object = {} + if params.get("serial") is not None: + new_object["serial"] = params.get( + "serial") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="devices", + function='getDeviceLldpCdp', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/devices_management_interface.py b/ansible_collections/cisco/meraki/plugins/action/devices_management_interface.py new file mode 100644 index 000000000..3ba507e38 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/devices_management_interface.py @@ -0,0 +1,221 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or +# https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, + meraki_compare_equality, + get_dict_result, +) +from ansible_collections.cisco.meraki.plugins.plugin_utils.exceptions import ( + InconsistentParameters, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + state=dict(type="str", default="present", choices=["present"]), + serial=dict(type="str"), + wan1=dict(type="dict"), + wan2=dict(type="dict"), +)) + +required_if = [ + ("state", "present", ["serial"], True), +] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class DevicesManagementInterface(object): + def __init__(self, params, meraki): + self.meraki = meraki + self.new_object = dict( + serial=params.get("serial"), + wan1=params.get("wan1"), + wan2=params.get("wan2"), + ) + + def get_all_params(self, name=None, id=None): + new_object_params = {} + if self.new_object.get('serial') is not None or self.new_object.get('serial') is not None: + new_object_params['serial'] = self.new_object.get('serial') + return new_object_params + + def create_params(self): + new_object_params = {} + if self.new_object.get('serial') is not None or self.new_object.get('serial') is not None: + new_object_params['serial'] = self.new_object.get('serial') or \ + self.new_object.get('serial') + return new_object_params + + def update_all_params(self): + new_object_params = {} + if self.new_object.get('wan1') is not None or self.new_object.get('wan1') is not None: + new_object_params['wan1'] = self.new_object.get('wan1') or \ + self.new_object.get('wan1') + if self.new_object.get('wan2') is not None or self.new_object.get('wan2') is not None: + new_object_params['wan2'] = self.new_object.get('wan2') or \ + self.new_object.get('wan2') + if self.new_object.get('serial') is not None or self.new_object.get('serial') is not None: + new_object_params['serial'] = self.new_object.get('serial') or \ + self.new_object.get('serial') + return new_object_params + + def get_object_by_name(self, name): + result = None + # NOTE: Does not have a get by name method, using get all + try: + items = self.meraki.exec_meraki( + family="devices", + function="getDeviceManagementInterface", + params=self.get_all_params(name=name), + ) + if isinstance(items, dict): + if 'response' in items: + items = items.get('response') + result = get_dict_result(items, 'name', name) + if result is None: + result = items + except Exception as e: + print("Error: ", e) + result = None + return result + + def get_object_by_id(self, id): + result = None + # NOTE: Does not have a get by id method or it is in another action + return result + + def exists(self): + prev_obj = None + id_exists = False + name_exists = False + o_id = self.new_object.get("serial") + name = self.new_object.get("name") + if o_id: + prev_obj = self.get_object_by_name(o_id) + id_exists = prev_obj is not None and isinstance(prev_obj, dict) + if not id_exists and name: + prev_obj = self.get_object_by_name(name) + name_exists = prev_obj is not None and isinstance(prev_obj, dict) + if name_exists: + _id = prev_obj.get("id") + if id_exists and name_exists and o_id != _id: + raise InconsistentParameters( + "The 'id' and 'name' params don't refer to the same object") + if _id: + self.new_object.update(dict(id=_id)) + it_exists = prev_obj is not None and isinstance(prev_obj, dict) + return (it_exists, prev_obj) + + def requires_update(self, current_obj): + requested_obj = self.new_object + + obj_params = [ + ("serial", "serial"), + ("wan1", "wan1"), + ("wan2", "wan2"), + ] + # Method 1. Params present in request (Ansible) obj are the same as the current (ISE) params + # If any does not have eq params, it requires update + return any(not meraki_compare_equality(current_obj.get(meraki_param), + requested_obj.get(ansible_param)) + for (meraki_param, ansible_param) in obj_params) + + def create(self): + result = self.meraki.exec_meraki( + family="devices", + function="rebootDevice", + params=self.create_params(), + op_modifies=True, + ) + return result + + def update(self): + id = self.new_object.get("id") + name = self.new_object.get("name") + result = None + result = self.meraki.exec_meraki( + family="devices", + function="updateDeviceManagementInterface", + params=self.update_all_params(), + op_modifies=True, + ) + return result + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = False + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + meraki = MERAKI(self._task.args) + obj = DevicesManagementInterface(self._task.args, meraki) + + state = self._task.args.get("state") + + response = None + if state == "present": + (obj_exists, prev_obj) = obj.exists() + if obj_exists: + if obj.requires_update(prev_obj): + response = obj.update() + meraki.object_updated() + else: + response = prev_obj + meraki.object_already_present() + else: + response = obj.create() + meraki.object_created() + + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/devices_management_interface_info.py b/ansible_collections/cisco/meraki/plugins/action/devices_management_interface_info.py new file mode 100644 index 000000000..194bf440a --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/devices_management_interface_info.py @@ -0,0 +1,90 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + serial=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_all(self, params): + new_object = {} + if params.get("serial") is not None: + new_object["serial"] = params.get( + "serial") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="devices", + function='getDeviceManagementInterface', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/devices_sensor_relationships.py b/ansible_collections/cisco/meraki/plugins/action/devices_sensor_relationships.py new file mode 100644 index 000000000..75c20b830 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/devices_sensor_relationships.py @@ -0,0 +1,199 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or +# https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, + meraki_compare_equality, + get_dict_result, +) +from ansible_collections.cisco.meraki.plugins.plugin_utils.exceptions import ( + InconsistentParameters, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + state=dict(type="str", default="present", choices=["present"]), + livestream=dict(type="dict"), + serial=dict(type="str"), +)) + +required_if = [ + ("state", "present", ["serial"], True), +] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class DevicesSensorRelationships(object): + def __init__(self, params, meraki): + self.meraki = meraki + self.new_object = dict( + livestream=params.get("livestream"), + serial=params.get("serial"), + ) + + def get_all_params(self, name=None, id=None): + new_object_params = {} + if self.new_object.get('serial') is not None or self.new_object.get('serial') is not None: + new_object_params['serial'] = self.new_object.get('serial') + return new_object_params + + def update_all_params(self): + new_object_params = {} + if self.new_object.get('livestream') is not None or self.new_object.get('livestream') is not None: + new_object_params['livestream'] = self.new_object.get('livestream') or \ + self.new_object.get('livestream') + if self.new_object.get('serial') is not None or self.new_object.get('serial') is not None: + new_object_params['serial'] = self.new_object.get('serial') or \ + self.new_object.get('serial') + return new_object_params + + def get_object_by_name(self, name): + result = None + # NOTE: Does not have a get by name method, using get all + try: + items = self.meraki.exec_meraki( + family="sensor", + function="getDeviceSensorRelationships", + params=self.get_all_params(name=name), + ) + if isinstance(items, dict): + if 'response' in items: + items = items.get('response') + result = get_dict_result(items, 'name', name) + if result is None: + result = items + except Exception as e: + print("Error: ", e) + result = None + return result + + def get_object_by_id(self, id): + result = None + # NOTE: Does not have a get by id method or it is in another action + return result + + def exists(self): + prev_obj = None + id_exists = False + name_exists = False + o_id = self.new_object.get("serial") + name = self.new_object.get("name") + if o_id: + prev_obj = self.get_object_by_name(o_id) + id_exists = prev_obj is not None and isinstance(prev_obj, dict) + if not id_exists and name: + prev_obj = self.get_object_by_name(name) + name_exists = prev_obj is not None and isinstance(prev_obj, dict) + if name_exists: + _id = prev_obj.get("id") + if id_exists and name_exists and o_id != _id: + raise InconsistentParameters( + "The 'id' and 'name' params don't refer to the same object") + if _id: + self.new_object.update(dict(id=_id)) + it_exists = prev_obj is not None and isinstance(prev_obj, dict) + return (it_exists, prev_obj) + + def requires_update(self, current_obj): + requested_obj = self.new_object + + obj_params = [ + ("livestream", "livestream"), + ("serial", "serial"), + ] + # Method 1. Params present in request (Ansible) obj are the same as the current (ISE) params + # If any does not have eq params, it requires update + return any(not meraki_compare_equality(current_obj.get(meraki_param), + requested_obj.get(ansible_param)) + for (meraki_param, ansible_param) in obj_params) + + def update(self): + id = self.new_object.get("id") + name = self.new_object.get("name") + result = None + result = self.meraki.exec_meraki( + family="sensor", + function="updateDeviceSensorRelationships", + params=self.update_all_params(), + op_modifies=True, + ) + return result + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = False + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + meraki = MERAKI(self._task.args) + obj = DevicesSensorRelationships(self._task.args, meraki) + + state = self._task.args.get("state") + + response = None + if state == "present": + (obj_exists, prev_obj) = obj.exists() + if obj_exists: + if obj.requires_update(prev_obj): + response = obj.update() + meraki.object_updated() + else: + response = prev_obj + meraki.object_already_present() + else: + meraki.fail_json( + "Object does not exists, plugin only has update") + + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/devices_sensor_relationships_info.py b/ansible_collections/cisco/meraki/plugins/action/devices_sensor_relationships_info.py new file mode 100644 index 000000000..29592fffa --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/devices_sensor_relationships_info.py @@ -0,0 +1,90 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + serial=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_all(self, params): + new_object = {} + if params.get("serial") is not None: + new_object["serial"] = params.get( + "serial") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="sensor", + function='getDeviceSensorRelationships', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/devices_switch_ports.py b/ansible_collections/cisco/meraki/plugins/action/devices_switch_ports.py new file mode 100644 index 000000000..659e6a4f8 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/devices_switch_ports.py @@ -0,0 +1,383 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or +# https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, + meraki_compare_equality2, + get_dict_result, +) +from ansible_collections.cisco.meraki.plugins.plugin_utils.exceptions import ( + InconsistentParameters, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + state=dict(type="str", default="present", choices=["present"]), + name=dict(type="str"), + tags=dict(type="list"), + enabled=dict(type="bool"), + poeEnabled=dict(type="bool"), + type=dict(type="str"), + vlan=dict(type="int"), + voiceVlan=dict(type="int"), + allowedVlans=dict(type="str"), + isolationEnabled=dict(type="bool"), + rstpEnabled=dict(type="bool"), + stpGuard=dict(type="str"), + linkNegotiation=dict(type="str"), + portScheduleId=dict(type="str"), + udld=dict(type="str"), + accessPolicyType=dict(type="str"), + accessPolicyNumber=dict(type="int"), + macAllowList=dict(type="list"), + stickyMacAllowList=dict(type="list"), + stickyMacAllowListLimit=dict(type="int"), + stormControlEnabled=dict(type="bool"), + adaptivePolicyGroupId=dict(type="str"), + peerSgtCapable=dict(type="bool"), + flexibleStackingEnabled=dict(type="bool"), + daiTrusted=dict(type="bool"), + profile=dict(type="dict"), + serial=dict(type="str"), + portId=dict(type="str"), +)) + +required_if = [ + ("state", "present", ["name", "portId", "serial"], True), +] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class DevicesSwitchPorts(object): + def __init__(self, params, meraki): + self.meraki = meraki + self.new_object = dict( + name=params.get("name"), + tags=params.get("tags"), + enabled=params.get("enabled"), + poeEnabled=params.get("poeEnabled"), + type=params.get("type"), + vlan=params.get("vlan"), + voiceVlan=params.get("voiceVlan"), + allowedVlans=params.get("allowedVlans"), + isolationEnabled=params.get("isolationEnabled"), + rstpEnabled=params.get("rstpEnabled"), + stpGuard=params.get("stpGuard"), + linkNegotiation=params.get("linkNegotiation"), + portScheduleId=params.get("portScheduleId"), + udld=params.get("udld"), + accessPolicyType=params.get("accessPolicyType"), + accessPolicyNumber=params.get("accessPolicyNumber"), + macAllowList=params.get("macAllowList"), + stickyMacAllowList=params.get("stickyMacAllowList"), + stickyMacAllowListLimit=params.get("stickyMacAllowListLimit"), + stormControlEnabled=params.get("stormControlEnabled"), + adaptivePolicyGroupId=params.get("adaptivePolicyGroupId"), + peerSgtCapable=params.get("peerSgtCapable"), + flexibleStackingEnabled=params.get("flexibleStackingEnabled"), + daiTrusted=params.get("daiTrusted"), + profile=params.get("profile"), + serial=params.get("serial"), + port_id=params.get("portId"), + ) + + def get_all_params(self, name=None, id=None): + new_object_params = {} + if self.new_object.get('serial') is not None or self.new_object.get('serial') is not None: + new_object_params['serial'] = self.new_object.get('serial') + return new_object_params + + def get_params_by_id(self, name=None, id=None): + new_object_params = {} + if self.new_object.get('serial') is not None or self.new_object.get('serial') is not None: + new_object_params['serial'] = self.new_object.get('serial') + if self.new_object.get('portId') is not None or self.new_object.get('port_id') is not None: + new_object_params['portId'] = self.new_object.get('portId') or \ + self.new_object.get('port_id') + return new_object_params + + def update_by_id_params(self): + new_object_params = {} + if self.new_object.get('name') is not None or self.new_object.get('name') is not None: + new_object_params['name'] = self.new_object.get('name') or \ + self.new_object.get('name') + if self.new_object.get('tags') is not None or self.new_object.get('tags') is not None: + new_object_params['tags'] = self.new_object.get('tags') or \ + self.new_object.get('tags') + if self.new_object.get('enabled') is not None or self.new_object.get('enabled') is not None: + new_object_params['enabled'] = self.new_object.get('enabled') + if self.new_object.get('poeEnabled') is not None or self.new_object.get('poe_enabled') is not None: + new_object_params['poeEnabled'] = self.new_object.get('poeEnabled') + if self.new_object.get('type') is not None or self.new_object.get('type') is not None: + new_object_params['type'] = self.new_object.get('type') or \ + self.new_object.get('type') + if self.new_object.get('vlan') is not None or self.new_object.get('vlan') is not None: + new_object_params['vlan'] = self.new_object.get('vlan') or \ + self.new_object.get('vlan') + if self.new_object.get('voiceVlan') is not None or self.new_object.get('voice_vlan') is not None: + new_object_params['voiceVlan'] = self.new_object.get('voiceVlan') or \ + self.new_object.get('voice_vlan') + if self.new_object.get('allowedVlans') is not None or self.new_object.get('allowed_vlans') is not None: + new_object_params['allowedVlans'] = self.new_object.get('allowedVlans') or \ + self.new_object.get('allowed_vlans') + if self.new_object.get('isolationEnabled') is not None or self.new_object.get('isolation_enabled') is not None: + new_object_params['isolationEnabled'] = self.new_object.get( + 'isolationEnabled') + if self.new_object.get('rstpEnabled') is not None or self.new_object.get('rstp_enabled') is not None: + new_object_params['rstpEnabled'] = self.new_object.get( + 'rstpEnabled') + if self.new_object.get('stpGuard') is not None or self.new_object.get('stp_guard') is not None: + new_object_params['stpGuard'] = self.new_object.get('stpGuard') or \ + self.new_object.get('stp_guard') + if self.new_object.get('linkNegotiation') is not None or self.new_object.get('link_negotiation') is not None: + new_object_params['linkNegotiation'] = self.new_object.get('linkNegotiation') or \ + self.new_object.get('link_negotiation') + if self.new_object.get('portScheduleId') is not None or self.new_object.get('port_schedule_id') is not None: + new_object_params['portScheduleId'] = self.new_object.get('portScheduleId') or \ + self.new_object.get('port_schedule_id') + if self.new_object.get('udld') is not None or self.new_object.get('udld') is not None: + new_object_params['udld'] = self.new_object.get('udld') or \ + self.new_object.get('udld') + if self.new_object.get('accessPolicyType') is not None or self.new_object.get('access_policy_type') is not None: + new_object_params['accessPolicyType'] = self.new_object.get('accessPolicyType') or \ + self.new_object.get('access_policy_type') + if self.new_object.get('accessPolicyNumber') is not None or self.new_object.get('access_policy_number') is not None: + new_object_params['accessPolicyNumber'] = self.new_object.get('accessPolicyNumber') or \ + self.new_object.get('access_policy_number') + if self.new_object.get('macAllowList') is not None or self.new_object.get('mac_allow_list') is not None: + new_object_params['macAllowList'] = self.new_object.get('macAllowList') or \ + self.new_object.get('mac_allow_list') + if self.new_object.get('stickyMacAllowList') is not None or self.new_object.get('sticky_mac_allow_list') is not None: + new_object_params['stickyMacAllowList'] = self.new_object.get('stickyMacAllowList') or \ + self.new_object.get('sticky_mac_allow_list') + if self.new_object.get('stickyMacAllowListLimit') is not None or self.new_object.get('sticky_mac_allow_list_limit') is not None: + new_object_params['stickyMacAllowListLimit'] = self.new_object.get('stickyMacAllowListLimit') or \ + self.new_object.get('sticky_mac_allow_list_limit') + if self.new_object.get('stormControlEnabled') is not None or self.new_object.get('storm_control_enabled') is not None: + new_object_params['stormControlEnabled'] = self.new_object.get( + 'stormControlEnabled') + if self.new_object.get('adaptivePolicyGroupId') is not None or self.new_object.get('adaptive_policy_group_id') is not None: + new_object_params['adaptivePolicyGroupId'] = self.new_object.get('adaptivePolicyGroupId') or \ + self.new_object.get('adaptive_policy_group_id') + if self.new_object.get('peerSgtCapable') is not None or self.new_object.get('peer_sgt_capable') is not None: + new_object_params['peerSgtCapable'] = self.new_object.get( + 'peerSgtCapable') + if self.new_object.get('flexibleStackingEnabled') is not None or self.new_object.get('flexible_stacking_enabled') is not None: + new_object_params['flexibleStackingEnabled'] = self.new_object.get( + 'flexibleStackingEnabled') + if self.new_object.get('daiTrusted') is not None or self.new_object.get('dai_trusted') is not None: + new_object_params['daiTrusted'] = self.new_object.get('daiTrusted') + if self.new_object.get('profile') is not None or self.new_object.get('profile') is not None: + new_object_params['profile'] = self.new_object.get('profile') or \ + self.new_object.get('profile') + if self.new_object.get('serial') is not None or self.new_object.get('serial') is not None: + new_object_params['serial'] = self.new_object.get('serial') or \ + self.new_object.get('serial') + if self.new_object.get('portId') is not None or self.new_object.get('port_id') is not None: + new_object_params['portId'] = self.new_object.get('portId') or \ + self.new_object.get('port_id') + return new_object_params + + def get_object_by_name(self, name): + result = None + name = self.new_object.get('portId') or self.new_object.get('port_id') + # NOTE: Does not have a get by name method, using get all + try: + items = self.meraki.exec_meraki( + family="switch", + function="getDeviceSwitchPorts", + params=self.get_all_params(name=name), + ) + if isinstance(items, dict): + if 'response' in items: + items = items.get('response') + result = get_dict_result(items, 'portId', name) + if result is None: + result = items + except Exception as e: + print("Error: ", e) + result = None + return result + + def get_object_by_id(self, id): + result = None + try: + items = self.meraki.exec_meraki( + family="switch", + function="getDeviceSwitchPort", + params=self.get_params_by_id() + ) + if isinstance(items, dict): + if 'response' in items: + items = items.get('response') + result = items + except Exception as e: + print("Error: ", e) + result = None + return result + + def exists(self): + prev_obj = None + id_exists = False + name_exists = False + o_id = self.new_object.get("serial") + o_id = o_id or self.new_object.get( + "port_id") or self.new_object.get("portId") + name = self.new_object.get("name") + if o_id: + prev_obj = self.get_object_by_id(o_id) + id_exists = prev_obj is not None and isinstance(prev_obj, dict) + if not id_exists and name: + prev_obj = self.get_object_by_name(name) + name_exists = prev_obj is not None and isinstance(prev_obj, dict) + if name_exists: + _id = prev_obj.get("id") + _id = _id or prev_obj.get("portId") + if id_exists and name_exists and o_id != _id: + raise InconsistentParameters( + "The 'id' and 'name' params don't refer to the same object") + if _id: + self.new_object.update(dict(id=_id)) + self.new_object.update(dict(portId=_id)) + if _id: + prev_obj = self.get_object_by_id(_id) + it_exists = prev_obj is not None and isinstance(prev_obj, dict) + return (it_exists, prev_obj) + + def requires_update(self, current_obj): + requested_obj = self.new_object + + obj_params = [ + ("name", "name"), + ("tags", "tags"), + ("enabled", "enabled"), + ("poeEnabled", "poeEnabled"), + ("type", "type"), + ("vlan", "vlan"), + ("voiceVlan", "voiceVlan"), + ("allowedVlans", "allowedVlans"), + ("isolationEnabled", "isolationEnabled"), + ("rstpEnabled", "rstpEnabled"), + ("stpGuard", "stpGuard"), + ("linkNegotiation", "linkNegotiation"), + ("portScheduleId", "portScheduleId"), + ("udld", "udld"), + ("accessPolicyType", "accessPolicyType"), + ("accessPolicyNumber", "accessPolicyNumber"), + ("macAllowList", "macAllowList"), + ("stickyMacAllowList", "stickyMacAllowList"), + ("stickyMacAllowListLimit", "stickyMacAllowListLimit"), + ("stormControlEnabled", "stormControlEnabled"), + ("adaptivePolicyGroupId", "adaptivePolicyGroupId"), + ("peerSgtCapable", "peerSgtCapable"), + ("flexibleStackingEnabled", "flexibleStackingEnabled"), + ("daiTrusted", "daiTrusted"), + ("profile", "profile"), + ("serial", "serial"), + ("portId", "portId"), + ] + # Method 1. Params present in request (Ansible) obj are the same as the current (ISE) params + # If any does not have eq params, it requires update + return any(not meraki_compare_equality2(current_obj.get(meraki_param), + requested_obj.get(ansible_param)) + for (meraki_param, ansible_param) in obj_params) + + def update(self): + id = self.new_object.get("id") + id = id or self.new_object.get("portId") + name = self.new_object.get("name") + result = None + if not id: + prev_obj_name = self.get_object_by_name(name) + id_ = None + if prev_obj_name: + id_ = prev_obj_name.get("id") + id_ = id_ or prev_obj_name.get("portId") + if id_: + self.new_object.update(dict(portid=id_)) + result = self.meraki.exec_meraki( + family="switch", + function="updateDeviceSwitchPort", + params=self.update_by_id_params(), + op_modifies=True, + ) + return result + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = False + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + meraki = MERAKI(self._task.args) + obj = DevicesSwitchPorts(self._task.args, meraki) + + state = self._task.args.get("state") + + response = None + if state == "present": + (obj_exists, prev_obj) = obj.exists() + if obj_exists: + if obj.requires_update(prev_obj): + response = obj.update() + meraki.object_updated() + else: + response = prev_obj + meraki.object_already_present() + else: + meraki.fail_json( + "Object does not exists, plugin only has update") + + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/devices_switch_ports_cycle.py b/ansible_collections/cisco/meraki/plugins/action/devices_switch_ports_cycle.py new file mode 100644 index 000000000..1d2c55984 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/devices_switch_ports_cycle.py @@ -0,0 +1,89 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguements specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + ports=dict(type="list"), + serial=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = False + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_object(self, params): + new_object = dict( + ports=params.get("ports"), + serial=params.get("serial"), + ) + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="switch", + function='cycleDeviceSwitchPorts', + op_modifies=True, + params=self.get_object(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/devices_switch_ports_info.py b/ansible_collections/cisco/meraki/plugins/action/devices_switch_ports_info.py new file mode 100644 index 000000000..90ba671b6 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/devices_switch_ports_info.py @@ -0,0 +1,112 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + serial=dict(type="str"), + portId=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_object(self, params): + new_object = {} + if params.get("serial") is not None: + new_object["serial"] = params.get( + "serial") + if params.get("portId") is not None: + new_object["portId"] = params.get( + "portId") + return new_object + + def get_all(self, params): + new_object = {} + if params.get("serial") is not None: + new_object["serial"] = params.get( + "serial") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + id = self._task.args.get("portId") + if id: + response = meraki.exec_meraki( + family="switch", + function='getDeviceSwitchPort', + params=self.get_object(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result + if not id: + response = meraki.exec_meraki( + family="switch", + function='getDeviceSwitchPorts', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/devices_switch_ports_statuses_info.py b/ansible_collections/cisco/meraki/plugins/action/devices_switch_ports_statuses_info.py new file mode 100644 index 000000000..b1191387b --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/devices_switch_ports_statuses_info.py @@ -0,0 +1,98 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + serial=dict(type="str"), + t0=dict(type="str"), + timespan=dict(type="float"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_all(self, params): + new_object = {} + if params.get("serial") is not None: + new_object["serial"] = params.get( + "serial") + if params.get("t0") is not None: + new_object["t0"] = params.get( + "t0") + if params.get("timespan") is not None: + new_object["timespan"] = params.get( + "timespan") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="switch", + function='getDeviceSwitchPortsStatuses', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/devices_switch_routing_interfaces.py b/ansible_collections/cisco/meraki/plugins/action/devices_switch_routing_interfaces.py new file mode 100644 index 000000000..774366850 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/devices_switch_routing_interfaces.py @@ -0,0 +1,372 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or +# https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, + meraki_compare_equality, + get_dict_result, +) +from ansible_collections.cisco.meraki.plugins.plugin_utils.exceptions import ( + InconsistentParameters, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + state=dict(type="str", default="present", choices=["present", "absent"]), + name=dict(type="str"), + subnet=dict(type="str"), + interfaceIp=dict(type="str"), + multicastRouting=dict(type="str"), + vlanId=dict(type="int"), + defaultGateway=dict(type="str"), + ospfSettings=dict(type="dict"), + ospfV3=dict(type="dict"), + ipv6=dict(type="dict"), + serial=dict(type="str"), + interfaceId=dict(type="str"), +)) + +required_if = [ + ("state", "present", ["interfaceId", "name", "serial"], True), + ("state", "absent", ["interfaceId", "name", "serial"], True), +] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class DevicesSwitchRoutingInterfaces(object): + def __init__(self, params, meraki): + self.meraki = meraki + self.new_object = dict( + name=params.get("name"), + subnet=params.get("subnet"), + interfaceIp=params.get("interfaceIp"), + multicastRouting=params.get("multicastRouting"), + vlanId=params.get("vlanId"), + defaultGateway=params.get("defaultGateway"), + ospfSettings=params.get("ospfSettings"), + ospfV3=params.get("ospfV3"), + ipv6=params.get("ipv6"), + serial=params.get("serial"), + interfaceId=params.get("interfaceId"), + ) + + def get_all_params(self, name=None, id=None): + new_object_params = {} + if self.new_object.get('serial') is not None or self.new_object.get('serial') is not None: + new_object_params['serial'] = self.new_object.get('serial') + return new_object_params + + def get_params_by_id(self, name=None, id=None): + new_object_params = {} + if self.new_object.get('serial') is not None or self.new_object.get('serial') is not None: + new_object_params['serial'] = self.new_object.get('serial') + if self.new_object.get('interfaceId') is not None or self.new_object.get('interface_id') is not None: + new_object_params['interfaceId'] = self.new_object.get('interfaceId') or \ + self.new_object.get('interface_id') + return new_object_params + + def create_params(self): + new_object_params = {} + if self.new_object.get('name') is not None or self.new_object.get('name') is not None: + new_object_params['name'] = self.new_object.get('name') or \ + self.new_object.get('name') + if self.new_object.get('subnet') is not None or self.new_object.get('subnet') is not None: + new_object_params['subnet'] = self.new_object.get('subnet') or \ + self.new_object.get('subnet') + if self.new_object.get('interfaceIp') is not None or self.new_object.get('interface_ip') is not None: + new_object_params['interfaceIp'] = self.new_object.get('interfaceIp') or \ + self.new_object.get('interface_ip') + if self.new_object.get('multicastRouting') is not None or self.new_object.get('multicast_routing') is not None: + new_object_params['multicastRouting'] = self.new_object.get('multicastRouting') or \ + self.new_object.get('multicast_routing') + if self.new_object.get('vlanId') is not None or self.new_object.get('vlan_id') is not None: + new_object_params['vlanId'] = self.new_object.get('vlanId') or \ + self.new_object.get('vlan_id') + if self.new_object.get('defaultGateway') is not None or self.new_object.get('default_gateway') is not None: + new_object_params['defaultGateway'] = self.new_object.get('defaultGateway') or \ + self.new_object.get('default_gateway') + if self.new_object.get('ospfSettings') is not None or self.new_object.get('ospf_settings') is not None: + new_object_params['ospfSettings'] = self.new_object.get('ospfSettings') or \ + self.new_object.get('ospf_settings') + if self.new_object.get('ospfV3') is not None or self.new_object.get('ospf_v3') is not None: + new_object_params['ospfV3'] = self.new_object.get('ospfV3') or \ + self.new_object.get('ospf_v3') + if self.new_object.get('ipv6') is not None or self.new_object.get('ipv6') is not None: + new_object_params['ipv6'] = self.new_object.get('ipv6') or \ + self.new_object.get('ipv6') + if self.new_object.get('serial') is not None or self.new_object.get('serial') is not None: + new_object_params['serial'] = self.new_object.get('serial') or \ + self.new_object.get('serial') + return new_object_params + + def delete_by_id_params(self): + new_object_params = {} + if self.new_object.get('serial') is not None or self.new_object.get('serial') is not None: + new_object_params['serial'] = self.new_object.get('serial') or \ + self.new_object.get('serial') + if self.new_object.get('interfaceId') is not None or self.new_object.get('interface_id') is not None: + new_object_params['interfaceId'] = self.new_object.get('interfaceId') or \ + self.new_object.get('interface_id') + return new_object_params + + def update_by_id_params(self): + new_object_params = {} + if self.new_object.get('name') is not None or self.new_object.get('name') is not None: + new_object_params['name'] = self.new_object.get('name') or \ + self.new_object.get('name') + if self.new_object.get('subnet') is not None or self.new_object.get('subnet') is not None: + new_object_params['subnet'] = self.new_object.get('subnet') or \ + self.new_object.get('subnet') + if self.new_object.get('interfaceIp') is not None or self.new_object.get('interface_ip') is not None: + new_object_params['interfaceIp'] = self.new_object.get('interfaceIp') or \ + self.new_object.get('interface_ip') + if self.new_object.get('multicastRouting') is not None or self.new_object.get('multicast_routing') is not None: + new_object_params['multicastRouting'] = self.new_object.get('multicastRouting') or \ + self.new_object.get('multicast_routing') + if self.new_object.get('vlanId') is not None or self.new_object.get('vlan_id') is not None: + new_object_params['vlanId'] = self.new_object.get('vlanId') or \ + self.new_object.get('vlan_id') + if self.new_object.get('defaultGateway') is not None or self.new_object.get('default_gateway') is not None: + new_object_params['defaultGateway'] = self.new_object.get('defaultGateway') or \ + self.new_object.get('default_gateway') + if self.new_object.get('ospfSettings') is not None or self.new_object.get('ospf_settings') is not None: + new_object_params['ospfSettings'] = self.new_object.get('ospfSettings') or \ + self.new_object.get('ospf_settings') + if self.new_object.get('ospfV3') is not None or self.new_object.get('ospf_v3') is not None: + new_object_params['ospfV3'] = self.new_object.get('ospfV3') or \ + self.new_object.get('ospf_v3') + if self.new_object.get('ipv6') is not None or self.new_object.get('ipv6') is not None: + new_object_params['ipv6'] = self.new_object.get('ipv6') or \ + self.new_object.get('ipv6') + if self.new_object.get('serial') is not None or self.new_object.get('serial') is not None: + new_object_params['serial'] = self.new_object.get('serial') or \ + self.new_object.get('serial') + if self.new_object.get('interfaceId') is not None or self.new_object.get('interface_id') is not None: + new_object_params['interfaceId'] = self.new_object.get('interfaceId') or \ + self.new_object.get('interface_id') + return new_object_params + + def get_object_by_name(self, name): + result = None + # NOTE: Does not have a get by name method or it is in another action + try: + items = self.meraki.exec_meraki( + family="switch", + function="getDeviceSwitchRoutingInterfaces", + params=self.get_all_params(name=name), + ) + if isinstance(items, dict): + if 'response' in items: + items = items.get('response') + result = get_dict_result(items, 'name', name) + if result is None: + result = items + except Exception as e: + print("Error: ", e) + result = None + return result + + def get_object_by_id(self, id): + result = None + try: + items = self.meraki.exec_meraki( + family="switch", + function="getDeviceSwitchRoutingInterface", + params=self.get_params_by_id() + ) + if isinstance(items, dict): + if 'response' in items: + items = items.get('response') + result = get_dict_result(items, 'interfaceId', id) + except Exception as e: + print("Error: ", e) + result = None + return result + + def exists(self): + id_exists = False + name_exists = False + prev_obj = None + o_id = self.new_object.get("id") + o_id = o_id or self.new_object.get( + "interface_id") or self.new_object.get("interfaceId") + name = self.new_object.get("name") + if o_id: + prev_obj = self.get_object_by_id(o_id) + id_exists = prev_obj is not None and isinstance(prev_obj, dict) + if not id_exists and name: + prev_obj = self.get_object_by_name(name) + name_exists = prev_obj is not None and isinstance(prev_obj, dict) + if name_exists: + _id = prev_obj.get("id") + _id = _id or prev_obj.get("interfaceId") + if id_exists and name_exists and o_id != _id: + raise InconsistentParameters( + "The 'id' and 'name' params don't refer to the same object") + if _id: + self.new_object.update(dict(id=_id)) + self.new_object.update(dict(interfaceId=_id)) + if _id: + prev_obj = self.get_object_by_id(_id) + it_exists = prev_obj is not None and isinstance(prev_obj, dict) + return (it_exists, prev_obj) + + def requires_update(self, current_obj): + requested_obj = self.new_object + + obj_params = [ + ("name", "name"), + ("subnet", "subnet"), + ("interfaceIp", "interfaceIp"), + ("multicastRouting", "multicastRouting"), + ("vlanId", "vlanId"), + ("defaultGateway", "defaultGateway"), + ("ospfSettings", "ospfSettings"), + ("ospfV3", "ospfV3"), + ("ipv6", "ipv6"), + ("serial", "serial"), + ("interfaceId", "interfaceId"), + ] + # Method 1. Params present in request (Ansible) obj are the same as the current (DNAC) params + # If any does not have eq params, it requires update + return any(not meraki_compare_equality(current_obj.get(meraki_param), + requested_obj.get(ansible_param)) + for (meraki_param, ansible_param) in obj_params) + + def create(self): + result = self.meraki.exec_meraki( + family="switch", + function="createDeviceSwitchRoutingInterface", + params=self.create_params(), + op_modifies=True, + ) + return result + + def update(self): + id = self.new_object.get("id") + id = id or self.new_object.get("interfaceId") + name = self.new_object.get("name") + result = None + if not id: + prev_obj_name = self.get_object_by_name(name) + id_ = None + if prev_obj_name: + id_ = prev_obj_name.get("id") + id_ = id_ or prev_obj_name.get("interfaceId") + if id_: + self.new_object.update(dict(interfaceId=id_)) + result = self.meraki.exec_meraki( + family="switch", + function="updateDeviceSwitchRoutingInterface", + params=self.update_by_id_params(), + op_modifies=True, + ) + return result + + def delete(self): + id = self.new_object.get("id") + id = id or self.new_object.get("interfaceId") + name = self.new_object.get("name") + result = None + if not id: + prev_obj_name = self.get_object_by_name(name) + id_ = None + if prev_obj_name: + id_ = prev_obj_name.get("id") + id_ = id_ or prev_obj_name.get("interfaceId") + if id_: + self.new_object.update(dict(interfaceId=id_)) + result = self.meraki.exec_meraki( + family="switch", + function="deleteDeviceSwitchRoutingInterface", + params=self.delete_by_id_params(), + ) + return result + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = False + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + meraki = MERAKI(self._task.args) + obj = DevicesSwitchRoutingInterfaces(self._task.args, meraki) + + state = self._task.args.get("state") + + response = None + + if state == "present": + (obj_exists, prev_obj) = obj.exists() + if obj_exists: + if obj.requires_update(prev_obj): + response = obj.update() + meraki.object_updated() + else: + response = prev_obj + meraki.object_already_present() + else: + response = obj.create() + meraki.object_created() + + elif state == "absent": + (obj_exists, prev_obj) = obj.exists() + if obj_exists: + response = obj.delete() + meraki.object_deleted() + else: + meraki.object_already_absent() + + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/devices_switch_routing_interfaces_dhcp.py b/ansible_collections/cisco/meraki/plugins/action/devices_switch_routing_interfaces_dhcp.py new file mode 100644 index 000000000..4fdb74e4e --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/devices_switch_routing_interfaces_dhcp.py @@ -0,0 +1,267 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or +# https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, + meraki_compare_equality, + get_dict_result, +) +from ansible_collections.cisco.meraki.plugins.plugin_utils.exceptions import ( + InconsistentParameters, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + state=dict(type="str", default="present", choices=["present"]), + dhcpMode=dict(type="str"), + dhcpRelayServerIps=dict(type="list"), + dhcpLeaseTime=dict(type="str"), + dnsNameserversOption=dict(type="str"), + dnsCustomNameservers=dict(type="list"), + bootOptionsEnabled=dict(type="bool"), + bootNextServer=dict(type="str"), + bootFileName=dict(type="str"), + dhcpOptions=dict(type="list"), + reservedIpRanges=dict(type="list"), + fixedIpAssignments=dict(type="list"), + serial=dict(type="str"), + interfaceId=dict(type="str"), +)) + +required_if = [ + ("state", "present", ["interfaceId", "serial"], True), +] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class DevicesSwitchRoutingInterfacesDhcp(object): + def __init__(self, params, meraki): + self.meraki = meraki + self.new_object = dict( + dhcpMode=params.get("dhcpMode"), + dhcpRelayServerIps=params.get("dhcpRelayServerIps"), + dhcpLeaseTime=params.get("dhcpLeaseTime"), + dnsNameserversOption=params.get("dnsNameserversOption"), + dnsCustomNameservers=params.get("dnsCustomNameservers"), + bootOptionsEnabled=params.get("bootOptionsEnabled"), + bootNextServer=params.get("bootNextServer"), + bootFileName=params.get("bootFileName"), + dhcpOptions=params.get("dhcpOptions"), + reservedIpRanges=params.get("reservedIpRanges"), + fixedIpAssignments=params.get("fixedIpAssignments"), + serial=params.get("serial"), + interface_id=params.get("interfaceId"), + ) + + def get_all_params(self, name=None, id=None): + new_object_params = {} + if self.new_object.get('serial') is not None or self.new_object.get('serial') is not None: + new_object_params['serial'] = self.new_object.get('serial') + if self.new_object.get('interfaceId') is not None or self.new_object.get('interface_id') is not None: + new_object_params['interfaceId'] = self.new_object.get('interfaceId') or \ + self.new_object.get('interface_id') + return new_object_params + + def update_all_params(self): + new_object_params = {} + if self.new_object.get('dhcpMode') is not None or self.new_object.get('dhcp_mode') is not None: + new_object_params['dhcpMode'] = self.new_object.get('dhcpMode') or \ + self.new_object.get('dhcp_mode') + if self.new_object.get('dhcpRelayServerIps') is not None or self.new_object.get('dhcp_relay_server_ips') is not None: + new_object_params['dhcpRelayServerIps'] = self.new_object.get('dhcpRelayServerIps') or \ + self.new_object.get('dhcp_relay_server_ips') + if self.new_object.get('dhcpLeaseTime') is not None or self.new_object.get('dhcp_lease_time') is not None: + new_object_params['dhcpLeaseTime'] = self.new_object.get('dhcpLeaseTime') or \ + self.new_object.get('dhcp_lease_time') + if self.new_object.get('dnsNameserversOption') is not None or self.new_object.get('dns_nameservers_option') is not None: + new_object_params['dnsNameserversOption'] = self.new_object.get('dnsNameserversOption') or \ + self.new_object.get('dns_nameservers_option') + if self.new_object.get('dnsCustomNameservers') is not None or self.new_object.get('dns_custom_nameservers') is not None: + new_object_params['dnsCustomNameservers'] = self.new_object.get('dnsCustomNameservers') or \ + self.new_object.get('dns_custom_nameservers') + if self.new_object.get('bootOptionsEnabled') is not None or self.new_object.get('boot_options_enabled') is not None: + new_object_params['bootOptionsEnabled'] = self.new_object.get('bootOptionsEnabled') + if self.new_object.get('bootNextServer') is not None or self.new_object.get('boot_next_server') is not None: + new_object_params['bootNextServer'] = self.new_object.get('bootNextServer') or \ + self.new_object.get('boot_next_server') + if self.new_object.get('bootFileName') is not None or self.new_object.get('boot_file_name') is not None: + new_object_params['bootFileName'] = self.new_object.get('bootFileName') or \ + self.new_object.get('boot_file_name') + if self.new_object.get('dhcpOptions') is not None or self.new_object.get('dhcp_options') is not None: + new_object_params['dhcpOptions'] = self.new_object.get('dhcpOptions') or \ + self.new_object.get('dhcp_options') + if self.new_object.get('reservedIpRanges') is not None or self.new_object.get('reserved_ip_ranges') is not None: + new_object_params['reservedIpRanges'] = self.new_object.get('reservedIpRanges') or \ + self.new_object.get('reserved_ip_ranges') + if self.new_object.get('fixedIpAssignments') is not None or self.new_object.get('fixed_ip_assignments') is not None: + new_object_params['fixedIpAssignments'] = self.new_object.get('fixedIpAssignments') or \ + self.new_object.get('fixed_ip_assignments') + if self.new_object.get('serial') is not None or self.new_object.get('serial') is not None: + new_object_params['serial'] = self.new_object.get('serial') or \ + self.new_object.get('serial') + if self.new_object.get('interfaceId') is not None or self.new_object.get('interface_id') is not None: + new_object_params['interfaceId'] = self.new_object.get('interfaceId') or \ + self.new_object.get('interface_id') + return new_object_params + + def get_object_by_name(self, name): + result = None + # NOTE: Does not have a get by name method, using get all + try: + items = self.meraki.exec_meraki( + family="switch", + function="getDeviceSwitchRoutingInterfaceDhcp", + params=self.get_all_params(name=name), + ) + if isinstance(items, dict): + if 'response' in items: + items = items.get('response') + result = get_dict_result(items, 'name', name) + if result is None: + result = items + except Exception as e: + print("Error: ", e) + result = None + return result + + def get_object_by_id(self, id): + result = None + # NOTE: Does not have a get by id method or it is in another action + return result + + def exists(self): + prev_obj = None + id_exists = False + name_exists = False + o_id = self.new_object.get("serial") + name = self.new_object.get("name") + if o_id: + prev_obj = self.get_object_by_name(o_id) + id_exists = prev_obj is not None and isinstance(prev_obj, dict) + if not id_exists and name: + prev_obj = self.get_object_by_name(name) + name_exists = prev_obj is not None and isinstance(prev_obj, dict) + if name_exists: + _id = prev_obj.get("id") + if id_exists and name_exists and o_id != _id: + raise InconsistentParameters( + "The 'id' and 'name' params don't refer to the same object") + if _id: + self.new_object.update(dict(id=_id)) + it_exists = prev_obj is not None and isinstance(prev_obj, dict) + return (it_exists, prev_obj) + + def requires_update(self, current_obj): + requested_obj = self.new_object + + obj_params = [ + ("dhcpMode", "dhcpMode"), + ("dhcpRelayServerIps", "dhcpRelayServerIps"), + ("dhcpLeaseTime", "dhcpLeaseTime"), + ("dnsNameserversOption", "dnsNameserversOption"), + ("dnsCustomNameservers", "dnsCustomNameservers"), + ("bootOptionsEnabled", "bootOptionsEnabled"), + ("bootNextServer", "bootNextServer"), + ("bootFileName", "bootFileName"), + ("dhcpOptions", "dhcpOptions"), + ("reservedIpRanges", "reservedIpRanges"), + ("fixedIpAssignments", "fixedIpAssignments"), + ("serial", "serial"), + ("interfaceId", "interfaceId"), + ] + # Method 1. Params present in request (Ansible) obj are the same as the current (ISE) params + # If any does not have eq params, it requires update + return any(not meraki_compare_equality(current_obj.get(meraki_param), + requested_obj.get(ansible_param)) + for (meraki_param, ansible_param) in obj_params) + + def update(self): + id = self.new_object.get("id") + name = self.new_object.get("name") + result = None + result = self.meraki.exec_meraki( + family="switch", + function="updateDeviceSwitchRoutingInterfaceDhcp", + params=self.update_all_params(), + op_modifies=True, + ) + return result + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = False + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + meraki = MERAKI(self._task.args) + obj = DevicesSwitchRoutingInterfacesDhcp(self._task.args, meraki) + + state = self._task.args.get("state") + + response = None + if state == "present": + (obj_exists, prev_obj) = obj.exists() + if obj_exists: + if obj.requires_update(prev_obj): + response = obj.update() + meraki.object_updated() + else: + response = prev_obj + meraki.object_already_present() + else: + meraki.fail_json( + "Object does not exists, plugin only has update") + + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/devices_switch_routing_interfaces_dhcp_info.py b/ansible_collections/cisco/meraki/plugins/action/devices_switch_routing_interfaces_dhcp_info.py new file mode 100644 index 000000000..2cea7850b --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/devices_switch_routing_interfaces_dhcp_info.py @@ -0,0 +1,94 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + serial=dict(type="str"), + interfaceId=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_all(self, params): + new_object = {} + if params.get("serial") is not None: + new_object["serial"] = params.get( + "serial") + if params.get("interfaceId") is not None: + new_object["interfaceId"] = params.get( + "interfaceId") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="switch", + function='getDeviceSwitchRoutingInterfaceDhcp', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/devices_switch_routing_interfaces_info.py b/ansible_collections/cisco/meraki/plugins/action/devices_switch_routing_interfaces_info.py new file mode 100644 index 000000000..2d65db8f8 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/devices_switch_routing_interfaces_info.py @@ -0,0 +1,112 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + serial=dict(type="str"), + interfaceId=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_object(self, params): + new_object = {} + if params.get("serial") is not None: + new_object["serial"] = params.get( + "serial") + if params.get("interfaceId") is not None: + new_object["interfaceId"] = params.get( + "interfaceId") + return new_object + + def get_all(self, params): + new_object = {} + if params.get("serial") is not None: + new_object["serial"] = params.get( + "serial") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + id = self._task.args.get("interfaceId") + if id: + response = meraki.exec_meraki( + family="switch", + function='getDeviceSwitchRoutingInterface', + params=self.get_object(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result + if not id: + response = meraki.exec_meraki( + family="switch", + function='getDeviceSwitchRoutingInterfaces', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/devices_switch_routing_static_routes.py b/ansible_collections/cisco/meraki/plugins/action/devices_switch_routing_static_routes.py new file mode 100644 index 000000000..e24a6e721 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/devices_switch_routing_static_routes.py @@ -0,0 +1,332 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or +# https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, + meraki_compare_equality, + get_dict_result, +) +from ansible_collections.cisco.meraki.plugins.plugin_utils.exceptions import ( + InconsistentParameters, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + state=dict(type="str", default="present", choices=["present", "absent"]), + name=dict(type="str"), + subnet=dict(type="str"), + nextHopIp=dict(type="str"), + advertiseViaOspfEnabled=dict(type="bool"), + preferOverOspfRoutesEnabled=dict(type="bool"), + serial=dict(type="str"), + staticRouteId=dict(type="str"), +)) + +required_if = [ + ("state", "present", ["name", "serial", "staticRouteId"], True), + ("state", "absent", ["name", "serial", "staticRouteId"], True), +] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class DevicesSwitchRoutingStaticRoutes(object): + def __init__(self, params, meraki): + self.meraki = meraki + self.new_object = dict( + name=params.get("name"), + subnet=params.get("subnet"), + nextHopIp=params.get("nextHopIp"), + advertiseViaOspfEnabled=params.get("advertiseViaOspfEnabled"), + preferOverOspfRoutesEnabled=params.get("preferOverOspfRoutesEnabled"), + serial=params.get("serial"), + staticRouteId=params.get("staticRouteId"), + ) + + def get_all_params(self, name=None, id=None): + new_object_params = {} + if self.new_object.get('serial') is not None or self.new_object.get('serial') is not None: + new_object_params['serial'] = self.new_object.get('serial') + return new_object_params + + def get_params_by_id(self, name=None, id=None): + new_object_params = {} + if self.new_object.get('serial') is not None or self.new_object.get('serial') is not None: + new_object_params['serial'] = self.new_object.get('serial') + if self.new_object.get('staticRouteId') is not None or self.new_object.get('static_route_id') is not None: + new_object_params['staticRouteId'] = self.new_object.get('staticRouteId') or \ + self.new_object.get('static_route_id') + return new_object_params + + def create_params(self): + new_object_params = {} + if self.new_object.get('name') is not None or self.new_object.get('name') is not None: + new_object_params['name'] = self.new_object.get('name') or \ + self.new_object.get('name') + if self.new_object.get('subnet') is not None or self.new_object.get('subnet') is not None: + new_object_params['subnet'] = self.new_object.get('subnet') or \ + self.new_object.get('subnet') + if self.new_object.get('nextHopIp') is not None or self.new_object.get('next_hop_ip') is not None: + new_object_params['nextHopIp'] = self.new_object.get('nextHopIp') or \ + self.new_object.get('next_hop_ip') + if self.new_object.get('advertiseViaOspfEnabled') is not None or self.new_object.get('advertise_via_ospf_enabled') is not None: + new_object_params['advertiseViaOspfEnabled'] = self.new_object.get('advertiseViaOspfEnabled') + if self.new_object.get('preferOverOspfRoutesEnabled') is not None or self.new_object.get('prefer_over_ospf_routes_enabled') is not None: + new_object_params['preferOverOspfRoutesEnabled'] = self.new_object.get('preferOverOspfRoutesEnabled') + if self.new_object.get('serial') is not None or self.new_object.get('serial') is not None: + new_object_params['serial'] = self.new_object.get('serial') or \ + self.new_object.get('serial') + return new_object_params + + def delete_by_id_params(self): + new_object_params = {} + if self.new_object.get('serial') is not None or self.new_object.get('serial') is not None: + new_object_params['serial'] = self.new_object.get('serial') or \ + self.new_object.get('serial') + if self.new_object.get('staticRouteId') is not None or self.new_object.get('static_route_id') is not None: + new_object_params['staticRouteId'] = self.new_object.get('staticRouteId') or \ + self.new_object.get('static_route_id') + return new_object_params + + def update_by_id_params(self): + new_object_params = {} + if self.new_object.get('name') is not None or self.new_object.get('name') is not None: + new_object_params['name'] = self.new_object.get('name') or \ + self.new_object.get('name') + if self.new_object.get('subnet') is not None or self.new_object.get('subnet') is not None: + new_object_params['subnet'] = self.new_object.get('subnet') or \ + self.new_object.get('subnet') + if self.new_object.get('nextHopIp') is not None or self.new_object.get('next_hop_ip') is not None: + new_object_params['nextHopIp'] = self.new_object.get('nextHopIp') or \ + self.new_object.get('next_hop_ip') + if self.new_object.get('advertiseViaOspfEnabled') is not None or self.new_object.get('advertise_via_ospf_enabled') is not None: + new_object_params['advertiseViaOspfEnabled'] = self.new_object.get('advertiseViaOspfEnabled') + if self.new_object.get('preferOverOspfRoutesEnabled') is not None or self.new_object.get('prefer_over_ospf_routes_enabled') is not None: + new_object_params['preferOverOspfRoutesEnabled'] = self.new_object.get('preferOverOspfRoutesEnabled') + if self.new_object.get('serial') is not None or self.new_object.get('serial') is not None: + new_object_params['serial'] = self.new_object.get('serial') or \ + self.new_object.get('serial') + if self.new_object.get('staticRouteId') is not None or self.new_object.get('static_route_id') is not None: + new_object_params['staticRouteId'] = self.new_object.get('staticRouteId') or \ + self.new_object.get('static_route_id') + return new_object_params + + def get_object_by_name(self, name): + result = None + # NOTE: Does not have a get by name method or it is in another action + try: + items = self.meraki.exec_meraki( + family="switch", + function="getDeviceSwitchRoutingStaticRoutes", + params=self.get_all_params(name=name), + ) + if isinstance(items, dict): + if 'response' in items: + items = items.get('response') + result = get_dict_result(items, 'name', name) + if result is None: + result = items + except Exception as e: + print("Error: ", e) + result = None + return result + + def get_object_by_id(self, id): + result = None + try: + items = self.meraki.exec_meraki( + family="switch", + function="getDeviceSwitchRoutingStaticRoute", + params=self.get_params_by_id() + ) + if isinstance(items, dict): + if 'response' in items: + items = items.get('response') + result = get_dict_result(items, 'staticRouteId', id) + except Exception as e: + print("Error: ", e) + result = None + return result + + def exists(self): + id_exists = False + name_exists = False + prev_obj = None + o_id = self.new_object.get("id") + o_id = o_id or self.new_object.get( + "static_route_id") or self.new_object.get("staticRouteId") + name = self.new_object.get("name") + if o_id: + prev_obj = self.get_object_by_id(o_id) + id_exists = prev_obj is not None and isinstance(prev_obj, dict) + if not id_exists and name: + prev_obj = self.get_object_by_name(name) + name_exists = prev_obj is not None and isinstance(prev_obj, dict) + if name_exists: + _id = prev_obj.get("id") + _id = _id or prev_obj.get("staticRouteId") + if id_exists and name_exists and o_id != _id: + raise InconsistentParameters( + "The 'id' and 'name' params don't refer to the same object") + if _id: + self.new_object.update(dict(id=_id)) + self.new_object.update(dict(staticRouteId=_id)) + if _id: + prev_obj = self.get_object_by_id(_id) + it_exists = prev_obj is not None and isinstance(prev_obj, dict) + return (it_exists, prev_obj) + + def requires_update(self, current_obj): + requested_obj = self.new_object + + obj_params = [ + ("name", "name"), + ("subnet", "subnet"), + ("nextHopIp", "nextHopIp"), + ("advertiseViaOspfEnabled", "advertiseViaOspfEnabled"), + ("preferOverOspfRoutesEnabled", "preferOverOspfRoutesEnabled"), + ("serial", "serial"), + ("staticRouteId", "staticRouteId"), + ] + # Method 1. Params present in request (Ansible) obj are the same as the current (DNAC) params + # If any does not have eq params, it requires update + return any(not meraki_compare_equality(current_obj.get(meraki_param), + requested_obj.get(ansible_param)) + for (meraki_param, ansible_param) in obj_params) + + def create(self): + result = self.meraki.exec_meraki( + family="switch", + function="createDeviceSwitchRoutingStaticRoute", + params=self.create_params(), + op_modifies=True, + ) + return result + + def update(self): + id = self.new_object.get("id") + id = id or self.new_object.get("staticRouteId") + name = self.new_object.get("name") + result = None + if not id: + prev_obj_name = self.get_object_by_name(name) + id_ = None + if prev_obj_name: + id_ = prev_obj_name.get("id") + id_ = id_ or prev_obj_name.get("staticRouteId") + if id_: + self.new_object.update(dict(staticRouteId=id_)) + result = self.meraki.exec_meraki( + family="switch", + function="updateDeviceSwitchRoutingStaticRoute", + params=self.update_by_id_params(), + op_modifies=True, + ) + return result + + def delete(self): + id = self.new_object.get("id") + id = id or self.new_object.get("staticRouteId") + name = self.new_object.get("name") + result = None + if not id: + prev_obj_name = self.get_object_by_name(name) + id_ = None + if prev_obj_name: + id_ = prev_obj_name.get("id") + id_ = id_ or prev_obj_name.get("staticRouteId") + if id_: + self.new_object.update(dict(staticRouteId=id_)) + result = self.meraki.exec_meraki( + family="switch", + function="deleteDeviceSwitchRoutingStaticRoute", + params=self.delete_by_id_params(), + ) + return result + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = False + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + meraki = MERAKI(self._task.args) + obj = DevicesSwitchRoutingStaticRoutes(self._task.args, meraki) + + state = self._task.args.get("state") + + response = None + + if state == "present": + (obj_exists, prev_obj) = obj.exists() + if obj_exists: + if obj.requires_update(prev_obj): + response = obj.update() + meraki.object_updated() + else: + response = prev_obj + meraki.object_already_present() + else: + response = obj.create() + meraki.object_created() + + elif state == "absent": + (obj_exists, prev_obj) = obj.exists() + if obj_exists: + response = obj.delete() + meraki.object_deleted() + else: + meraki.object_already_absent() + + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/devices_switch_routing_static_routes_info.py b/ansible_collections/cisco/meraki/plugins/action/devices_switch_routing_static_routes_info.py new file mode 100644 index 000000000..630ba950c --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/devices_switch_routing_static_routes_info.py @@ -0,0 +1,112 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + serial=dict(type="str"), + staticRouteId=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_object(self, params): + new_object = {} + if params.get("serial") is not None: + new_object["serial"] = params.get( + "serial") + if params.get("staticRouteId") is not None: + new_object["staticRouteId"] = params.get( + "staticRouteId") + return new_object + + def get_all(self, params): + new_object = {} + if params.get("serial") is not None: + new_object["serial"] = params.get( + "serial") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + id = self._task.args.get("staticRouteId") + if id: + response = meraki.exec_meraki( + family="switch", + function='getDeviceSwitchRoutingStaticRoute', + params=self.get_object(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result + if not id: + response = meraki.exec_meraki( + family="switch", + function='getDeviceSwitchRoutingStaticRoutes', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/devices_switch_warm_spare.py b/ansible_collections/cisco/meraki/plugins/action/devices_switch_warm_spare.py new file mode 100644 index 000000000..85fdd803c --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/devices_switch_warm_spare.py @@ -0,0 +1,204 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or +# https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, + meraki_compare_equality, + get_dict_result, +) +from ansible_collections.cisco.meraki.plugins.plugin_utils.exceptions import ( + InconsistentParameters, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + state=dict(type="str", default="present", choices=["present"]), + enabled=dict(type="bool"), + spareSerial=dict(type="str"), + serial=dict(type="str"), +)) + +required_if = [ + ("state", "present", ["serial"], True), +] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class DevicesSwitchWarmSpare(object): + def __init__(self, params, meraki): + self.meraki = meraki + self.new_object = dict( + enabled=params.get("enabled"), + spareSerial=params.get("spareSerial"), + serial=params.get("serial"), + ) + + def get_all_params(self, name=None, id=None): + new_object_params = {} + if self.new_object.get('serial') is not None or self.new_object.get('serial') is not None: + new_object_params['serial'] = self.new_object.get('serial') + return new_object_params + + def update_all_params(self): + new_object_params = {} + if self.new_object.get('enabled') is not None or self.new_object.get('enabled') is not None: + new_object_params['enabled'] = self.new_object.get('enabled') + if self.new_object.get('spareSerial') is not None or self.new_object.get('spare_serial') is not None: + new_object_params['spareSerial'] = self.new_object.get('spareSerial') or \ + self.new_object.get('spare_serial') + if self.new_object.get('serial') is not None or self.new_object.get('serial') is not None: + new_object_params['serial'] = self.new_object.get('serial') or \ + self.new_object.get('serial') + return new_object_params + + def get_object_by_name(self, name): + result = None + # NOTE: Does not have a get by name method, using get all + try: + items = self.meraki.exec_meraki( + family="switch", + function="getDeviceSwitchWarmSpare", + params=self.get_all_params(name=name), + ) + if isinstance(items, dict): + if 'response' in items: + items = items.get('response') + result = get_dict_result(items, 'name', name) + if result is None: + result = items + except Exception as e: + print("Error: ", e) + result = None + return result + + def get_object_by_id(self, id): + result = None + # NOTE: Does not have a get by id method or it is in another action + return result + + def exists(self): + prev_obj = None + id_exists = False + name_exists = False + o_id = self.new_object.get("serial") + name = self.new_object.get("name") + if o_id: + prev_obj = self.get_object_by_name(o_id) + id_exists = prev_obj is not None and isinstance(prev_obj, dict) + if not id_exists and name: + prev_obj = self.get_object_by_name(name) + name_exists = prev_obj is not None and isinstance(prev_obj, dict) + if name_exists: + _id = prev_obj.get("id") + if id_exists and name_exists and o_id != _id: + raise InconsistentParameters( + "The 'id' and 'name' params don't refer to the same object") + if _id: + self.new_object.update(dict(id=_id)) + it_exists = prev_obj is not None and isinstance(prev_obj, dict) + return (it_exists, prev_obj) + + def requires_update(self, current_obj): + requested_obj = self.new_object + + obj_params = [ + ("enabled", "enabled"), + ("spareSerial", "spareSerial"), + ("serial", "serial"), + ] + # Method 1. Params present in request (Ansible) obj are the same as the current (ISE) params + # If any does not have eq params, it requires update + return any(not meraki_compare_equality(current_obj.get(meraki_param), + requested_obj.get(ansible_param)) + for (meraki_param, ansible_param) in obj_params) + + def update(self): + id = self.new_object.get("id") + name = self.new_object.get("name") + result = None + result = self.meraki.exec_meraki( + family="switch", + function="updateDeviceSwitchWarmSpare", + params=self.update_all_params(), + op_modifies=True, + ) + return result + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = False + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + meraki = MERAKI(self._task.args) + obj = DevicesSwitchWarmSpare(self._task.args, meraki) + + state = self._task.args.get("state") + + response = None + if state == "present": + (obj_exists, prev_obj) = obj.exists() + if obj_exists: + if obj.requires_update(prev_obj): + response = obj.update() + meraki.object_updated() + else: + response = prev_obj + meraki.object_already_present() + else: + meraki.fail_json( + "Object does not exists, plugin only has update") + + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/devices_switch_warm_spare_info.py b/ansible_collections/cisco/meraki/plugins/action/devices_switch_warm_spare_info.py new file mode 100644 index 000000000..368deb259 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/devices_switch_warm_spare_info.py @@ -0,0 +1,90 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + serial=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_all(self, params): + new_object = {} + if params.get("serial") is not None: + new_object["serial"] = params.get( + "serial") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="switch", + function='getDeviceSwitchWarmSpare', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/devices_wireless_bluetooth_settings.py b/ansible_collections/cisco/meraki/plugins/action/devices_wireless_bluetooth_settings.py new file mode 100644 index 000000000..dd3712df6 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/devices_wireless_bluetooth_settings.py @@ -0,0 +1,211 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or +# https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, + meraki_compare_equality, + get_dict_result, +) +from ansible_collections.cisco.meraki.plugins.plugin_utils.exceptions import ( + InconsistentParameters, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + state=dict(type="str", default="present", choices=["present"]), + uuid=dict(type="str"), + major=dict(type="int"), + minor=dict(type="int"), + serial=dict(type="str"), +)) + +required_if = [ + ("state", "present", ["serial"], True), +] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class DevicesWirelessBluetoothSettings(object): + def __init__(self, params, meraki): + self.meraki = meraki + self.new_object = dict( + uuid=params.get("uuid"), + major=params.get("major"), + minor=params.get("minor"), + serial=params.get("serial"), + ) + + def get_all_params(self, name=None, id=None): + new_object_params = {} + if self.new_object.get('serial') is not None or self.new_object.get('serial') is not None: + new_object_params['serial'] = self.new_object.get('serial') + return new_object_params + + def update_all_params(self): + new_object_params = {} + if self.new_object.get('uuid') is not None or self.new_object.get('uuid') is not None: + new_object_params['uuid'] = self.new_object.get('uuid') or \ + self.new_object.get('uuid') + if self.new_object.get('major') is not None or self.new_object.get('major') is not None: + new_object_params['major'] = self.new_object.get('major') or \ + self.new_object.get('major') + if self.new_object.get('minor') is not None or self.new_object.get('minor') is not None: + new_object_params['minor'] = self.new_object.get('minor') or \ + self.new_object.get('minor') + if self.new_object.get('serial') is not None or self.new_object.get('serial') is not None: + new_object_params['serial'] = self.new_object.get('serial') or \ + self.new_object.get('serial') + return new_object_params + + def get_object_by_name(self, name): + result = None + # NOTE: Does not have a get by name method, using get all + try: + items = self.meraki.exec_meraki( + family="wireless", + function="getDeviceWirelessBluetoothSettings", + params=self.get_all_params(name=name), + ) + if isinstance(items, dict): + if 'response' in items: + items = items.get('response') + result = get_dict_result(items, 'name', name) + if result is None: + result = items + except Exception as e: + print("Error: ", e) + result = None + return result + + def get_object_by_id(self, id): + result = None + # NOTE: Does not have a get by id method or it is in another action + return result + + def exists(self): + prev_obj = None + id_exists = False + name_exists = False + o_id = self.new_object.get("serial") + name = self.new_object.get("name") + if o_id: + prev_obj = self.get_object_by_name(o_id) + id_exists = prev_obj is not None and isinstance(prev_obj, dict) + if not id_exists and name: + prev_obj = self.get_object_by_name(name) + name_exists = prev_obj is not None and isinstance(prev_obj, dict) + if name_exists: + _id = prev_obj.get("id") + if id_exists and name_exists and o_id != _id: + raise InconsistentParameters( + "The 'id' and 'name' params don't refer to the same object") + if _id: + self.new_object.update(dict(id=_id)) + it_exists = prev_obj is not None and isinstance(prev_obj, dict) + return (it_exists, prev_obj) + + def requires_update(self, current_obj): + requested_obj = self.new_object + + obj_params = [ + ("uuid", "uuid"), + ("major", "major"), + ("minor", "minor"), + ("serial", "serial"), + ] + # Method 1. Params present in request (Ansible) obj are the same as the current (ISE) params + # If any does not have eq params, it requires update + return any(not meraki_compare_equality(current_obj.get(meraki_param), + requested_obj.get(ansible_param)) + for (meraki_param, ansible_param) in obj_params) + + def update(self): + id = self.new_object.get("id") + name = self.new_object.get("name") + result = None + result = self.meraki.exec_meraki( + family="wireless", + function="updateDeviceWirelessBluetoothSettings", + params=self.update_all_params(), + op_modifies=True, + ) + return result + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = False + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + meraki = MERAKI(self._task.args) + obj = DevicesWirelessBluetoothSettings(self._task.args, meraki) + + state = self._task.args.get("state") + + response = None + if state == "present": + (obj_exists, prev_obj) = obj.exists() + if obj_exists: + if obj.requires_update(prev_obj): + response = obj.update() + meraki.object_updated() + else: + response = prev_obj + meraki.object_already_present() + else: + meraki.fail_json( + "Object does not exists, plugin only has update") + + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/devices_wireless_bluetooth_settings_info.py b/ansible_collections/cisco/meraki/plugins/action/devices_wireless_bluetooth_settings_info.py new file mode 100644 index 000000000..41cd9ee3e --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/devices_wireless_bluetooth_settings_info.py @@ -0,0 +1,90 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + serial=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_all(self, params): + new_object = {} + if params.get("serial") is not None: + new_object["serial"] = params.get( + "serial") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="wireless", + function='getDeviceWirelessBluetoothSettings', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/devices_wireless_connection_stats_info.py b/ansible_collections/cisco/meraki/plugins/action/devices_wireless_connection_stats_info.py new file mode 100644 index 000000000..3abd28e29 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/devices_wireless_connection_stats_info.py @@ -0,0 +1,118 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + serial=dict(type="str"), + t0=dict(type="str"), + t1=dict(type="str"), + timespan=dict(type="float"), + band=dict(type="str"), + ssid=dict(type="int"), + vlan=dict(type="int"), + apTag=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_all(self, params): + new_object = {} + if params.get("serial") is not None: + new_object["serial"] = params.get( + "serial") + if params.get("t0") is not None: + new_object["t0"] = params.get( + "t0") + if params.get("t1") is not None: + new_object["t1"] = params.get( + "t1") + if params.get("timespan") is not None: + new_object["timespan"] = params.get( + "timespan") + if params.get("band") is not None: + new_object["band"] = params.get( + "band") + if params.get("ssid") is not None: + new_object["ssid"] = params.get( + "ssid") + if params.get("vlan") is not None: + new_object["vlan"] = params.get( + "vlan") + if params.get("apTag") is not None: + new_object["apTag"] = params.get( + "apTag") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="wireless", + function='getDeviceWirelessConnectionStats', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/devices_wireless_latency_stats_info.py b/ansible_collections/cisco/meraki/plugins/action/devices_wireless_latency_stats_info.py new file mode 100644 index 000000000..bb8f31be1 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/devices_wireless_latency_stats_info.py @@ -0,0 +1,122 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + serial=dict(type="str"), + t0=dict(type="str"), + t1=dict(type="str"), + timespan=dict(type="float"), + band=dict(type="str"), + ssid=dict(type="int"), + vlan=dict(type="int"), + apTag=dict(type="str"), + fields=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_all(self, params): + new_object = {} + if params.get("serial") is not None: + new_object["serial"] = params.get( + "serial") + if params.get("t0") is not None: + new_object["t0"] = params.get( + "t0") + if params.get("t1") is not None: + new_object["t1"] = params.get( + "t1") + if params.get("timespan") is not None: + new_object["timespan"] = params.get( + "timespan") + if params.get("band") is not None: + new_object["band"] = params.get( + "band") + if params.get("ssid") is not None: + new_object["ssid"] = params.get( + "ssid") + if params.get("vlan") is not None: + new_object["vlan"] = params.get( + "vlan") + if params.get("apTag") is not None: + new_object["apTag"] = params.get( + "apTag") + if params.get("fields") is not None: + new_object["fields"] = params.get( + "fields") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="wireless", + function='getDeviceWirelessLatencyStats', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/devices_wireless_radio_settings.py b/ansible_collections/cisco/meraki/plugins/action/devices_wireless_radio_settings.py new file mode 100644 index 000000000..72dad3f48 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/devices_wireless_radio_settings.py @@ -0,0 +1,211 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or +# https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, + meraki_compare_equality, + get_dict_result, +) +from ansible_collections.cisco.meraki.plugins.plugin_utils.exceptions import ( + InconsistentParameters, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + state=dict(type="str", default="present", choices=["present"]), + rfProfileId=dict(type="str"), + twoFourGhzSettings=dict(type="dict"), + fiveGhzSettings=dict(type="dict"), + serial=dict(type="str"), +)) + +required_if = [ + ("state", "present", ["serial"], True), +] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class DevicesWirelessRadioSettings(object): + def __init__(self, params, meraki): + self.meraki = meraki + self.new_object = dict( + rfProfileId=params.get("rfProfileId"), + twoFourGhzSettings=params.get("twoFourGhzSettings"), + fiveGhzSettings=params.get("fiveGhzSettings"), + serial=params.get("serial"), + ) + + def get_all_params(self, name=None, id=None): + new_object_params = {} + if self.new_object.get('serial') is not None or self.new_object.get('serial') is not None: + new_object_params['serial'] = self.new_object.get('serial') + return new_object_params + + def update_all_params(self): + new_object_params = {} + if self.new_object.get('rfProfileId') is not None or self.new_object.get('rf_profile_id') is not None: + new_object_params['rfProfileId'] = self.new_object.get('rfProfileId') or \ + self.new_object.get('rf_profile_id') + if self.new_object.get('twoFourGhzSettings') is not None or self.new_object.get('two_four_ghz_settings') is not None: + new_object_params['twoFourGhzSettings'] = self.new_object.get('twoFourGhzSettings') or \ + self.new_object.get('two_four_ghz_settings') + if self.new_object.get('fiveGhzSettings') is not None or self.new_object.get('five_ghz_settings') is not None: + new_object_params['fiveGhzSettings'] = self.new_object.get('fiveGhzSettings') or \ + self.new_object.get('five_ghz_settings') + if self.new_object.get('serial') is not None or self.new_object.get('serial') is not None: + new_object_params['serial'] = self.new_object.get('serial') or \ + self.new_object.get('serial') + return new_object_params + + def get_object_by_name(self, name): + result = None + # NOTE: Does not have a get by name method, using get all + try: + items = self.meraki.exec_meraki( + family="wireless", + function="getDeviceWirelessRadioSettings", + params=self.get_all_params(name=name), + ) + if isinstance(items, dict): + if 'response' in items: + items = items.get('response') + result = get_dict_result(items, 'name', name) + if result is None: + result = items + except Exception as e: + print("Error: ", e) + result = None + return result + + def get_object_by_id(self, id): + result = None + # NOTE: Does not have a get by id method or it is in another action + return result + + def exists(self): + prev_obj = None + id_exists = False + name_exists = False + o_id = self.new_object.get("serial") + name = self.new_object.get("name") + if o_id: + prev_obj = self.get_object_by_name(o_id) + id_exists = prev_obj is not None and isinstance(prev_obj, dict) + if not id_exists and name: + prev_obj = self.get_object_by_name(name) + name_exists = prev_obj is not None and isinstance(prev_obj, dict) + if name_exists: + _id = prev_obj.get("id") + if id_exists and name_exists and o_id != _id: + raise InconsistentParameters( + "The 'id' and 'name' params don't refer to the same object") + if _id: + self.new_object.update(dict(id=_id)) + it_exists = prev_obj is not None and isinstance(prev_obj, dict) + return (it_exists, prev_obj) + + def requires_update(self, current_obj): + requested_obj = self.new_object + + obj_params = [ + ("rfProfileId", "rfProfileId"), + ("twoFourGhzSettings", "twoFourGhzSettings"), + ("fiveGhzSettings", "fiveGhzSettings"), + ("serial", "serial"), + ] + # Method 1. Params present in request (Ansible) obj are the same as the current (ISE) params + # If any does not have eq params, it requires update + return any(not meraki_compare_equality(current_obj.get(meraki_param), + requested_obj.get(ansible_param)) + for (meraki_param, ansible_param) in obj_params) + + def update(self): + id = self.new_object.get("id") + name = self.new_object.get("name") + result = None + result = self.meraki.exec_meraki( + family="wireless", + function="updateDeviceWirelessRadioSettings", + params=self.update_all_params(), + op_modifies=True, + ) + return result + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = False + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + meraki = MERAKI(self._task.args) + obj = DevicesWirelessRadioSettings(self._task.args, meraki) + + state = self._task.args.get("state") + + response = None + if state == "present": + (obj_exists, prev_obj) = obj.exists() + if obj_exists: + if obj.requires_update(prev_obj): + response = obj.update() + meraki.object_updated() + else: + response = prev_obj + meraki.object_already_present() + else: + meraki.fail_json( + "Object does not exists, plugin only has update") + + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/devices_wireless_radio_settings_info.py b/ansible_collections/cisco/meraki/plugins/action/devices_wireless_radio_settings_info.py new file mode 100644 index 000000000..f1bdda485 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/devices_wireless_radio_settings_info.py @@ -0,0 +1,90 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + serial=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_all(self, params): + new_object = {} + if params.get("serial") is not None: + new_object["serial"] = params.get( + "serial") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="wireless", + function='getDeviceWirelessRadioSettings', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/devices_wireless_status_info.py b/ansible_collections/cisco/meraki/plugins/action/devices_wireless_status_info.py new file mode 100644 index 000000000..5990c5324 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/devices_wireless_status_info.py @@ -0,0 +1,90 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + serial=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_all(self, params): + new_object = {} + if params.get("serial") is not None: + new_object["serial"] = params.get( + "serial") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="wireless", + function='getDeviceWirelessStatus', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks.py b/ansible_collections/cisco/meraki/plugins/action/networks.py new file mode 100644 index 000000000..378b0bc0d --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks.py @@ -0,0 +1,362 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or +# https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, + meraki_compare_equality2, + get_dict_result, +) +from ansible_collections.cisco.meraki.plugins.plugin_utils.exceptions import ( + InconsistentParameters, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + state=dict(type="str", default="present", choices=["present", "absent"]), + name=dict(type="str"), + productTypes=dict(type="list"), + tags=dict(type="list"), + timeZone=dict(type="str"), + copyFromNetworkId=dict(type="str"), + notes=dict(type="str"), + organizationId=dict(type="str"), + networkId=dict(type="str"), + enrollmentString=dict(type="str"), +)) + +required_if = [ + ("state", "present", ["name", "networkId", "organizationId"], True), + ("state", "absent", ["name", "networkId", "organizationId"], True), +] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class Networks(object): + def __init__(self, params, meraki): + self.meraki = meraki + self.new_object = dict( + name=params.get("name"), + productTypes=params.get("productTypes"), + tags=params.get("tags"), + timeZone=params.get("timeZone"), + copyFromNetworkId=params.get("copyFromNetworkId"), + notes=params.get("notes"), + organizationId=params.get("organizationId"), + networkId=params.get("networkId"), + enrollmentString=params.get("enrollmentString"), + ) + + def get_all_params(self, name=None, id=None): + new_object_params = {} + if self.new_object.get('configTemplateId') is not None or self.new_object.get('config_template_id') is not None: + new_object_params['configTemplateId'] = self.new_object.get('configTemplateId') or \ + self.new_object.get('config_template_id') + if self.new_object.get('isBoundToConfigTemplate') is not None or self.new_object.get('is_bound_to_config_template') is not None: + new_object_params['isBoundToConfigTemplate'] = self.new_object.get('isBoundToConfigTemplate') or \ + self.new_object.get('is_bound_to_config_template') + if self.new_object.get('tags') is not None or self.new_object.get('tags') is not None: + new_object_params['tags'] = self.new_object.get('tags') + if self.new_object.get('tagsFilterType') is not None or self.new_object.get('tags_filter_type') is not None: + new_object_params['tagsFilterType'] = self.new_object.get('tagsFilterType') or \ + self.new_object.get('tags_filter_type') + if self.new_object.get('perPage') is not None or self.new_object.get('per_page') is not None: + new_object_params['perPage'] = self.new_object.get('perPage') or \ + self.new_object.get('per_page') + new_object_params['total_pages'] = -1 + if self.new_object.get('startingAfter') is not None or self.new_object.get('starting_after') is not None: + new_object_params['startingAfter'] = self.new_object.get('startingAfter') or \ + self.new_object.get('starting_after') + if self.new_object.get('endingBefore') is not None or self.new_object.get('ending_before') is not None: + new_object_params['endingBefore'] = self.new_object.get('endingBefore') or \ + self.new_object.get('ending_before') + if self.new_object.get('organizationId') is not None or self.new_object.get('organization_id') is not None: + new_object_params['organizationId'] = self.new_object.get('organizationId') or \ + self.new_object.get('organization_id') + return new_object_params + + def get_params_by_id(self, name=None, id=None): + new_object_params = {} + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + return new_object_params + + def create_params(self): + new_object_params = {} + if self.new_object.get('name') is not None or self.new_object.get('name') is not None: + new_object_params['name'] = self.new_object.get('name') or \ + self.new_object.get('name') + if self.new_object.get('productTypes') is not None or self.new_object.get('product_types') is not None: + new_object_params['productTypes'] = self.new_object.get('productTypes') or \ + self.new_object.get('product_types') + if self.new_object.get('tags') is not None or self.new_object.get('tags') is not None: + new_object_params['tags'] = self.new_object.get('tags') or \ + self.new_object.get('tags') + if self.new_object.get('timeZone') is not None or self.new_object.get('time_zone') is not None: + new_object_params['timeZone'] = self.new_object.get('timeZone') or \ + self.new_object.get('time_zone') + if self.new_object.get('copyFromNetworkId') is not None or self.new_object.get('copy_from_network_id') is not None: + new_object_params['copyFromNetworkId'] = self.new_object.get('copyFromNetworkId') or \ + self.new_object.get('copy_from_network_id') + if self.new_object.get('notes') is not None or self.new_object.get('notes') is not None: + new_object_params['notes'] = self.new_object.get('notes') or \ + self.new_object.get('notes') + if self.new_object.get('organizationId') is not None or self.new_object.get('organization_id') is not None: + new_object_params['organizationId'] = self.new_object.get('organizationId') or \ + self.new_object.get('organization_id') + return new_object_params + + def delete_by_id_params(self): + new_object_params = {} + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + return new_object_params + + def update_by_id_params(self): + new_object_params = {} + if self.new_object.get('name') is not None or self.new_object.get('name') is not None: + new_object_params['name'] = self.new_object.get('name') or \ + self.new_object.get('name') + if self.new_object.get('timeZone') is not None or self.new_object.get('time_zone') is not None: + new_object_params['timeZone'] = self.new_object.get('timeZone') or \ + self.new_object.get('time_zone') + if self.new_object.get('productTypes') is not None or self.new_object.get('product_types') is not None: + new_object_params['productTypes'] = self.new_object.get('productTypes') or \ + self.new_object.get('product_types') + if self.new_object.get('tags') is not None or self.new_object.get('tags') is not None: + new_object_params['tags'] = self.new_object.get('tags') or \ + self.new_object.get('tags') + if self.new_object.get('enrollmentString') is not None or self.new_object.get('enrollment_string') is not None: + new_object_params['enrollmentString'] = self.new_object.get('enrollmentString') or \ + self.new_object.get('enrollment_string') + if self.new_object.get('notes') is not None or self.new_object.get('notes') is not None: + new_object_params['notes'] = self.new_object.get('notes') or \ + self.new_object.get('notes') + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + return new_object_params + + def get_object_by_name(self, name): + result = None + # NOTE: Does not have a get by name method or it is in another action + try: + items = self.meraki.exec_meraki( + family="organizations", + function="getOrganizationNetworks", + params=self.get_all_params(name=name), + ) + if isinstance(items, dict): + if 'response' in items: + items = items.get('response') + result = get_dict_result(items, 'name', name) + if result is None: + result = items + except Exception as e: + print("Error: ", e) + result = None + return result + + def get_object_by_id(self, id): + result = None + try: + items = self.meraki.exec_meraki( + family="networks", + function="getNetwork", + params=self.get_params_by_id() + ) + if isinstance(items, dict): + if 'response' in items: + items = items.get('response') + result = get_dict_result(items, 'networkId', id) + except Exception as e: + print("Error: ", e) + result = None + return result + + def exists(self): + id_exists = False + name_exists = False + prev_obj = None + o_id = self.new_object.get("id") + o_id = o_id or self.new_object.get( + "network_id") or self.new_object.get("networkId") + name = self.new_object.get("name") + if o_id: + prev_obj = self.get_object_by_id(o_id) + id_exists = prev_obj is not None and isinstance(prev_obj, dict) + if not id_exists and name: + prev_obj = self.get_object_by_name(name) + name_exists = prev_obj is not None and isinstance(prev_obj, dict) + if name_exists: + _id = prev_obj.get("id") + _id = _id or prev_obj.get("networkId") + if id_exists and name_exists and o_id != _id: + raise InconsistentParameters( + "The 'id' and 'name' params don't refer to the same object") + if _id: + self.new_object.update(dict(id=_id)) + self.new_object.update(dict(networkId=_id)) + if _id: + prev_obj = self.get_object_by_id(_id) + it_exists = prev_obj is not None and isinstance(prev_obj, dict) + return (it_exists, prev_obj) + + def requires_update(self, current_obj): + requested_obj = self.new_object + + obj_params = [ + ("name", "name"), + ("productTypes", "productTypes"), + ("tags", "tags"), + ("timeZone", "timeZone"), + ("copyFromNetworkId", "copyFromNetworkId"), + ("notes", "notes"), + ("organizationId", "organizationId"), + ("networkId", "networkId"), + ("enrollmentString", "enrollmentString"), + ] + # Method 1. Params present in request (Ansible) obj are the same as the current (DNAC) params + # If any does not have eq params, it requires update + return any(not meraki_compare_equality2(current_obj.get(meraki_param), + requested_obj.get(ansible_param)) + for (meraki_param, ansible_param) in obj_params) + + def create(self): + result = self.meraki.exec_meraki( + family="organizations", + function="createOrganizationNetwork", + params=self.create_params(), + op_modifies=True, + ) + return result + + def update(self): + id = self.new_object.get("id") + id = id or self.new_object.get("networkId") + name = self.new_object.get("name") + result = None + if not id: + prev_obj_name = self.get_object_by_name(name) + id_ = None + if prev_obj_name: + id_ = prev_obj_name.get("id") + id_ = id_ or prev_obj_name.get("networkId") + if id_: + self.new_object.update(dict(networkId=id_)) + result = self.meraki.exec_meraki( + family="networks", + function="updateNetwork", + params=self.update_by_id_params(), + op_modifies=True, + ) + return result + + def delete(self): + id = self.new_object.get("id") + id = id or self.new_object.get("networkId") + name = self.new_object.get("name") + result = None + if not id: + prev_obj_name = self.get_object_by_name(name) + id_ = None + if prev_obj_name: + id_ = prev_obj_name.get("id") + id_ = id_ or prev_obj_name.get("networkId") + if id_: + self.new_object.update(dict(networkId=id_)) + result = self.meraki.exec_meraki( + family="networks", + function="deleteNetwork", + params=self.delete_by_id_params(), + ) + return result + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = False + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + meraki = MERAKI(self._task.args) + obj = Networks(self._task.args, meraki) + + state = self._task.args.get("state") + + response = None + + if state == "present": + (obj_exists, prev_obj) = obj.exists() + if obj_exists: + if obj.requires_update(prev_obj): + response = obj.update() + meraki.object_updated() + else: + response = prev_obj + meraki.object_already_present() + else: + response = obj.create() + meraki.object_created() + + elif state == "absent": + (obj_exists, prev_obj) = obj.exists() + if obj_exists: + response = obj.delete() + meraki.object_deleted() + else: + meraki.object_already_absent() + + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_alerts_history_info.py b/ansible_collections/cisco/meraki/plugins/action/networks_alerts_history_info.py new file mode 100644 index 000000000..d24397de4 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_alerts_history_info.py @@ -0,0 +1,108 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + networkId=dict(type="str"), + perPage=dict(type="int"), + total_pages=dict(type="int"), + direction=dict(type="str"), + startingAfter=dict(type="str"), + endingBefore=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_all(self, params): + new_object = {} + if params.get("networkId") is not None: + new_object["networkId"] = params.get( + "networkId") + if params.get("perPage") is not None: + new_object["perPage"] = params.get( + "perPage") + new_object['total_pages'] = params.get( + "total_pages") or 1 + new_object['direction'] = params.get( + "direction") or "next" + if params.get("startingAfter") is not None: + new_object["startingAfter"] = params.get( + "startingAfter") + if params.get("endingBefore") is not None: + new_object["endingBefore"] = params.get( + "endingBefore") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="networks", + function='getNetworkAlertsHistory', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_alerts_settings.py b/ansible_collections/cisco/meraki/plugins/action/networks_alerts_settings.py new file mode 100644 index 000000000..9389b5db1 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_alerts_settings.py @@ -0,0 +1,206 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or +# https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, + meraki_compare_equality, + get_dict_result, +) +from ansible_collections.cisco.meraki.plugins.plugin_utils.exceptions import ( + InconsistentParameters, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + state=dict(type="str", default="present", choices=["present"]), + defaultDestinations=dict(type="dict"), + alerts=dict(type="list"), + networkId=dict(type="str"), +)) + +required_if = [ + ("state", "present", ["networkId"], True), +] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class NetworksAlertsSettings(object): + def __init__(self, params, meraki): + self.meraki = meraki + self.new_object = dict( + defaultDestinations=params.get("defaultDestinations"), + alerts=params.get("alerts"), + network_id=params.get("networkId"), + ) + + def get_all_params(self, name=None, id=None): + new_object_params = {} + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + return new_object_params + + def update_all_params(self): + new_object_params = {} + if self.new_object.get('defaultDestinations') is not None or self.new_object.get('default_destinations') is not None: + new_object_params['defaultDestinations'] = self.new_object.get('defaultDestinations') or \ + self.new_object.get('default_destinations') + if self.new_object.get('alerts') is not None or self.new_object.get('alerts') is not None: + new_object_params['alerts'] = self.new_object.get('alerts') or \ + self.new_object.get('alerts') + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + return new_object_params + + def get_object_by_name(self, name): + result = None + # NOTE: Does not have a get by name method, using get all + try: + items = self.meraki.exec_meraki( + family="networks", + function="getNetworkAlertsSettings", + params=self.get_all_params(name=name), + ) + if isinstance(items, dict): + if 'response' in items: + items = items.get('response') + result = get_dict_result(items, 'name', name) + if result is None: + result = items + except Exception as e: + print("Error: ", e) + result = None + return result + + def get_object_by_id(self, id): + result = None + # NOTE: Does not have a get by id method or it is in another action + return result + + def exists(self): + prev_obj = None + id_exists = False + name_exists = False + o_id = self.new_object.get("networkId") or self.new_object.get("network_id") + name = self.new_object.get("name") + if o_id: + prev_obj = self.get_object_by_name(o_id) + id_exists = prev_obj is not None and isinstance(prev_obj, dict) + if not id_exists and name: + prev_obj = self.get_object_by_name(name) + name_exists = prev_obj is not None and isinstance(prev_obj, dict) + if name_exists: + _id = prev_obj.get("id") + if id_exists and name_exists and o_id != _id: + raise InconsistentParameters( + "The 'id' and 'name' params don't refer to the same object") + if _id: + self.new_object.update(dict(id=_id)) + it_exists = prev_obj is not None and isinstance(prev_obj, dict) + return (it_exists, prev_obj) + + def requires_update(self, current_obj): + requested_obj = self.new_object + + obj_params = [ + ("defaultDestinations", "defaultDestinations"), + ("alerts", "alerts"), + ("networkId", "networkId"), + ] + # Method 1. Params present in request (Ansible) obj are the same as the current (ISE) params + # If any does not have eq params, it requires update + return any(not meraki_compare_equality(current_obj.get(meraki_param), + requested_obj.get(ansible_param)) + for (meraki_param, ansible_param) in obj_params) + + def update(self): + id = self.new_object.get("id") + name = self.new_object.get("name") + result = None + result = self.meraki.exec_meraki( + family="networks", + function="updateNetworkAlertsSettings", + params=self.update_all_params(), + op_modifies=True, + ) + return result + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = False + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + meraki = MERAKI(self._task.args) + obj = NetworksAlertsSettings(self._task.args, meraki) + + state = self._task.args.get("state") + + response = None + if state == "present": + (obj_exists, prev_obj) = obj.exists() + if obj_exists: + if obj.requires_update(prev_obj): + response = obj.update() + meraki.object_updated() + else: + response = prev_obj + meraki.object_already_present() + else: + meraki.fail_json( + "Object does not exists, plugin only has update") + + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_alerts_settings_info.py b/ansible_collections/cisco/meraki/plugins/action/networks_alerts_settings_info.py new file mode 100644 index 000000000..7f3d5d003 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_alerts_settings_info.py @@ -0,0 +1,90 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + networkId=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_all(self, params): + new_object = {} + if params.get("networkId") is not None: + new_object["networkId"] = params.get( + "networkId") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="networks", + function='getNetworkAlertsSettings', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_appliance_connectivity_monitoring_destinations.py b/ansible_collections/cisco/meraki/plugins/action/networks_appliance_connectivity_monitoring_destinations.py new file mode 100644 index 000000000..2a480e1c1 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_appliance_connectivity_monitoring_destinations.py @@ -0,0 +1,200 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or +# https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, + meraki_compare_equality, + get_dict_result, +) +from ansible_collections.cisco.meraki.plugins.plugin_utils.exceptions import ( + InconsistentParameters, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + state=dict(type="str", default="present", choices=["present"]), + destinations=dict(type="list"), + networkId=dict(type="str"), +)) + +required_if = [ + ("state", "present", ["networkId"], True), +] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class NetworksApplianceConnectivityMonitoringDestinations(object): + def __init__(self, params, meraki): + self.meraki = meraki + self.new_object = dict( + destinations=params.get("destinations"), + network_id=params.get("networkId"), + ) + + def get_all_params(self, name=None, id=None): + new_object_params = {} + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + return new_object_params + + def update_all_params(self): + new_object_params = {} + if self.new_object.get('destinations') is not None or self.new_object.get('destinations') is not None: + new_object_params['destinations'] = self.new_object.get('destinations') or \ + self.new_object.get('destinations') + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + return new_object_params + + def get_object_by_name(self, name): + result = None + # NOTE: Does not have a get by name method, using get all + try: + items = self.meraki.exec_meraki( + family="appliance", + function="getNetworkApplianceConnectivityMonitoringDestinations", + params=self.get_all_params(name=name), + ) + if isinstance(items, dict): + if 'response' in items: + items = items.get('response') + result = get_dict_result(items, 'name', name) + if result is None: + result = items + except Exception as e: + print("Error: ", e) + result = None + return result + + def get_object_by_id(self, id): + result = None + # NOTE: Does not have a get by id method or it is in another action + return result + + def exists(self): + prev_obj = None + id_exists = False + name_exists = False + o_id = self.new_object.get("networkId") or self.new_object.get("network_id") + name = self.new_object.get("name") + if o_id: + prev_obj = self.get_object_by_name(o_id) + id_exists = prev_obj is not None and isinstance(prev_obj, dict) + if not id_exists and name: + prev_obj = self.get_object_by_name(name) + name_exists = prev_obj is not None and isinstance(prev_obj, dict) + if name_exists: + _id = prev_obj.get("id") + if id_exists and name_exists and o_id != _id: + raise InconsistentParameters( + "The 'id' and 'name' params don't refer to the same object") + if _id: + self.new_object.update(dict(id=_id)) + it_exists = prev_obj is not None and isinstance(prev_obj, dict) + return (it_exists, prev_obj) + + def requires_update(self, current_obj): + requested_obj = self.new_object + + obj_params = [ + ("destinations", "destinations"), + ("networkId", "networkId"), + ] + # Method 1. Params present in request (Ansible) obj are the same as the current (ISE) params + # If any does not have eq params, it requires update + return any(not meraki_compare_equality(current_obj.get(meraki_param), + requested_obj.get(ansible_param)) + for (meraki_param, ansible_param) in obj_params) + + def update(self): + id = self.new_object.get("id") + name = self.new_object.get("name") + result = None + result = self.meraki.exec_meraki( + family="appliance", + function="updateNetworkApplianceConnectivityMonitoringDestinations", + params=self.update_all_params(), + op_modifies=True, + ) + return result + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = False + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + meraki = MERAKI(self._task.args) + obj = NetworksApplianceConnectivityMonitoringDestinations(self._task.args, meraki) + + state = self._task.args.get("state") + + response = None + if state == "present": + (obj_exists, prev_obj) = obj.exists() + if obj_exists: + if obj.requires_update(prev_obj): + response = obj.update() + meraki.object_updated() + else: + response = prev_obj + meraki.object_already_present() + else: + meraki.fail_json( + "Object does not exists, plugin only has update") + + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_appliance_connectivity_monitoring_destinations_info.py b/ansible_collections/cisco/meraki/plugins/action/networks_appliance_connectivity_monitoring_destinations_info.py new file mode 100644 index 000000000..74368dcdb --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_appliance_connectivity_monitoring_destinations_info.py @@ -0,0 +1,90 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + networkId=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_all(self, params): + new_object = {} + if params.get("networkId") is not None: + new_object["networkId"] = params.get( + "networkId") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="appliance", + function='getNetworkApplianceConnectivityMonitoringDestinations', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_appliance_content_filtering.py b/ansible_collections/cisco/meraki/plugins/action/networks_appliance_content_filtering.py new file mode 100644 index 000000000..5cad13ae6 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_appliance_content_filtering.py @@ -0,0 +1,218 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or +# https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, + meraki_compare_equality, + get_dict_result, +) +from ansible_collections.cisco.meraki.plugins.plugin_utils.exceptions import ( + InconsistentParameters, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + state=dict(type="str", default="present", choices=["present"]), + allowedUrlPatterns=dict(type="list"), + blockedUrlPatterns=dict(type="list"), + blockedUrlCategories=dict(type="list"), + urlCategoryListSize=dict(type="str"), + networkId=dict(type="str"), +)) + +required_if = [ + ("state", "present", ["networkId"], True), +] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class NetworksApplianceContentFiltering(object): + def __init__(self, params, meraki): + self.meraki = meraki + self.new_object = dict( + allowedUrlPatterns=params.get("allowedUrlPatterns"), + blockedUrlPatterns=params.get("blockedUrlPatterns"), + blockedUrlCategories=params.get("blockedUrlCategories"), + urlCategoryListSize=params.get("urlCategoryListSize"), + network_id=params.get("networkId"), + ) + + def get_all_params(self, name=None, id=None): + new_object_params = {} + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + return new_object_params + + def update_all_params(self): + new_object_params = {} + if self.new_object.get('allowedUrlPatterns') is not None or self.new_object.get('allowed_url_patterns') is not None: + new_object_params['allowedUrlPatterns'] = self.new_object.get('allowedUrlPatterns') or \ + self.new_object.get('allowed_url_patterns') + if self.new_object.get('blockedUrlPatterns') is not None or self.new_object.get('blocked_url_patterns') is not None: + new_object_params['blockedUrlPatterns'] = self.new_object.get('blockedUrlPatterns') or \ + self.new_object.get('blocked_url_patterns') + if self.new_object.get('blockedUrlCategories') is not None or self.new_object.get('blocked_url_categories') is not None: + new_object_params['blockedUrlCategories'] = self.new_object.get('blockedUrlCategories') or \ + self.new_object.get('blocked_url_categories') + if self.new_object.get('urlCategoryListSize') is not None or self.new_object.get('url_category_list_size') is not None: + new_object_params['urlCategoryListSize'] = self.new_object.get('urlCategoryListSize') or \ + self.new_object.get('url_category_list_size') + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + return new_object_params + + def get_object_by_name(self, name): + result = None + # NOTE: Does not have a get by name method, using get all + try: + items = self.meraki.exec_meraki( + family="appliance", + function="getNetworkApplianceContentFiltering", + params=self.get_all_params(name=name), + ) + if isinstance(items, dict): + if 'response' in items: + items = items.get('response') + result = get_dict_result(items, 'name', name) + if result is None: + result = items + except Exception as e: + print("Error: ", e) + result = None + return result + + def get_object_by_id(self, id): + result = None + # NOTE: Does not have a get by id method or it is in another action + return result + + def exists(self): + prev_obj = None + id_exists = False + name_exists = False + o_id = self.new_object.get("networkId") or self.new_object.get("network_id") + name = self.new_object.get("name") + if o_id: + prev_obj = self.get_object_by_name(o_id) + id_exists = prev_obj is not None and isinstance(prev_obj, dict) + if not id_exists and name: + prev_obj = self.get_object_by_name(name) + name_exists = prev_obj is not None and isinstance(prev_obj, dict) + if name_exists: + _id = prev_obj.get("id") + if id_exists and name_exists and o_id != _id: + raise InconsistentParameters( + "The 'id' and 'name' params don't refer to the same object") + if _id: + self.new_object.update(dict(id=_id)) + it_exists = prev_obj is not None and isinstance(prev_obj, dict) + return (it_exists, prev_obj) + + def requires_update(self, current_obj): + requested_obj = self.new_object + + obj_params = [ + ("allowedUrlPatterns", "allowedUrlPatterns"), + ("blockedUrlPatterns", "blockedUrlPatterns"), + ("blockedUrlCategories", "blockedUrlCategories"), + ("urlCategoryListSize", "urlCategoryListSize"), + ("networkId", "networkId"), + ] + # Method 1. Params present in request (Ansible) obj are the same as the current (ISE) params + # If any does not have eq params, it requires update + return any(not meraki_compare_equality(current_obj.get(meraki_param), + requested_obj.get(ansible_param)) + for (meraki_param, ansible_param) in obj_params) + + def update(self): + id = self.new_object.get("id") + name = self.new_object.get("name") + result = None + result = self.meraki.exec_meraki( + family="appliance", + function="updateNetworkApplianceContentFiltering", + params=self.update_all_params(), + op_modifies=True, + ) + return result + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = False + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + meraki = MERAKI(self._task.args) + obj = NetworksApplianceContentFiltering(self._task.args, meraki) + + state = self._task.args.get("state") + + response = None + if state == "present": + (obj_exists, prev_obj) = obj.exists() + if obj_exists: + if obj.requires_update(prev_obj): + response = obj.update() + meraki.object_updated() + else: + response = prev_obj + meraki.object_already_present() + else: + meraki.fail_json( + "Object does not exists, plugin only has update") + + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_appliance_content_filtering_categories_info.py b/ansible_collections/cisco/meraki/plugins/action/networks_appliance_content_filtering_categories_info.py new file mode 100644 index 000000000..ecc83beb3 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_appliance_content_filtering_categories_info.py @@ -0,0 +1,90 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + networkId=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_all(self, params): + new_object = {} + if params.get("networkId") is not None: + new_object["networkId"] = params.get( + "networkId") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="appliance", + function='getNetworkApplianceContentFilteringCategories', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_appliance_content_filtering_info.py b/ansible_collections/cisco/meraki/plugins/action/networks_appliance_content_filtering_info.py new file mode 100644 index 000000000..5098b4608 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_appliance_content_filtering_info.py @@ -0,0 +1,90 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + networkId=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_all(self, params): + new_object = {} + if params.get("networkId") is not None: + new_object["networkId"] = params.get( + "networkId") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="appliance", + function='getNetworkApplianceContentFiltering', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_appliance_firewall_cellular_firewall_rules.py b/ansible_collections/cisco/meraki/plugins/action/networks_appliance_firewall_cellular_firewall_rules.py new file mode 100644 index 000000000..50da83e7d --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_appliance_firewall_cellular_firewall_rules.py @@ -0,0 +1,200 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or +# https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, + meraki_compare_equality, + get_dict_result, +) +from ansible_collections.cisco.meraki.plugins.plugin_utils.exceptions import ( + InconsistentParameters, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + state=dict(type="str", default="present", choices=["present"]), + rules=dict(type="list"), + networkId=dict(type="str"), +)) + +required_if = [ + ("state", "present", ["networkId"], True), +] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class NetworksApplianceFirewallCellularFirewallRules(object): + def __init__(self, params, meraki): + self.meraki = meraki + self.new_object = dict( + rules=params.get("rules"), + network_id=params.get("networkId"), + ) + + def get_all_params(self, name=None, id=None): + new_object_params = {} + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + return new_object_params + + def update_all_params(self): + new_object_params = {} + if self.new_object.get('rules') is not None or self.new_object.get('rules') is not None: + new_object_params['rules'] = self.new_object.get('rules') or \ + self.new_object.get('rules') + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + return new_object_params + + def get_object_by_name(self, name): + result = None + # NOTE: Does not have a get by name method, using get all + try: + items = self.meraki.exec_meraki( + family="appliance", + function="getNetworkApplianceFirewallCellularFirewallRules", + params=self.get_all_params(name=name), + ) + if isinstance(items, dict): + if 'response' in items: + items = items.get('response') + result = get_dict_result(items, 'name', name) + if result is None: + result = items + except Exception as e: + print("Error: ", e) + result = None + return result + + def get_object_by_id(self, id): + result = None + # NOTE: Does not have a get by id method or it is in another action + return result + + def exists(self): + prev_obj = None + id_exists = False + name_exists = False + o_id = self.new_object.get("networkId") or self.new_object.get("network_id") + name = self.new_object.get("name") + if o_id: + prev_obj = self.get_object_by_name(o_id) + id_exists = prev_obj is not None and isinstance(prev_obj, dict) + if not id_exists and name: + prev_obj = self.get_object_by_name(name) + name_exists = prev_obj is not None and isinstance(prev_obj, dict) + if name_exists: + _id = prev_obj.get("id") + if id_exists and name_exists and o_id != _id: + raise InconsistentParameters( + "The 'id' and 'name' params don't refer to the same object") + if _id: + self.new_object.update(dict(id=_id)) + it_exists = prev_obj is not None and isinstance(prev_obj, dict) + return (it_exists, prev_obj) + + def requires_update(self, current_obj): + requested_obj = self.new_object + + obj_params = [ + ("rules", "rules"), + ("networkId", "networkId"), + ] + # Method 1. Params present in request (Ansible) obj are the same as the current (ISE) params + # If any does not have eq params, it requires update + return any(not meraki_compare_equality(current_obj.get(meraki_param), + requested_obj.get(ansible_param)) + for (meraki_param, ansible_param) in obj_params) + + def update(self): + id = self.new_object.get("id") + name = self.new_object.get("name") + result = None + result = self.meraki.exec_meraki( + family="appliance", + function="updateNetworkApplianceFirewallCellularFirewallRules", + params=self.update_all_params(), + op_modifies=True, + ) + return result + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = False + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + meraki = MERAKI(self._task.args) + obj = NetworksApplianceFirewallCellularFirewallRules(self._task.args, meraki) + + state = self._task.args.get("state") + + response = None + if state == "present": + (obj_exists, prev_obj) = obj.exists() + if obj_exists: + if obj.requires_update(prev_obj): + response = obj.update() + meraki.object_updated() + else: + response = prev_obj + meraki.object_already_present() + else: + meraki.fail_json( + "Object does not exists, plugin only has update") + + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_appliance_firewall_cellular_firewall_rules_info.py b/ansible_collections/cisco/meraki/plugins/action/networks_appliance_firewall_cellular_firewall_rules_info.py new file mode 100644 index 000000000..11762fcfa --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_appliance_firewall_cellular_firewall_rules_info.py @@ -0,0 +1,90 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + networkId=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_all(self, params): + new_object = {} + if params.get("networkId") is not None: + new_object["networkId"] = params.get( + "networkId") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="appliance", + function='getNetworkApplianceFirewallCellularFirewallRules', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_appliance_firewall_firewalled_services.py b/ansible_collections/cisco/meraki/plugins/action/networks_appliance_firewall_firewalled_services.py new file mode 100644 index 000000000..358ccd45c --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_appliance_firewall_firewalled_services.py @@ -0,0 +1,225 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or +# https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, + meraki_compare_equality, +) +from ansible_collections.cisco.meraki.plugins.plugin_utils.exceptions import ( + InconsistentParameters, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + state=dict(type="str", default="present", choices=["present"]), + access=dict(type="str"), + allowedIps=dict(type="list"), + networkId=dict(type="str"), + service=dict(type="str"), +)) + +required_if = [ + ("state", "present", ["networkId", "service"], True), +] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class NetworksApplianceFirewallFirewalledServices(object): + def __init__(self, params, meraki): + self.meraki = meraki + self.new_object = dict( + access=params.get("access"), + allowedIps=params.get("allowedIps"), + network_id=params.get("networkId"), + service=params.get("service"), + ) + + def get_params_by_id(self, name=None, id=None): + new_object_params = {} + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + if self.new_object.get('service') is not None or self.new_object.get('service') is not None: + new_object_params['service'] = self.new_object.get('service') + return new_object_params + + def update_by_id_params(self): + new_object_params = {} + if self.new_object.get('access') is not None or self.new_object.get('access') is not None: + new_object_params['access'] = self.new_object.get('access') or \ + self.new_object.get('access') + if self.new_object.get('allowedIps') is not None or self.new_object.get('allowed_ips') is not None: + new_object_params['allowedIps'] = self.new_object.get('allowedIps') or \ + self.new_object.get('allowed_ips') + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + if self.new_object.get('service') is not None or self.new_object.get('service') is not None: + new_object_params['service'] = self.new_object.get('service') or \ + self.new_object.get('service') + return new_object_params + + def get_object_by_name(self, name): + result = None + # NOTE: Does not have a get by name and get all + return result + + def get_object_by_id(self, id): + result = None + try: + items = self.meraki.exec_meraki( + family="appliance", + function="getNetworkApplianceFirewallFirewalledService", + params=self.get_params_by_id() + ) + if isinstance(items, dict): + if 'response' in items: + items = items.get('response') + result = items + except Exception as e: + print("Error: ", e) + result = None + return result + + def exists(self): + prev_obj = None + id_exists = False + name_exists = False + o_id = self.new_object.get("networkId") or self.new_object.get("network_id") + o_id = o_id or self.new_object.get( + "service") or self.new_object.get("service") + name = self.new_object.get("name") + if o_id: + prev_obj = self.get_object_by_id(o_id) + id_exists = prev_obj is not None and isinstance(prev_obj, dict) + if not id_exists and name: + prev_obj = self.get_object_by_name(name) + name_exists = prev_obj is not None and isinstance(prev_obj, dict) + if name_exists: + _id = prev_obj.get("id") + _id = _id or prev_obj.get("service") + if id_exists and name_exists and o_id != _id: + raise InconsistentParameters( + "The 'id' and 'name' params don't refer to the same object") + if _id: + self.new_object.update(dict(id=_id)) + self.new_object.update(dict(service=_id)) + if _id: + prev_obj = self.get_object_by_id(_id) + it_exists = prev_obj is not None and isinstance(prev_obj, dict) + return (it_exists, prev_obj) + + def requires_update(self, current_obj): + requested_obj = self.new_object + + obj_params = [ + ("access", "access"), + ("allowedIps", "allowedIps"), + ("networkId", "networkId"), + ("service", "service"), + ] + # Method 1. Params present in request (Ansible) obj are the same as the current (ISE) params + # If any does not have eq params, it requires update + return any(not meraki_compare_equality(current_obj.get(meraki_param), + requested_obj.get(ansible_param)) + for (meraki_param, ansible_param) in obj_params) + + def update(self): + id = self.new_object.get("id") + id = id or self.new_object.get("service") + name = self.new_object.get("name") + result = None + if not id: + prev_obj_name = self.get_object_by_name(name) + id_ = None + if prev_obj_name: + id_ = prev_obj_name.get("id") + id_ = id_ or prev_obj_name.get("service") + if id_: + self.new_object.update(dict(service=id_)) + result = self.meraki.exec_meraki( + family="appliance", + function="updateNetworkApplianceFirewallFirewalledService", + params=self.update_by_id_params(), + op_modifies=True, + ) + return result + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = False + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + meraki = MERAKI(self._task.args) + obj = NetworksApplianceFirewallFirewalledServices(self._task.args, meraki) + + state = self._task.args.get("state") + + response = None + if state == "present": + (obj_exists, prev_obj) = obj.exists() + if obj_exists: + if obj.requires_update(prev_obj): + response = obj.update() + meraki.object_updated() + else: + response = prev_obj + meraki.object_already_present() + else: + meraki.fail_json( + "Object does not exists, plugin only has update") + + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_appliance_firewall_firewalled_services_info.py b/ansible_collections/cisco/meraki/plugins/action/networks_appliance_firewall_firewalled_services_info.py new file mode 100644 index 000000000..62596e973 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_appliance_firewall_firewalled_services_info.py @@ -0,0 +1,102 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + networkId=dict(type="str"), + service=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_object(self, params): + new_object = {} + if params.get("networkId") is not None: + new_object["networkId"] = params.get( + "networkId") + if params.get("service") is not None: + new_object["service"] = params.get( + "service") + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + id = self._task.args.get("service") + if id: + response = meraki.exec_meraki( + family="appliance", + function='getNetworkApplianceFirewallFirewalledService', + params=self.get_object(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result + if not id: + # NOTE: Does not have a get all method or it is in another action + response = None + meraki.object_modify_result(changed=False, result="Module does not have get all, check arguments of module") + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_appliance_firewall_inbound_firewall_rules.py b/ansible_collections/cisco/meraki/plugins/action/networks_appliance_firewall_inbound_firewall_rules.py new file mode 100644 index 000000000..002aa2ea7 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_appliance_firewall_inbound_firewall_rules.py @@ -0,0 +1,205 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or +# https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, + meraki_compare_equality, + get_dict_result, +) +from ansible_collections.cisco.meraki.plugins.plugin_utils.exceptions import ( + InconsistentParameters, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + state=dict(type="str", default="present", choices=["present"]), + rules=dict(type="list"), + syslogDefaultRule=dict(type="bool"), + networkId=dict(type="str"), +)) + +required_if = [ + ("state", "present", ["networkId"], True), +] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class NetworksApplianceFirewallInboundFirewallRules(object): + def __init__(self, params, meraki): + self.meraki = meraki + self.new_object = dict( + rules=params.get("rules"), + syslogDefaultRule=params.get("syslogDefaultRule"), + network_id=params.get("networkId"), + ) + + def get_all_params(self, name=None, id=None): + new_object_params = {} + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + return new_object_params + + def update_all_params(self): + new_object_params = {} + if self.new_object.get('rules') is not None or self.new_object.get('rules') is not None: + new_object_params['rules'] = self.new_object.get('rules') or \ + self.new_object.get('rules') + if self.new_object.get('syslogDefaultRule') is not None or self.new_object.get('syslog_default_rule') is not None: + new_object_params['syslogDefaultRule'] = self.new_object.get('syslogDefaultRule') + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + return new_object_params + + def get_object_by_name(self, name): + result = None + # NOTE: Does not have a get by name method, using get all + try: + items = self.meraki.exec_meraki( + family="appliance", + function="getNetworkApplianceFirewallInboundFirewallRules", + params=self.get_all_params(name=name), + ) + if isinstance(items, dict): + if 'response' in items: + items = items.get('response') + result = get_dict_result(items, 'name', name) + if result is None: + result = items + except Exception as e: + print("Error: ", e) + result = None + return result + + def get_object_by_id(self, id): + result = None + # NOTE: Does not have a get by id method or it is in another action + return result + + def exists(self): + prev_obj = None + id_exists = False + name_exists = False + o_id = self.new_object.get("networkId") or self.new_object.get("network_id") + name = self.new_object.get("name") + if o_id: + prev_obj = self.get_object_by_name(o_id) + id_exists = prev_obj is not None and isinstance(prev_obj, dict) + if not id_exists and name: + prev_obj = self.get_object_by_name(name) + name_exists = prev_obj is not None and isinstance(prev_obj, dict) + if name_exists: + _id = prev_obj.get("id") + if id_exists and name_exists and o_id != _id: + raise InconsistentParameters( + "The 'id' and 'name' params don't refer to the same object") + if _id: + self.new_object.update(dict(id=_id)) + it_exists = prev_obj is not None and isinstance(prev_obj, dict) + return (it_exists, prev_obj) + + def requires_update(self, current_obj): + requested_obj = self.new_object + + obj_params = [ + ("rules", "rules"), + ("syslogDefaultRule", "syslogDefaultRule"), + ("networkId", "networkId"), + ] + # Method 1. Params present in request (Ansible) obj are the same as the current (ISE) params + # If any does not have eq params, it requires update + return any(not meraki_compare_equality(current_obj.get(meraki_param), + requested_obj.get(ansible_param)) + for (meraki_param, ansible_param) in obj_params) + + def update(self): + id = self.new_object.get("id") + name = self.new_object.get("name") + result = None + result = self.meraki.exec_meraki( + family="appliance", + function="updateNetworkApplianceFirewallInboundFirewallRules", + params=self.update_all_params(), + op_modifies=True, + ) + return result + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = False + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + meraki = MERAKI(self._task.args) + obj = NetworksApplianceFirewallInboundFirewallRules(self._task.args, meraki) + + state = self._task.args.get("state") + + response = None + if state == "present": + (obj_exists, prev_obj) = obj.exists() + if obj_exists: + if obj.requires_update(prev_obj): + response = obj.update() + meraki.object_updated() + else: + response = prev_obj + meraki.object_already_present() + else: + meraki.fail_json( + "Object does not exists, plugin only has update") + + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_appliance_firewall_inbound_firewall_rules_info.py b/ansible_collections/cisco/meraki/plugins/action/networks_appliance_firewall_inbound_firewall_rules_info.py new file mode 100644 index 000000000..3a9ca8669 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_appliance_firewall_inbound_firewall_rules_info.py @@ -0,0 +1,90 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + networkId=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_all(self, params): + new_object = {} + if params.get("networkId") is not None: + new_object["networkId"] = params.get( + "networkId") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="appliance", + function='getNetworkApplianceFirewallInboundFirewallRules', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_appliance_firewall_l3_firewall_rules.py b/ansible_collections/cisco/meraki/plugins/action/networks_appliance_firewall_l3_firewall_rules.py new file mode 100644 index 000000000..3e844eca4 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_appliance_firewall_l3_firewall_rules.py @@ -0,0 +1,206 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or +# https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, + meraki_compare_equality, + get_dict_result, + delete_default_rule, +) +from ansible_collections.cisco.meraki.plugins.plugin_utils.exceptions import ( + InconsistentParameters, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + state=dict(type="str", default="present", choices=["present"]), + rules=dict(type="list"), + syslogDefaultRule=dict(type="bool"), + networkId=dict(type="str"), +)) + +required_if = [ + ("state", "present", ["networkId"], True), +] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class NetworksApplianceFirewallL3FirewallRules(object): + def __init__(self, params, meraki): + self.meraki = meraki + self.new_object = dict( + rules=params.get("rules"), + syslogDefaultRule=params.get("syslogDefaultRule"), + network_id=params.get("networkId"), + ) + + def get_all_params(self, name=None, id=None): + new_object_params = {} + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + return new_object_params + + def update_all_params(self): + new_object_params = {} + if self.new_object.get('rules') is not None or self.new_object.get('rules') is not None: + new_object_params['rules'] = self.new_object.get('rules') or \ + self.new_object.get('rules') + if self.new_object.get('syslogDefaultRule') is not None or self.new_object.get('syslog_default_rule') is not None: + new_object_params['syslogDefaultRule'] = self.new_object.get('syslogDefaultRule') + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + return new_object_params + + def get_object_by_name(self, name): + result = None + # NOTE: Does not have a get by name method, using get all + try: + items = self.meraki.exec_meraki( + family="appliance", + function="getNetworkApplianceFirewallL3FirewallRules", + params=self.get_all_params(name=name), + ) + if isinstance(items, dict): + if 'response' in items: + items = items.get('response') + result = get_dict_result(items, 'name', name) + if result is None: + result = items + except Exception as e: + print("Error: ", e) + result = None + return result + + def get_object_by_id(self, id): + result = None + # NOTE: Does not have a get by id method or it is in another action + return result + + def exists(self): + prev_obj = None + id_exists = False + name_exists = False + o_id = self.new_object.get("networkId") or self.new_object.get("network_id") + name = self.new_object.get("name") + if o_id: + prev_obj = self.get_object_by_name(o_id) + id_exists = prev_obj is not None and isinstance(prev_obj, dict) + if not id_exists and name: + prev_obj = self.get_object_by_name(name) + name_exists = prev_obj is not None and isinstance(prev_obj, dict) + if name_exists: + _id = prev_obj.get("id") + if id_exists and name_exists and o_id != _id: + raise InconsistentParameters( + "The 'id' and 'name' params don't refer to the same object") + if _id: + self.new_object.update(dict(id=_id)) + it_exists = prev_obj is not None and isinstance(prev_obj, dict) + return (it_exists, prev_obj) + + def requires_update(self, current_obj): + requested_obj = self.new_object + current_obj["rules"] = delete_default_rule(current_obj["rules"]) + obj_params = [ + ("rules", "rules"), + ("syslogDefaultRule", "syslogDefaultRule"), + ("networkId", "networkId"), + ] + # Method 1. Params present in request (Ansible) obj are the same as the current (ISE) params + # If any does not have eq params, it requires update + return any(not meraki_compare_equality(current_obj.get(meraki_param), + requested_obj.get(ansible_param)) + for (meraki_param, ansible_param) in obj_params) + + def update(self): + id = self.new_object.get("id") + name = self.new_object.get("name") + result = None + result = self.meraki.exec_meraki( + family="appliance", + function="updateNetworkApplianceFirewallL3FirewallRules", + params=self.update_all_params(), + op_modifies=True, + ) + return result + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = False + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + meraki = MERAKI(self._task.args) + obj = NetworksApplianceFirewallL3FirewallRules(self._task.args, meraki) + + state = self._task.args.get("state") + + response = None + if state == "present": + (obj_exists, prev_obj) = obj.exists() + if obj_exists: + if obj.requires_update(prev_obj): + response = obj.update() + meraki.object_updated() + else: + response = prev_obj + meraki.object_already_present() + else: + meraki.fail_json( + "Object does not exists, plugin only has update") + + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_appliance_firewall_l3_firewall_rules_info.py b/ansible_collections/cisco/meraki/plugins/action/networks_appliance_firewall_l3_firewall_rules_info.py new file mode 100644 index 000000000..6cf9ac0ee --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_appliance_firewall_l3_firewall_rules_info.py @@ -0,0 +1,90 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + networkId=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_all(self, params): + new_object = {} + if params.get("networkId") is not None: + new_object["networkId"] = params.get( + "networkId") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="appliance", + function='getNetworkApplianceFirewallL3FirewallRules', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_appliance_firewall_l7_firewall_rules.py b/ansible_collections/cisco/meraki/plugins/action/networks_appliance_firewall_l7_firewall_rules.py new file mode 100644 index 000000000..74622aa78 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_appliance_firewall_l7_firewall_rules.py @@ -0,0 +1,200 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or +# https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, + meraki_compare_equality, + get_dict_result, +) +from ansible_collections.cisco.meraki.plugins.plugin_utils.exceptions import ( + InconsistentParameters, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + state=dict(type="str", default="present", choices=["present"]), + rules=dict(type="list"), + networkId=dict(type="str"), +)) + +required_if = [ + ("state", "present", ["networkId"], True), +] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class NetworksApplianceFirewallL7FirewallRules(object): + def __init__(self, params, meraki): + self.meraki = meraki + self.new_object = dict( + rules=params.get("rules"), + network_id=params.get("networkId"), + ) + + def get_all_params(self, name=None, id=None): + new_object_params = {} + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + return new_object_params + + def update_all_params(self): + new_object_params = {} + if self.new_object.get('rules') is not None or self.new_object.get('rules') is not None: + new_object_params['rules'] = self.new_object.get('rules') or \ + self.new_object.get('rules') + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + return new_object_params + + def get_object_by_name(self, name): + result = None + # NOTE: Does not have a get by name method, using get all + try: + items = self.meraki.exec_meraki( + family="appliance", + function="getNetworkApplianceFirewallL7FirewallRules", + params=self.get_all_params(name=name), + ) + if isinstance(items, dict): + if 'response' in items: + items = items.get('response') + result = get_dict_result(items, 'name', name) + if result is None: + result = items + except Exception as e: + print("Error: ", e) + result = None + return result + + def get_object_by_id(self, id): + result = None + # NOTE: Does not have a get by id method or it is in another action + return result + + def exists(self): + prev_obj = None + id_exists = False + name_exists = False + o_id = self.new_object.get("networkId") or self.new_object.get("network_id") + name = self.new_object.get("name") + if o_id: + prev_obj = self.get_object_by_name(o_id) + id_exists = prev_obj is not None and isinstance(prev_obj, dict) + if not id_exists and name: + prev_obj = self.get_object_by_name(name) + name_exists = prev_obj is not None and isinstance(prev_obj, dict) + if name_exists: + _id = prev_obj.get("id") + if id_exists and name_exists and o_id != _id: + raise InconsistentParameters( + "The 'id' and 'name' params don't refer to the same object") + if _id: + self.new_object.update(dict(id=_id)) + it_exists = prev_obj is not None and isinstance(prev_obj, dict) + return (it_exists, prev_obj) + + def requires_update(self, current_obj): + requested_obj = self.new_object + + obj_params = [ + ("rules", "rules"), + ("networkId", "networkId"), + ] + # Method 1. Params present in request (Ansible) obj are the same as the current (ISE) params + # If any does not have eq params, it requires update + return any(not meraki_compare_equality(current_obj.get(meraki_param), + requested_obj.get(ansible_param)) + for (meraki_param, ansible_param) in obj_params) + + def update(self): + id = self.new_object.get("id") + name = self.new_object.get("name") + result = None + result = self.meraki.exec_meraki( + family="appliance", + function="updateNetworkApplianceFirewallL7FirewallRules", + params=self.update_all_params(), + op_modifies=True, + ) + return result + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = False + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + meraki = MERAKI(self._task.args) + obj = NetworksApplianceFirewallL7FirewallRules(self._task.args, meraki) + + state = self._task.args.get("state") + + response = None + if state == "present": + (obj_exists, prev_obj) = obj.exists() + if obj_exists: + if obj.requires_update(prev_obj): + response = obj.update() + meraki.object_updated() + else: + response = prev_obj + meraki.object_already_present() + else: + meraki.fail_json( + "Object does not exists, plugin only has update") + + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_appliance_firewall_l7_firewall_rules_application_categories_info.py b/ansible_collections/cisco/meraki/plugins/action/networks_appliance_firewall_l7_firewall_rules_application_categories_info.py new file mode 100644 index 000000000..a98eeb365 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_appliance_firewall_l7_firewall_rules_application_categories_info.py @@ -0,0 +1,90 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + networkId=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_all(self, params): + new_object = {} + if params.get("networkId") is not None: + new_object["networkId"] = params.get( + "networkId") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="appliance", + function='getNetworkApplianceFirewallL7FirewallRulesApplicationCategories', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_appliance_firewall_l7_firewall_rules_info.py b/ansible_collections/cisco/meraki/plugins/action/networks_appliance_firewall_l7_firewall_rules_info.py new file mode 100644 index 000000000..83549a993 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_appliance_firewall_l7_firewall_rules_info.py @@ -0,0 +1,90 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + networkId=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_all(self, params): + new_object = {} + if params.get("networkId") is not None: + new_object["networkId"] = params.get( + "networkId") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="appliance", + function='getNetworkApplianceFirewallL7FirewallRules', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_appliance_firewall_one_to_many_nat_rules.py b/ansible_collections/cisco/meraki/plugins/action/networks_appliance_firewall_one_to_many_nat_rules.py new file mode 100644 index 000000000..28030b364 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_appliance_firewall_one_to_many_nat_rules.py @@ -0,0 +1,200 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or +# https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, + meraki_compare_equality, + get_dict_result, +) +from ansible_collections.cisco.meraki.plugins.plugin_utils.exceptions import ( + InconsistentParameters, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + state=dict(type="str", default="present", choices=["present"]), + rules=dict(type="list"), + networkId=dict(type="str"), +)) + +required_if = [ + ("state", "present", ["networkId"], True), +] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class NetworksApplianceFirewallOneToManyNatRules(object): + def __init__(self, params, meraki): + self.meraki = meraki + self.new_object = dict( + rules=params.get("rules"), + network_id=params.get("networkId"), + ) + + def get_all_params(self, name=None, id=None): + new_object_params = {} + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + return new_object_params + + def update_all_params(self): + new_object_params = {} + if self.new_object.get('rules') is not None or self.new_object.get('rules') is not None: + new_object_params['rules'] = self.new_object.get('rules') or \ + self.new_object.get('rules') + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + return new_object_params + + def get_object_by_name(self, name): + result = None + # NOTE: Does not have a get by name method, using get all + try: + items = self.meraki.exec_meraki( + family="appliance", + function="getNetworkApplianceFirewallOneToManyNatRules", + params=self.get_all_params(name=name), + ) + if isinstance(items, dict): + if 'response' in items: + items = items.get('response') + result = get_dict_result(items, 'name', name) + if result is None: + result = items + except Exception as e: + print("Error: ", e) + result = None + return result + + def get_object_by_id(self, id): + result = None + # NOTE: Does not have a get by id method or it is in another action + return result + + def exists(self): + prev_obj = None + id_exists = False + name_exists = False + o_id = self.new_object.get("networkId") or self.new_object.get("network_id") + name = self.new_object.get("name") + if o_id: + prev_obj = self.get_object_by_name(o_id) + id_exists = prev_obj is not None and isinstance(prev_obj, dict) + if not id_exists and name: + prev_obj = self.get_object_by_name(name) + name_exists = prev_obj is not None and isinstance(prev_obj, dict) + if name_exists: + _id = prev_obj.get("id") + if id_exists and name_exists and o_id != _id: + raise InconsistentParameters( + "The 'id' and 'name' params don't refer to the same object") + if _id: + self.new_object.update(dict(id=_id)) + it_exists = prev_obj is not None and isinstance(prev_obj, dict) + return (it_exists, prev_obj) + + def requires_update(self, current_obj): + requested_obj = self.new_object + + obj_params = [ + ("rules", "rules"), + ("networkId", "networkId"), + ] + # Method 1. Params present in request (Ansible) obj are the same as the current (ISE) params + # If any does not have eq params, it requires update + return any(not meraki_compare_equality(current_obj.get(meraki_param), + requested_obj.get(ansible_param)) + for (meraki_param, ansible_param) in obj_params) + + def update(self): + id = self.new_object.get("id") + name = self.new_object.get("name") + result = None + result = self.meraki.exec_meraki( + family="appliance", + function="updateNetworkApplianceFirewallOneToManyNatRules", + params=self.update_all_params(), + op_modifies=True, + ) + return result + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = False + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + meraki = MERAKI(self._task.args) + obj = NetworksApplianceFirewallOneToManyNatRules(self._task.args, meraki) + + state = self._task.args.get("state") + + response = None + if state == "present": + (obj_exists, prev_obj) = obj.exists() + if obj_exists: + if obj.requires_update(prev_obj): + response = obj.update() + meraki.object_updated() + else: + response = prev_obj + meraki.object_already_present() + else: + meraki.fail_json( + "Object does not exists, plugin only has update") + + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_appliance_firewall_one_to_many_nat_rules_info.py b/ansible_collections/cisco/meraki/plugins/action/networks_appliance_firewall_one_to_many_nat_rules_info.py new file mode 100644 index 000000000..fba2f3f37 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_appliance_firewall_one_to_many_nat_rules_info.py @@ -0,0 +1,90 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + networkId=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_all(self, params): + new_object = {} + if params.get("networkId") is not None: + new_object["networkId"] = params.get( + "networkId") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="appliance", + function='getNetworkApplianceFirewallOneToManyNatRules', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_appliance_firewall_one_to_one_nat_rules.py b/ansible_collections/cisco/meraki/plugins/action/networks_appliance_firewall_one_to_one_nat_rules.py new file mode 100644 index 000000000..73f1f9bb7 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_appliance_firewall_one_to_one_nat_rules.py @@ -0,0 +1,200 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or +# https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, + meraki_compare_equality, + get_dict_result, +) +from ansible_collections.cisco.meraki.plugins.plugin_utils.exceptions import ( + InconsistentParameters, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + state=dict(type="str", default="present", choices=["present"]), + rules=dict(type="list"), + networkId=dict(type="str"), +)) + +required_if = [ + ("state", "present", ["networkId"], True), +] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class NetworksApplianceFirewallOneToOneNatRules(object): + def __init__(self, params, meraki): + self.meraki = meraki + self.new_object = dict( + rules=params.get("rules"), + network_id=params.get("networkId"), + ) + + def get_all_params(self, name=None, id=None): + new_object_params = {} + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + return new_object_params + + def update_all_params(self): + new_object_params = {} + if self.new_object.get('rules') is not None or self.new_object.get('rules') is not None: + new_object_params['rules'] = self.new_object.get('rules') or \ + self.new_object.get('rules') + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + return new_object_params + + def get_object_by_name(self, name): + result = None + # NOTE: Does not have a get by name method, using get all + try: + items = self.meraki.exec_meraki( + family="appliance", + function="getNetworkApplianceFirewallOneToOneNatRules", + params=self.get_all_params(name=name), + ) + if isinstance(items, dict): + if 'response' in items: + items = items.get('response') + result = get_dict_result(items, 'name', name) + if result is None: + result = items + except Exception as e: + print("Error: ", e) + result = None + return result + + def get_object_by_id(self, id): + result = None + # NOTE: Does not have a get by id method or it is in another action + return result + + def exists(self): + prev_obj = None + id_exists = False + name_exists = False + o_id = self.new_object.get("networkId") or self.new_object.get("network_id") + name = self.new_object.get("name") + if o_id: + prev_obj = self.get_object_by_name(o_id) + id_exists = prev_obj is not None and isinstance(prev_obj, dict) + if not id_exists and name: + prev_obj = self.get_object_by_name(name) + name_exists = prev_obj is not None and isinstance(prev_obj, dict) + if name_exists: + _id = prev_obj.get("id") + if id_exists and name_exists and o_id != _id: + raise InconsistentParameters( + "The 'id' and 'name' params don't refer to the same object") + if _id: + self.new_object.update(dict(id=_id)) + it_exists = prev_obj is not None and isinstance(prev_obj, dict) + return (it_exists, prev_obj) + + def requires_update(self, current_obj): + requested_obj = self.new_object + + obj_params = [ + ("rules", "rules"), + ("networkId", "networkId"), + ] + # Method 1. Params present in request (Ansible) obj are the same as the current (ISE) params + # If any does not have eq params, it requires update + return any(not meraki_compare_equality(current_obj.get(meraki_param), + requested_obj.get(ansible_param)) + for (meraki_param, ansible_param) in obj_params) + + def update(self): + id = self.new_object.get("id") + name = self.new_object.get("name") + result = None + result = self.meraki.exec_meraki( + family="appliance", + function="updateNetworkApplianceFirewallOneToOneNatRules", + params=self.update_all_params(), + op_modifies=True, + ) + return result + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = False + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + meraki = MERAKI(self._task.args) + obj = NetworksApplianceFirewallOneToOneNatRules(self._task.args, meraki) + + state = self._task.args.get("state") + + response = None + if state == "present": + (obj_exists, prev_obj) = obj.exists() + if obj_exists: + if obj.requires_update(prev_obj): + response = obj.update() + meraki.object_updated() + else: + response = prev_obj + meraki.object_already_present() + else: + meraki.fail_json( + "Object does not exists, plugin only has update") + + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_appliance_firewall_one_to_one_nat_rules_info.py b/ansible_collections/cisco/meraki/plugins/action/networks_appliance_firewall_one_to_one_nat_rules_info.py new file mode 100644 index 000000000..6877367f8 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_appliance_firewall_one_to_one_nat_rules_info.py @@ -0,0 +1,90 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + networkId=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_all(self, params): + new_object = {} + if params.get("networkId") is not None: + new_object["networkId"] = params.get( + "networkId") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="appliance", + function='getNetworkApplianceFirewallOneToOneNatRules', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_appliance_firewall_port_forwarding_rules.py b/ansible_collections/cisco/meraki/plugins/action/networks_appliance_firewall_port_forwarding_rules.py new file mode 100644 index 000000000..154ae1721 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_appliance_firewall_port_forwarding_rules.py @@ -0,0 +1,200 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or +# https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, + meraki_compare_equality, + get_dict_result, +) +from ansible_collections.cisco.meraki.plugins.plugin_utils.exceptions import ( + InconsistentParameters, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + state=dict(type="str", default="present", choices=["present"]), + rules=dict(type="list"), + networkId=dict(type="str"), +)) + +required_if = [ + ("state", "present", ["networkId"], True), +] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class NetworksApplianceFirewallPortForwardingRules(object): + def __init__(self, params, meraki): + self.meraki = meraki + self.new_object = dict( + rules=params.get("rules"), + network_id=params.get("networkId"), + ) + + def get_all_params(self, name=None, id=None): + new_object_params = {} + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + return new_object_params + + def update_all_params(self): + new_object_params = {} + if self.new_object.get('rules') is not None or self.new_object.get('rules') is not None: + new_object_params['rules'] = self.new_object.get('rules') or \ + self.new_object.get('rules') + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + return new_object_params + + def get_object_by_name(self, name): + result = None + # NOTE: Does not have a get by name method, using get all + try: + items = self.meraki.exec_meraki( + family="appliance", + function="getNetworkApplianceFirewallPortForwardingRules", + params=self.get_all_params(name=name), + ) + if isinstance(items, dict): + if 'response' in items: + items = items.get('response') + result = get_dict_result(items, 'name', name) + if result is None: + result = items + except Exception as e: + print("Error: ", e) + result = None + return result + + def get_object_by_id(self, id): + result = None + # NOTE: Does not have a get by id method or it is in another action + return result + + def exists(self): + prev_obj = None + id_exists = False + name_exists = False + o_id = self.new_object.get("networkId") or self.new_object.get("network_id") + name = self.new_object.get("name") + if o_id: + prev_obj = self.get_object_by_name(o_id) + id_exists = prev_obj is not None and isinstance(prev_obj, dict) + if not id_exists and name: + prev_obj = self.get_object_by_name(name) + name_exists = prev_obj is not None and isinstance(prev_obj, dict) + if name_exists: + _id = prev_obj.get("id") + if id_exists and name_exists and o_id != _id: + raise InconsistentParameters( + "The 'id' and 'name' params don't refer to the same object") + if _id: + self.new_object.update(dict(id=_id)) + it_exists = prev_obj is not None and isinstance(prev_obj, dict) + return (it_exists, prev_obj) + + def requires_update(self, current_obj): + requested_obj = self.new_object + + obj_params = [ + ("rules", "rules"), + ("networkId", "networkId"), + ] + # Method 1. Params present in request (Ansible) obj are the same as the current (ISE) params + # If any does not have eq params, it requires update + return any(not meraki_compare_equality(current_obj.get(meraki_param), + requested_obj.get(ansible_param)) + for (meraki_param, ansible_param) in obj_params) + + def update(self): + id = self.new_object.get("id") + name = self.new_object.get("name") + result = None + result = self.meraki.exec_meraki( + family="appliance", + function="updateNetworkApplianceFirewallPortForwardingRules", + params=self.update_all_params(), + op_modifies=True, + ) + return result + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = False + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + meraki = MERAKI(self._task.args) + obj = NetworksApplianceFirewallPortForwardingRules(self._task.args, meraki) + + state = self._task.args.get("state") + + response = None + if state == "present": + (obj_exists, prev_obj) = obj.exists() + if obj_exists: + if obj.requires_update(prev_obj): + response = obj.update() + meraki.object_updated() + else: + response = prev_obj + meraki.object_already_present() + else: + meraki.fail_json( + "Object does not exists, plugin only has update") + + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_appliance_firewall_port_forwarding_rules_info.py b/ansible_collections/cisco/meraki/plugins/action/networks_appliance_firewall_port_forwarding_rules_info.py new file mode 100644 index 000000000..f1a0162f2 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_appliance_firewall_port_forwarding_rules_info.py @@ -0,0 +1,90 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + networkId=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_all(self, params): + new_object = {} + if params.get("networkId") is not None: + new_object["networkId"] = params.get( + "networkId") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="appliance", + function='getNetworkApplianceFirewallPortForwardingRules', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_appliance_firewall_settings.py b/ansible_collections/cisco/meraki/plugins/action/networks_appliance_firewall_settings.py new file mode 100644 index 000000000..3a06a2713 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_appliance_firewall_settings.py @@ -0,0 +1,200 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or +# https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, + meraki_compare_equality, + get_dict_result, +) +from ansible_collections.cisco.meraki.plugins.plugin_utils.exceptions import ( + InconsistentParameters, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + state=dict(type="str", default="present", choices=["present"]), + spoofingProtection=dict(type="dict"), + networkId=dict(type="str"), +)) + +required_if = [ + ("state", "present", ["networkId"], True), +] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class NetworksApplianceFirewallSettings(object): + def __init__(self, params, meraki): + self.meraki = meraki + self.new_object = dict( + spoofingProtection=params.get("spoofingProtection"), + network_id=params.get("networkId"), + ) + + def get_all_params(self, name=None, id=None): + new_object_params = {} + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + return new_object_params + + def update_all_params(self): + new_object_params = {} + if self.new_object.get('spoofingProtection') is not None or self.new_object.get('spoofing_protection') is not None: + new_object_params['spoofingProtection'] = self.new_object.get('spoofingProtection') or \ + self.new_object.get('spoofing_protection') + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + return new_object_params + + def get_object_by_name(self, name): + result = None + # NOTE: Does not have a get by name method, using get all + try: + items = self.meraki.exec_meraki( + family="appliance", + function="getNetworkApplianceFirewallSettings", + params=self.get_all_params(name=name), + ) + if isinstance(items, dict): + if 'response' in items: + items = items.get('response') + result = get_dict_result(items, 'name', name) + if result is None: + result = items + except Exception as e: + print("Error: ", e) + result = None + return result + + def get_object_by_id(self, id): + result = None + # NOTE: Does not have a get by id method or it is in another action + return result + + def exists(self): + prev_obj = None + id_exists = False + name_exists = False + o_id = self.new_object.get("networkId") or self.new_object.get("network_id") + name = self.new_object.get("name") + if o_id: + prev_obj = self.get_object_by_name(o_id) + id_exists = prev_obj is not None and isinstance(prev_obj, dict) + if not id_exists and name: + prev_obj = self.get_object_by_name(name) + name_exists = prev_obj is not None and isinstance(prev_obj, dict) + if name_exists: + _id = prev_obj.get("id") + if id_exists and name_exists and o_id != _id: + raise InconsistentParameters( + "The 'id' and 'name' params don't refer to the same object") + if _id: + self.new_object.update(dict(id=_id)) + it_exists = prev_obj is not None and isinstance(prev_obj, dict) + return (it_exists, prev_obj) + + def requires_update(self, current_obj): + requested_obj = self.new_object + + obj_params = [ + ("spoofingProtection", "spoofingProtection"), + ("networkId", "networkId"), + ] + # Method 1. Params present in request (Ansible) obj are the same as the current (ISE) params + # If any does not have eq params, it requires update + return any(not meraki_compare_equality(current_obj.get(meraki_param), + requested_obj.get(ansible_param)) + for (meraki_param, ansible_param) in obj_params) + + def update(self): + id = self.new_object.get("id") + name = self.new_object.get("name") + result = None + result = self.meraki.exec_meraki( + family="appliance", + function="updateNetworkApplianceFirewallSettings", + params=self.update_all_params(), + op_modifies=True, + ) + return result + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = False + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + meraki = MERAKI(self._task.args) + obj = NetworksApplianceFirewallSettings(self._task.args, meraki) + + state = self._task.args.get("state") + + response = None + if state == "present": + (obj_exists, prev_obj) = obj.exists() + if obj_exists: + if obj.requires_update(prev_obj): + response = obj.update() + meraki.object_updated() + else: + response = prev_obj + meraki.object_already_present() + else: + meraki.fail_json( + "Object does not exists, plugin only has update") + + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_appliance_firewall_settings_info.py b/ansible_collections/cisco/meraki/plugins/action/networks_appliance_firewall_settings_info.py new file mode 100644 index 000000000..c75bb134b --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_appliance_firewall_settings_info.py @@ -0,0 +1,90 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + networkId=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_all(self, params): + new_object = {} + if params.get("networkId") is not None: + new_object["networkId"] = params.get( + "networkId") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="appliance", + function='getNetworkApplianceFirewallSettings', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_appliance_ports.py b/ansible_collections/cisco/meraki/plugins/action/networks_appliance_ports.py new file mode 100644 index 000000000..1c57e3fb3 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_appliance_ports.py @@ -0,0 +1,271 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or +# https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, + meraki_compare_equality, + get_dict_result, +) +from ansible_collections.cisco.meraki.plugins.plugin_utils.exceptions import ( + InconsistentParameters, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + state=dict(type="str", default="present", choices=["present"]), + enabled=dict(type="bool"), + dropUntaggedTraffic=dict(type="bool"), + type=dict(type="str"), + vlan=dict(type="int"), + allowedVlans=dict(type="str"), + accessPolicy=dict(type="str"), + networkId=dict(type="str"), + portId=dict(type="str"), +)) + +required_if = [ + ("state", "present", ["networkId", "portId"], True), +] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class NetworksAppliancePorts(object): + def __init__(self, params, meraki): + self.meraki = meraki + self.new_object = dict( + enabled=params.get("enabled"), + dropUntaggedTraffic=params.get("dropUntaggedTraffic"), + type=params.get("type"), + vlan=params.get("vlan"), + allowedVlans=params.get("allowedVlans"), + accessPolicy=params.get("accessPolicy"), + network_id=params.get("networkId"), + port_id=params.get("portId"), + ) + + def get_all_params(self, name=None, id=None): + new_object_params = {} + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + return new_object_params + + def get_params_by_id(self, name=None, id=None): + new_object_params = {} + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + if self.new_object.get('portId') is not None or self.new_object.get('port_id') is not None: + new_object_params['portId'] = self.new_object.get('portId') or \ + self.new_object.get('port_id') + return new_object_params + + def update_by_id_params(self): + new_object_params = {} + if self.new_object.get('enabled') is not None or self.new_object.get('enabled') is not None: + new_object_params['enabled'] = self.new_object.get('enabled') + if self.new_object.get('dropUntaggedTraffic') is not None or self.new_object.get('drop_untagged_traffic') is not None: + new_object_params['dropUntaggedTraffic'] = self.new_object.get('dropUntaggedTraffic') + if self.new_object.get('type') is not None or self.new_object.get('type') is not None: + new_object_params['type'] = self.new_object.get('type') or \ + self.new_object.get('type') + if self.new_object.get('vlan') is not None or self.new_object.get('vlan') is not None: + new_object_params['vlan'] = self.new_object.get('vlan') or \ + self.new_object.get('vlan') + if self.new_object.get('allowedVlans') is not None or self.new_object.get('allowed_vlans') is not None: + new_object_params['allowedVlans'] = self.new_object.get('allowedVlans') or \ + self.new_object.get('allowed_vlans') + if self.new_object.get('accessPolicy') is not None or self.new_object.get('access_policy') is not None: + new_object_params['accessPolicy'] = self.new_object.get('accessPolicy') or \ + self.new_object.get('access_policy') + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + if self.new_object.get('portId') is not None or self.new_object.get('port_id') is not None: + new_object_params['portId'] = self.new_object.get('portId') or \ + self.new_object.get('port_id') + return new_object_params + + def get_object_by_name(self, name): + result = None + # NOTE: Does not have a get by name method, using get all + try: + items = self.meraki.exec_meraki( + family="appliance", + function="getNetworkAppliancePorts", + params=self.get_all_params(name=name), + ) + if isinstance(items, dict): + if 'response' in items: + items = items.get('response') + result = get_dict_result(items, 'name', name) + if result is None: + result = items + except Exception as e: + print("Error: ", e) + result = None + return result + + def get_object_by_id(self, id): + result = None + try: + items = self.meraki.exec_meraki( + family="appliance", + function="getNetworkAppliancePort", + params=self.get_params_by_id() + ) + if isinstance(items, dict): + if 'response' in items: + items = items.get('response') + result = items + except Exception as e: + print("Error: ", e) + result = None + return result + + def exists(self): + prev_obj = None + id_exists = False + name_exists = False + o_id = self.new_object.get("networkId") or self.new_object.get("network_id") + o_id = o_id or self.new_object.get( + "port_id") or self.new_object.get("portId") + name = self.new_object.get("name") + if o_id: + prev_obj = self.get_object_by_id(o_id) + id_exists = prev_obj is not None and isinstance(prev_obj, dict) + if not id_exists and name: + prev_obj = self.get_object_by_name(name) + name_exists = prev_obj is not None and isinstance(prev_obj, dict) + if name_exists: + _id = prev_obj.get("id") + _id = _id or prev_obj.get("portId") + if id_exists and name_exists and o_id != _id: + raise InconsistentParameters( + "The 'id' and 'name' params don't refer to the same object") + if _id: + self.new_object.update(dict(id=_id)) + self.new_object.update(dict(portId=_id)) + if _id: + prev_obj = self.get_object_by_id(_id) + it_exists = prev_obj is not None and isinstance(prev_obj, dict) + return (it_exists, prev_obj) + + def requires_update(self, current_obj): + requested_obj = self.new_object + + obj_params = [ + ("enabled", "enabled"), + ("dropUntaggedTraffic", "dropUntaggedTraffic"), + ("type", "type"), + ("vlan", "vlan"), + ("allowedVlans", "allowedVlans"), + ("accessPolicy", "accessPolicy"), + ("networkId", "networkId"), + ("portId", "portId"), + ] + # Method 1. Params present in request (Ansible) obj are the same as the current (ISE) params + # If any does not have eq params, it requires update + return any(not meraki_compare_equality(current_obj.get(meraki_param), + requested_obj.get(ansible_param)) + for (meraki_param, ansible_param) in obj_params) + + def update(self): + id = self.new_object.get("id") + id = id or self.new_object.get("portId") + name = self.new_object.get("name") + result = None + if not id: + prev_obj_name = self.get_object_by_name(name) + id_ = None + if prev_obj_name: + id_ = prev_obj_name.get("id") + id_ = id_ or prev_obj_name.get("portId") + if id_: + self.new_object.update(dict(portid=id_)) + result = self.meraki.exec_meraki( + family="appliance", + function="updateNetworkAppliancePort", + params=self.update_by_id_params(), + op_modifies=True, + ) + return result + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = False + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + meraki = MERAKI(self._task.args) + obj = NetworksAppliancePorts(self._task.args, meraki) + + state = self._task.args.get("state") + + response = None + if state == "present": + (obj_exists, prev_obj) = obj.exists() + if obj_exists: + if obj.requires_update(prev_obj): + response = obj.update() + meraki.object_updated() + else: + response = prev_obj + meraki.object_already_present() + else: + meraki.fail_json( + "Object does not exists, plugin only has update") + + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_appliance_ports_info.py b/ansible_collections/cisco/meraki/plugins/action/networks_appliance_ports_info.py new file mode 100644 index 000000000..9a5a693de --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_appliance_ports_info.py @@ -0,0 +1,112 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + networkId=dict(type="str"), + portId=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_object(self, params): + new_object = {} + if params.get("networkId") is not None: + new_object["networkId"] = params.get( + "networkId") + if params.get("portId") is not None: + new_object["portId"] = params.get( + "portId") + return new_object + + def get_all(self, params): + new_object = {} + if params.get("networkId") is not None: + new_object["networkId"] = params.get( + "networkId") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + id = self._task.args.get("portId") + if id: + response = meraki.exec_meraki( + family="appliance", + function='getNetworkAppliancePort', + params=self.get_object(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result + if not id: + response = meraki.exec_meraki( + family="appliance", + function='getNetworkAppliancePorts', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_appliance_prefixes_delegated_statics.py b/ansible_collections/cisco/meraki/plugins/action/networks_appliance_prefixes_delegated_statics.py new file mode 100644 index 000000000..0297ff01e --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_appliance_prefixes_delegated_statics.py @@ -0,0 +1,320 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or +# https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, + meraki_compare_equality, + get_dict_result, +) +from ansible_collections.cisco.meraki.plugins.plugin_utils.exceptions import ( + InconsistentParameters, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + state=dict(type="str", default="present", choices=["present", "absent"]), + prefix=dict(type="str"), + origin=dict(type="dict"), + description=dict(type="str"), + networkId=dict(type="str"), + staticDelegatedPrefixId=dict(type="str"), +)) + +required_if = [ + ("state", "present", ["networkId", "staticDelegatedPrefixId"], True), + ("state", "absent", ["networkId", "staticDelegatedPrefixId"], True), +] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class NetworksAppliancePrefixesDelegatedStatics(object): + def __init__(self, params, meraki): + self.meraki = meraki + self.new_object = dict( + prefix=params.get("prefix"), + origin=params.get("origin"), + description=params.get("description"), + networkId=params.get("networkId"), + staticDelegatedPrefixId=params.get("staticDelegatedPrefixId"), + ) + + def get_all_params(self, name=None, id=None): + new_object_params = {} + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + return new_object_params + + def get_params_by_id(self, name=None, id=None): + new_object_params = {} + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + if self.new_object.get('staticDelegatedPrefixId') is not None or self.new_object.get('static_delegated_prefix_id') is not None: + new_object_params['staticDelegatedPrefixId'] = self.new_object.get('staticDelegatedPrefixId') or \ + self.new_object.get('static_delegated_prefix_id') + return new_object_params + + def create_params(self): + new_object_params = {} + if self.new_object.get('prefix') is not None or self.new_object.get('prefix') is not None: + new_object_params['prefix'] = self.new_object.get('prefix') or \ + self.new_object.get('prefix') + if self.new_object.get('origin') is not None or self.new_object.get('origin') is not None: + new_object_params['origin'] = self.new_object.get('origin') or \ + self.new_object.get('origin') + if self.new_object.get('description') is not None or self.new_object.get('description') is not None: + new_object_params['description'] = self.new_object.get('description') or \ + self.new_object.get('description') + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + return new_object_params + + def delete_by_id_params(self): + new_object_params = {} + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + if self.new_object.get('staticDelegatedPrefixId') is not None or self.new_object.get('static_delegated_prefix_id') is not None: + new_object_params['staticDelegatedPrefixId'] = self.new_object.get('staticDelegatedPrefixId') or \ + self.new_object.get('static_delegated_prefix_id') + return new_object_params + + def update_by_id_params(self): + new_object_params = {} + if self.new_object.get('prefix') is not None or self.new_object.get('prefix') is not None: + new_object_params['prefix'] = self.new_object.get('prefix') or \ + self.new_object.get('prefix') + if self.new_object.get('origin') is not None or self.new_object.get('origin') is not None: + new_object_params['origin'] = self.new_object.get('origin') or \ + self.new_object.get('origin') + if self.new_object.get('description') is not None or self.new_object.get('description') is not None: + new_object_params['description'] = self.new_object.get('description') or \ + self.new_object.get('description') + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + if self.new_object.get('staticDelegatedPrefixId') is not None or self.new_object.get('static_delegated_prefix_id') is not None: + new_object_params['staticDelegatedPrefixId'] = self.new_object.get('staticDelegatedPrefixId') or \ + self.new_object.get('static_delegated_prefix_id') + return new_object_params + + def get_object_by_name(self, name): + result = None + # NOTE: Does not have a get by name method or it is in another action + try: + items = self.meraki.exec_meraki( + family="appliance", + function="getNetworkAppliancePrefixesDelegatedStatics", + params=self.get_all_params(name=name), + ) + if isinstance(items, dict): + if 'response' in items: + items = items.get('response') + result = get_dict_result(items, 'name', name) + if result is None: + result = items + except Exception as e: + print("Error: ", e) + result = None + return result + + def get_object_by_id(self, id): + result = None + try: + items = self.meraki.exec_meraki( + family="appliance", + function="getNetworkAppliancePrefixesDelegatedStatic", + params=self.get_params_by_id() + ) + if isinstance(items, dict): + if 'response' in items: + items = items.get('response') + result = get_dict_result(items, 'staticDelegatedPrefixId', id) + except Exception as e: + print("Error: ", e) + result = None + return result + + def exists(self): + id_exists = False + name_exists = False + prev_obj = None + o_id = self.new_object.get("id") + o_id = o_id or self.new_object.get( + "static_delegated_prefix_id") or self.new_object.get("staticDelegatedPrefixId") + name = self.new_object.get("name") + if o_id: + prev_obj = self.get_object_by_id(o_id) + id_exists = prev_obj is not None and isinstance(prev_obj, dict) + if not id_exists and name: + prev_obj = self.get_object_by_name(name) + name_exists = prev_obj is not None and isinstance(prev_obj, dict) + if name_exists: + _id = prev_obj.get("id") + _id = _id or prev_obj.get("staticDelegatedPrefixId") + if id_exists and name_exists and o_id != _id: + raise InconsistentParameters( + "The 'id' and 'name' params don't refer to the same object") + if _id: + self.new_object.update(dict(id=_id)) + self.new_object.update(dict(staticDelegatedPrefixId=_id)) + if _id: + prev_obj = self.get_object_by_id(_id) + it_exists = prev_obj is not None and isinstance(prev_obj, dict) + return (it_exists, prev_obj) + + def requires_update(self, current_obj): + requested_obj = self.new_object + + obj_params = [ + ("prefix", "prefix"), + ("origin", "origin"), + ("description", "description"), + ("networkId", "networkId"), + ("staticDelegatedPrefixId", "staticDelegatedPrefixId"), + ] + # Method 1. Params present in request (Ansible) obj are the same as the current (DNAC) params + # If any does not have eq params, it requires update + return any(not meraki_compare_equality(current_obj.get(meraki_param), + requested_obj.get(ansible_param)) + for (meraki_param, ansible_param) in obj_params) + + def create(self): + result = self.meraki.exec_meraki( + family="appliance", + function="createNetworkAppliancePrefixesDelegatedStatic", + params=self.create_params(), + op_modifies=True, + ) + return result + + def update(self): + id = self.new_object.get("id") + id = id or self.new_object.get("staticDelegatedPrefixId") + name = self.new_object.get("name") + result = None + if not id: + prev_obj_name = self.get_object_by_name(name) + id_ = None + if prev_obj_name: + id_ = prev_obj_name.get("id") + id_ = id_ or prev_obj_name.get("staticDelegatedPrefixId") + if id_: + self.new_object.update(dict(staticDelegatedPrefixId=id_)) + result = self.meraki.exec_meraki( + family="appliance", + function="updateNetworkAppliancePrefixesDelegatedStatic", + params=self.update_by_id_params(), + op_modifies=True, + ) + return result + + def delete(self): + id = self.new_object.get("id") + id = id or self.new_object.get("staticDelegatedPrefixId") + name = self.new_object.get("name") + result = None + if not id: + prev_obj_name = self.get_object_by_name(name) + id_ = None + if prev_obj_name: + id_ = prev_obj_name.get("id") + id_ = id_ or prev_obj_name.get("staticDelegatedPrefixId") + if id_: + self.new_object.update(dict(staticDelegatedPrefixId=id_)) + result = self.meraki.exec_meraki( + family="appliance", + function="deleteNetworkAppliancePrefixesDelegatedStatic", + params=self.delete_by_id_params(), + ) + return result + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = False + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + meraki = MERAKI(self._task.args) + obj = NetworksAppliancePrefixesDelegatedStatics(self._task.args, meraki) + + state = self._task.args.get("state") + + response = None + + if state == "present": + (obj_exists, prev_obj) = obj.exists() + if obj_exists: + if obj.requires_update(prev_obj): + response = obj.update() + meraki.object_updated() + else: + response = prev_obj + meraki.object_already_present() + else: + response = obj.create() + meraki.object_created() + + elif state == "absent": + (obj_exists, prev_obj) = obj.exists() + if obj_exists: + response = obj.delete() + meraki.object_deleted() + else: + meraki.object_already_absent() + + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_appliance_prefixes_delegated_statics_info.py b/ansible_collections/cisco/meraki/plugins/action/networks_appliance_prefixes_delegated_statics_info.py new file mode 100644 index 000000000..60ffe289c --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_appliance_prefixes_delegated_statics_info.py @@ -0,0 +1,112 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + networkId=dict(type="str"), + staticDelegatedPrefixId=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_object(self, params): + new_object = {} + if params.get("networkId") is not None: + new_object["networkId"] = params.get( + "networkId") + if params.get("staticDelegatedPrefixId") is not None: + new_object["staticDelegatedPrefixId"] = params.get( + "staticDelegatedPrefixId") + return new_object + + def get_all(self, params): + new_object = {} + if params.get("networkId") is not None: + new_object["networkId"] = params.get( + "networkId") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + id = self._task.args.get("staticDelegatedPrefixId") + if id: + response = meraki.exec_meraki( + family="appliance", + function='getNetworkAppliancePrefixesDelegatedStatic', + params=self.get_object(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result + if not id: + response = meraki.exec_meraki( + family="appliance", + function='getNetworkAppliancePrefixesDelegatedStatics', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_appliance_security_intrusion.py b/ansible_collections/cisco/meraki/plugins/action/networks_appliance_security_intrusion.py new file mode 100644 index 000000000..3449abf9c --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_appliance_security_intrusion.py @@ -0,0 +1,212 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or +# https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, + meraki_compare_equality, + get_dict_result, +) +from ansible_collections.cisco.meraki.plugins.plugin_utils.exceptions import ( + InconsistentParameters, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + state=dict(type="str", default="present", choices=["present"]), + mode=dict(type="str"), + idsRulesets=dict(type="str"), + protectedNetworks=dict(type="dict"), + networkId=dict(type="str"), +)) + +required_if = [ + ("state", "present", ["networkId"], True), +] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class NetworksApplianceSecurityIntrusion(object): + def __init__(self, params, meraki): + self.meraki = meraki + self.new_object = dict( + mode=params.get("mode"), + idsRulesets=params.get("idsRulesets"), + protectedNetworks=params.get("protectedNetworks"), + network_id=params.get("networkId"), + ) + + def get_all_params(self, name=None, id=None): + new_object_params = {} + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + return new_object_params + + def update_all_params(self): + new_object_params = {} + if self.new_object.get('mode') is not None or self.new_object.get('mode') is not None: + new_object_params['mode'] = self.new_object.get('mode') or \ + self.new_object.get('mode') + if self.new_object.get('idsRulesets') is not None or self.new_object.get('ids_rulesets') is not None: + new_object_params['idsRulesets'] = self.new_object.get('idsRulesets') or \ + self.new_object.get('ids_rulesets') + if self.new_object.get('protectedNetworks') is not None or self.new_object.get('protected_networks') is not None: + new_object_params['protectedNetworks'] = self.new_object.get('protectedNetworks') or \ + self.new_object.get('protected_networks') + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + return new_object_params + + def get_object_by_name(self, name): + result = None + # NOTE: Does not have a get by name method, using get all + try: + items = self.meraki.exec_meraki( + family="appliance", + function="getNetworkApplianceSecurityIntrusion", + params=self.get_all_params(name=name), + ) + if isinstance(items, dict): + if 'response' in items: + items = items.get('response') + result = get_dict_result(items, 'name', name) + if result is None: + result = items + except Exception as e: + print("Error: ", e) + result = None + return result + + def get_object_by_id(self, id): + result = None + # NOTE: Does not have a get by id method or it is in another action + return result + + def exists(self): + prev_obj = None + id_exists = False + name_exists = False + o_id = self.new_object.get("networkId") or self.new_object.get("network_id") + name = self.new_object.get("name") + if o_id: + prev_obj = self.get_object_by_name(o_id) + id_exists = prev_obj is not None and isinstance(prev_obj, dict) + if not id_exists and name: + prev_obj = self.get_object_by_name(name) + name_exists = prev_obj is not None and isinstance(prev_obj, dict) + if name_exists: + _id = prev_obj.get("id") + if id_exists and name_exists and o_id != _id: + raise InconsistentParameters( + "The 'id' and 'name' params don't refer to the same object") + if _id: + self.new_object.update(dict(id=_id)) + it_exists = prev_obj is not None and isinstance(prev_obj, dict) + return (it_exists, prev_obj) + + def requires_update(self, current_obj): + requested_obj = self.new_object + + obj_params = [ + ("mode", "mode"), + ("idsRulesets", "idsRulesets"), + ("protectedNetworks", "protectedNetworks"), + ("networkId", "networkId"), + ] + # Method 1. Params present in request (Ansible) obj are the same as the current (ISE) params + # If any does not have eq params, it requires update + return any(not meraki_compare_equality(current_obj.get(meraki_param), + requested_obj.get(ansible_param)) + for (meraki_param, ansible_param) in obj_params) + + def update(self): + id = self.new_object.get("id") + name = self.new_object.get("name") + result = None + result = self.meraki.exec_meraki( + family="appliance", + function="updateNetworkApplianceSecurityIntrusion", + params=self.update_all_params(), + op_modifies=True, + ) + return result + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = False + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + meraki = MERAKI(self._task.args) + obj = NetworksApplianceSecurityIntrusion(self._task.args, meraki) + + state = self._task.args.get("state") + + response = None + if state == "present": + (obj_exists, prev_obj) = obj.exists() + if obj_exists: + if obj.requires_update(prev_obj): + response = obj.update() + meraki.object_updated() + else: + response = prev_obj + meraki.object_already_present() + else: + meraki.fail_json( + "Object does not exists, plugin only has update") + + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_appliance_security_intrusion_info.py b/ansible_collections/cisco/meraki/plugins/action/networks_appliance_security_intrusion_info.py new file mode 100644 index 000000000..de1e58804 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_appliance_security_intrusion_info.py @@ -0,0 +1,90 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + networkId=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_all(self, params): + new_object = {} + if params.get("networkId") is not None: + new_object["networkId"] = params.get( + "networkId") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="appliance", + function='getNetworkApplianceSecurityIntrusion', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_appliance_security_malware.py b/ansible_collections/cisco/meraki/plugins/action/networks_appliance_security_malware.py new file mode 100644 index 000000000..904889494 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_appliance_security_malware.py @@ -0,0 +1,212 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or +# https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, + meraki_compare_equality, + get_dict_result, +) +from ansible_collections.cisco.meraki.plugins.plugin_utils.exceptions import ( + InconsistentParameters, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + state=dict(type="str", default="present", choices=["present"]), + mode=dict(type="str"), + allowedUrls=dict(type="list"), + allowedFiles=dict(type="list"), + networkId=dict(type="str"), +)) + +required_if = [ + ("state", "present", ["networkId"], True), +] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class NetworksApplianceSecurityMalware(object): + def __init__(self, params, meraki): + self.meraki = meraki + self.new_object = dict( + mode=params.get("mode"), + allowedUrls=params.get("allowedUrls"), + allowedFiles=params.get("allowedFiles"), + network_id=params.get("networkId"), + ) + + def get_all_params(self, name=None, id=None): + new_object_params = {} + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + return new_object_params + + def update_all_params(self): + new_object_params = {} + if self.new_object.get('mode') is not None or self.new_object.get('mode') is not None: + new_object_params['mode'] = self.new_object.get('mode') or \ + self.new_object.get('mode') + if self.new_object.get('allowedUrls') is not None or self.new_object.get('allowed_urls') is not None: + new_object_params['allowedUrls'] = self.new_object.get('allowedUrls') or \ + self.new_object.get('allowed_urls') + if self.new_object.get('allowedFiles') is not None or self.new_object.get('allowed_files') is not None: + new_object_params['allowedFiles'] = self.new_object.get('allowedFiles') or \ + self.new_object.get('allowed_files') + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + return new_object_params + + def get_object_by_name(self, name): + result = None + # NOTE: Does not have a get by name method, using get all + try: + items = self.meraki.exec_meraki( + family="appliance", + function="getNetworkApplianceSecurityMalware", + params=self.get_all_params(name=name), + ) + if isinstance(items, dict): + if 'response' in items: + items = items.get('response') + result = get_dict_result(items, 'name', name) + if result is None: + result = items + except Exception as e: + print("Error: ", e) + result = None + return result + + def get_object_by_id(self, id): + result = None + # NOTE: Does not have a get by id method or it is in another action + return result + + def exists(self): + prev_obj = None + id_exists = False + name_exists = False + o_id = self.new_object.get("networkId") or self.new_object.get("network_id") + name = self.new_object.get("name") + if o_id: + prev_obj = self.get_object_by_name(o_id) + id_exists = prev_obj is not None and isinstance(prev_obj, dict) + if not id_exists and name: + prev_obj = self.get_object_by_name(name) + name_exists = prev_obj is not None and isinstance(prev_obj, dict) + if name_exists: + _id = prev_obj.get("id") + if id_exists and name_exists and o_id != _id: + raise InconsistentParameters( + "The 'id' and 'name' params don't refer to the same object") + if _id: + self.new_object.update(dict(id=_id)) + it_exists = prev_obj is not None and isinstance(prev_obj, dict) + return (it_exists, prev_obj) + + def requires_update(self, current_obj): + requested_obj = self.new_object + + obj_params = [ + ("mode", "mode"), + ("allowedUrls", "allowedUrls"), + ("allowedFiles", "allowedFiles"), + ("networkId", "networkId"), + ] + # Method 1. Params present in request (Ansible) obj are the same as the current (ISE) params + # If any does not have eq params, it requires update + return any(not meraki_compare_equality(current_obj.get(meraki_param), + requested_obj.get(ansible_param)) + for (meraki_param, ansible_param) in obj_params) + + def update(self): + id = self.new_object.get("id") + name = self.new_object.get("name") + result = None + result = self.meraki.exec_meraki( + family="appliance", + function="updateNetworkApplianceSecurityMalware", + params=self.update_all_params(), + op_modifies=True, + ) + return result + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = False + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + meraki = MERAKI(self._task.args) + obj = NetworksApplianceSecurityMalware(self._task.args, meraki) + + state = self._task.args.get("state") + + response = None + if state == "present": + (obj_exists, prev_obj) = obj.exists() + if obj_exists: + if obj.requires_update(prev_obj): + response = obj.update() + meraki.object_updated() + else: + response = prev_obj + meraki.object_already_present() + else: + meraki.fail_json( + "Object does not exists, plugin only has update") + + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_appliance_security_malware_info.py b/ansible_collections/cisco/meraki/plugins/action/networks_appliance_security_malware_info.py new file mode 100644 index 000000000..865a457b0 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_appliance_security_malware_info.py @@ -0,0 +1,90 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + networkId=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_all(self, params): + new_object = {} + if params.get("networkId") is not None: + new_object["networkId"] = params.get( + "networkId") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="appliance", + function='getNetworkApplianceSecurityMalware', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_appliance_settings.py b/ansible_collections/cisco/meraki/plugins/action/networks_appliance_settings.py new file mode 100644 index 000000000..44dcf7b40 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_appliance_settings.py @@ -0,0 +1,212 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or +# https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, + meraki_compare_equality, + get_dict_result, +) +from ansible_collections.cisco.meraki.plugins.plugin_utils.exceptions import ( + InconsistentParameters, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + state=dict(type="str", default="present", choices=["present"]), + clientTrackingMethod=dict(type="str"), + deploymentMode=dict(type="str"), + dynamicDns=dict(type="dict"), + networkId=dict(type="str"), +)) + +required_if = [ + ("state", "present", ["networkId"], True), +] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class NetworksApplianceSettings(object): + def __init__(self, params, meraki): + self.meraki = meraki + self.new_object = dict( + clientTrackingMethod=params.get("clientTrackingMethod"), + deploymentMode=params.get("deploymentMode"), + dynamicDns=params.get("dynamicDns"), + network_id=params.get("networkId"), + ) + + def get_all_params(self, name=None, id=None): + new_object_params = {} + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + return new_object_params + + def update_all_params(self): + new_object_params = {} + if self.new_object.get('clientTrackingMethod') is not None or self.new_object.get('client_tracking_method') is not None: + new_object_params['clientTrackingMethod'] = self.new_object.get('clientTrackingMethod') or \ + self.new_object.get('client_tracking_method') + if self.new_object.get('deploymentMode') is not None or self.new_object.get('deployment_mode') is not None: + new_object_params['deploymentMode'] = self.new_object.get('deploymentMode') or \ + self.new_object.get('deployment_mode') + if self.new_object.get('dynamicDns') is not None or self.new_object.get('dynamic_dns') is not None: + new_object_params['dynamicDns'] = self.new_object.get('dynamicDns') or \ + self.new_object.get('dynamic_dns') + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + return new_object_params + + def get_object_by_name(self, name): + result = None + # NOTE: Does not have a get by name method, using get all + try: + items = self.meraki.exec_meraki( + family="appliance", + function="getNetworkApplianceSettings", + params=self.get_all_params(name=name), + ) + if isinstance(items, dict): + if 'response' in items: + items = items.get('response') + result = get_dict_result(items, 'name', name) + if result is None: + result = items + except Exception as e: + print("Error: ", e) + result = None + return result + + def get_object_by_id(self, id): + result = None + # NOTE: Does not have a get by id method or it is in another action + return result + + def exists(self): + prev_obj = None + id_exists = False + name_exists = False + o_id = self.new_object.get("networkId") or self.new_object.get("network_id") + name = self.new_object.get("name") + if o_id: + prev_obj = self.get_object_by_name(o_id) + id_exists = prev_obj is not None and isinstance(prev_obj, dict) + if not id_exists and name: + prev_obj = self.get_object_by_name(name) + name_exists = prev_obj is not None and isinstance(prev_obj, dict) + if name_exists: + _id = prev_obj.get("id") + if id_exists and name_exists and o_id != _id: + raise InconsistentParameters( + "The 'id' and 'name' params don't refer to the same object") + if _id: + self.new_object.update(dict(id=_id)) + it_exists = prev_obj is not None and isinstance(prev_obj, dict) + return (it_exists, prev_obj) + + def requires_update(self, current_obj): + requested_obj = self.new_object + + obj_params = [ + ("clientTrackingMethod", "clientTrackingMethod"), + ("deploymentMode", "deploymentMode"), + ("dynamicDns", "dynamicDns"), + ("networkId", "networkId"), + ] + # Method 1. Params present in request (Ansible) obj are the same as the current (ISE) params + # If any does not have eq params, it requires update + return any(not meraki_compare_equality(current_obj.get(meraki_param), + requested_obj.get(ansible_param)) + for (meraki_param, ansible_param) in obj_params) + + def update(self): + id = self.new_object.get("id") + name = self.new_object.get("name") + result = None + result = self.meraki.exec_meraki( + family="appliance", + function="updateNetworkApplianceSettings", + params=self.update_all_params(), + op_modifies=True, + ) + return result + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = False + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + meraki = MERAKI(self._task.args) + obj = NetworksApplianceSettings(self._task.args, meraki) + + state = self._task.args.get("state") + + response = None + if state == "present": + (obj_exists, prev_obj) = obj.exists() + if obj_exists: + if obj.requires_update(prev_obj): + response = obj.update() + meraki.object_updated() + else: + response = prev_obj + meraki.object_already_present() + else: + meraki.fail_json( + "Object does not exists, plugin only has update") + + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_appliance_settings_info.py b/ansible_collections/cisco/meraki/plugins/action/networks_appliance_settings_info.py new file mode 100644 index 000000000..25209da9d --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_appliance_settings_info.py @@ -0,0 +1,90 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + networkId=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_all(self, params): + new_object = {} + if params.get("networkId") is not None: + new_object["networkId"] = params.get( + "networkId") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="appliance", + function='getNetworkApplianceSettings', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_appliance_single_lan.py b/ansible_collections/cisco/meraki/plugins/action/networks_appliance_single_lan.py new file mode 100644 index 000000000..fd8219403 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_appliance_single_lan.py @@ -0,0 +1,218 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or +# https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, + meraki_compare_equality, + get_dict_result, +) +from ansible_collections.cisco.meraki.plugins.plugin_utils.exceptions import ( + InconsistentParameters, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + state=dict(type="str", default="present", choices=["present"]), + subnet=dict(type="str"), + applianceIp=dict(type="str"), + ipv6=dict(type="dict"), + mandatoryDhcp=dict(type="dict"), + networkId=dict(type="str"), +)) + +required_if = [ + ("state", "present", ["networkId"], True), +] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class NetworksApplianceSingleLan(object): + def __init__(self, params, meraki): + self.meraki = meraki + self.new_object = dict( + subnet=params.get("subnet"), + applianceIp=params.get("applianceIp"), + ipv6=params.get("ipv6"), + mandatoryDhcp=params.get("mandatoryDhcp"), + network_id=params.get("networkId"), + ) + + def get_all_params(self, name=None, id=None): + new_object_params = {} + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + return new_object_params + + def update_all_params(self): + new_object_params = {} + if self.new_object.get('subnet') is not None or self.new_object.get('subnet') is not None: + new_object_params['subnet'] = self.new_object.get('subnet') or \ + self.new_object.get('subnet') + if self.new_object.get('applianceIp') is not None or self.new_object.get('appliance_ip') is not None: + new_object_params['applianceIp'] = self.new_object.get('applianceIp') or \ + self.new_object.get('appliance_ip') + if self.new_object.get('ipv6') is not None or self.new_object.get('ipv6') is not None: + new_object_params['ipv6'] = self.new_object.get('ipv6') or \ + self.new_object.get('ipv6') + if self.new_object.get('mandatoryDhcp') is not None or self.new_object.get('mandatory_dhcp') is not None: + new_object_params['mandatoryDhcp'] = self.new_object.get('mandatoryDhcp') or \ + self.new_object.get('mandatory_dhcp') + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + return new_object_params + + def get_object_by_name(self, name): + result = None + # NOTE: Does not have a get by name method, using get all + try: + items = self.meraki.exec_meraki( + family="appliance", + function="getNetworkApplianceSingleLan", + params=self.get_all_params(name=name), + ) + if isinstance(items, dict): + if 'response' in items: + items = items.get('response') + result = get_dict_result(items, 'name', name) + if result is None: + result = items + except Exception as e: + print("Error: ", e) + result = None + return result + + def get_object_by_id(self, id): + result = None + # NOTE: Does not have a get by id method or it is in another action + return result + + def exists(self): + prev_obj = None + id_exists = False + name_exists = False + o_id = self.new_object.get("networkId") or self.new_object.get("network_id") + name = self.new_object.get("name") + if o_id: + prev_obj = self.get_object_by_name(o_id) + id_exists = prev_obj is not None and isinstance(prev_obj, dict) + if not id_exists and name: + prev_obj = self.get_object_by_name(name) + name_exists = prev_obj is not None and isinstance(prev_obj, dict) + if name_exists: + _id = prev_obj.get("id") + if id_exists and name_exists and o_id != _id: + raise InconsistentParameters( + "The 'id' and 'name' params don't refer to the same object") + if _id: + self.new_object.update(dict(id=_id)) + it_exists = prev_obj is not None and isinstance(prev_obj, dict) + return (it_exists, prev_obj) + + def requires_update(self, current_obj): + requested_obj = self.new_object + + obj_params = [ + ("subnet", "subnet"), + ("applianceIp", "applianceIp"), + ("ipv6", "ipv6"), + ("mandatoryDhcp", "mandatoryDhcp"), + ("networkId", "networkId"), + ] + # Method 1. Params present in request (Ansible) obj are the same as the current (ISE) params + # If any does not have eq params, it requires update + return any(not meraki_compare_equality(current_obj.get(meraki_param), + requested_obj.get(ansible_param)) + for (meraki_param, ansible_param) in obj_params) + + def update(self): + id = self.new_object.get("id") + name = self.new_object.get("name") + result = None + result = self.meraki.exec_meraki( + family="appliance", + function="updateNetworkApplianceSingleLan", + params=self.update_all_params(), + op_modifies=True, + ) + return result + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = False + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + meraki = MERAKI(self._task.args) + obj = NetworksApplianceSingleLan(self._task.args, meraki) + + state = self._task.args.get("state") + + response = None + if state == "present": + (obj_exists, prev_obj) = obj.exists() + if obj_exists: + if obj.requires_update(prev_obj): + response = obj.update() + meraki.object_updated() + else: + response = prev_obj + meraki.object_already_present() + else: + meraki.fail_json( + "Object does not exists, plugin only has update") + + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_appliance_single_lan_info.py b/ansible_collections/cisco/meraki/plugins/action/networks_appliance_single_lan_info.py new file mode 100644 index 000000000..8e563f246 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_appliance_single_lan_info.py @@ -0,0 +1,90 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + networkId=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_all(self, params): + new_object = {} + if params.get("networkId") is not None: + new_object["networkId"] = params.get( + "networkId") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="appliance", + function='getNetworkApplianceSingleLan', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_appliance_ssids.py b/ansible_collections/cisco/meraki/plugins/action/networks_appliance_ssids.py new file mode 100644 index 000000000..cfe172d5a --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_appliance_ssids.py @@ -0,0 +1,294 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or +# https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, + meraki_compare_equality, + get_dict_result, +) +from ansible_collections.cisco.meraki.plugins.plugin_utils.exceptions import ( + InconsistentParameters, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + state=dict(type="str", default="present", choices=["present"]), + name=dict(type="str"), + enabled=dict(type="bool"), + defaultVlanId=dict(type="int"), + authMode=dict(type="str"), + psk=dict(type="str"), + radiusServers=dict(type="list"), + encryptionMode=dict(type="str"), + wpaEncryptionMode=dict(type="str"), + visible=dict(type="bool"), + dhcpEnforcedDeauthentication=dict(type="dict"), + networkId=dict(type="str"), + number=dict(type="str"), +)) + +required_if = [ + ("state", "present", ["name", "networkId", "number"], True), +] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class NetworksApplianceSsids(object): + def __init__(self, params, meraki): + self.meraki = meraki + self.new_object = dict( + name=params.get("name"), + enabled=params.get("enabled"), + defaultVlanId=params.get("defaultVlanId"), + authMode=params.get("authMode"), + psk=params.get("psk"), + radiusServers=params.get("radiusServers"), + encryptionMode=params.get("encryptionMode"), + wpaEncryptionMode=params.get("wpaEncryptionMode"), + visible=params.get("visible"), + dhcpEnforcedDeauthentication=params.get("dhcpEnforcedDeauthentication"), + network_id=params.get("networkId"), + number=params.get("number"), + ) + + def get_all_params(self, name=None, id=None): + new_object_params = {} + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + return new_object_params + + def get_params_by_id(self, name=None, id=None): + new_object_params = {} + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + if self.new_object.get('number') is not None or self.new_object.get('number') is not None: + new_object_params['number'] = self.new_object.get('number') + return new_object_params + + def update_by_id_params(self): + new_object_params = {} + if self.new_object.get('name') is not None or self.new_object.get('name') is not None: + new_object_params['name'] = self.new_object.get('name') or \ + self.new_object.get('name') + if self.new_object.get('enabled') is not None or self.new_object.get('enabled') is not None: + new_object_params['enabled'] = self.new_object.get('enabled') + if self.new_object.get('defaultVlanId') is not None or self.new_object.get('default_vlan_id') is not None: + new_object_params['defaultVlanId'] = self.new_object.get('defaultVlanId') or \ + self.new_object.get('default_vlan_id') + if self.new_object.get('authMode') is not None or self.new_object.get('auth_mode') is not None: + new_object_params['authMode'] = self.new_object.get('authMode') or \ + self.new_object.get('auth_mode') + if self.new_object.get('psk') is not None or self.new_object.get('psk') is not None: + new_object_params['psk'] = self.new_object.get('psk') or \ + self.new_object.get('psk') + if self.new_object.get('radiusServers') is not None or self.new_object.get('radius_servers') is not None: + new_object_params['radiusServers'] = self.new_object.get('radiusServers') or \ + self.new_object.get('radius_servers') + if self.new_object.get('encryptionMode') is not None or self.new_object.get('encryption_mode') is not None: + new_object_params['encryptionMode'] = self.new_object.get('encryptionMode') or \ + self.new_object.get('encryption_mode') + if self.new_object.get('wpaEncryptionMode') is not None or self.new_object.get('wpa_encryption_mode') is not None: + new_object_params['wpaEncryptionMode'] = self.new_object.get('wpaEncryptionMode') or \ + self.new_object.get('wpa_encryption_mode') + if self.new_object.get('visible') is not None or self.new_object.get('visible') is not None: + new_object_params['visible'] = self.new_object.get('visible') + if self.new_object.get('dhcpEnforcedDeauthentication') is not None or self.new_object.get('dhcp_enforced_deauthentication') is not None: + new_object_params['dhcpEnforcedDeauthentication'] = self.new_object.get('dhcpEnforcedDeauthentication') or \ + self.new_object.get('dhcp_enforced_deauthentication') + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + if self.new_object.get('number') is not None or self.new_object.get('number') is not None: + new_object_params['number'] = self.new_object.get('number') or \ + self.new_object.get('number') + return new_object_params + + def get_object_by_name(self, name): + result = None + # NOTE: Does not have a get by name method, using get all + try: + items = self.meraki.exec_meraki( + family="appliance", + function="getNetworkApplianceSsids", + params=self.get_all_params(name=name), + ) + if isinstance(items, dict): + if 'response' in items: + items = items.get('response') + result = get_dict_result(items, 'name', name) + if result is None: + result = items + except Exception as e: + print("Error: ", e) + result = None + return result + + def get_object_by_id(self, id): + result = None + try: + items = self.meraki.exec_meraki( + family="appliance", + function="getNetworkApplianceSsid", + params=self.get_params_by_id() + ) + if isinstance(items, dict): + if 'response' in items: + items = items.get('response') + result = items + except Exception as e: + print("Error: ", e) + result = None + return result + + def exists(self): + prev_obj = None + id_exists = False + name_exists = False + o_id = self.new_object.get("networkId") or self.new_object.get("network_id") + o_id = o_id or self.new_object.get( + "number") or self.new_object.get("number") + name = self.new_object.get("name") + if o_id: + prev_obj = self.get_object_by_id(o_id) + id_exists = prev_obj is not None and isinstance(prev_obj, dict) + if not id_exists and name: + prev_obj = self.get_object_by_name(name) + name_exists = prev_obj is not None and isinstance(prev_obj, dict) + if name_exists: + _id = prev_obj.get("id") + _id = _id or prev_obj.get("number") + if id_exists and name_exists and o_id != _id: + raise InconsistentParameters( + "The 'id' and 'name' params don't refer to the same object") + if _id: + self.new_object.update(dict(id=_id)) + self.new_object.update(dict(number=_id)) + if _id: + prev_obj = self.get_object_by_id(_id) + it_exists = prev_obj is not None and isinstance(prev_obj, dict) + return (it_exists, prev_obj) + + def requires_update(self, current_obj): + requested_obj = self.new_object + + obj_params = [ + ("name", "name"), + ("enabled", "enabled"), + ("defaultVlanId", "defaultVlanId"), + ("authMode", "authMode"), + ("psk", "psk"), + ("radiusServers", "radiusServers"), + ("encryptionMode", "encryptionMode"), + ("wpaEncryptionMode", "wpaEncryptionMode"), + ("visible", "visible"), + ("dhcpEnforcedDeauthentication", "dhcpEnforcedDeauthentication"), + ("networkId", "networkId"), + ("number", "number"), + ] + # Method 1. Params present in request (Ansible) obj are the same as the current (ISE) params + # If any does not have eq params, it requires update + return any(not meraki_compare_equality(current_obj.get(meraki_param), + requested_obj.get(ansible_param)) + for (meraki_param, ansible_param) in obj_params) + + def update(self): + id = self.new_object.get("id") + id = id or self.new_object.get("number") + name = self.new_object.get("name") + result = None + if not id: + prev_obj_name = self.get_object_by_name(name) + id_ = None + if prev_obj_name: + id_ = prev_obj_name.get("id") + id_ = id_ or prev_obj_name.get("number") + if id_: + self.new_object.update(dict(number=id_)) + result = self.meraki.exec_meraki( + family="appliance", + function="updateNetworkApplianceSsid", + params=self.update_by_id_params(), + op_modifies=True, + ) + return result + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = False + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + meraki = MERAKI(self._task.args) + obj = NetworksApplianceSsids(self._task.args, meraki) + + state = self._task.args.get("state") + + response = None + if state == "present": + (obj_exists, prev_obj) = obj.exists() + if obj_exists: + if obj.requires_update(prev_obj): + response = obj.update() + meraki.object_updated() + else: + response = prev_obj + meraki.object_already_present() + else: + meraki.fail_json( + "Object does not exists, plugin only has update") + + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_appliance_ssids_info.py b/ansible_collections/cisco/meraki/plugins/action/networks_appliance_ssids_info.py new file mode 100644 index 000000000..800326d8d --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_appliance_ssids_info.py @@ -0,0 +1,112 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + networkId=dict(type="str"), + number=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_object(self, params): + new_object = {} + if params.get("networkId") is not None: + new_object["networkId"] = params.get( + "networkId") + if params.get("number") is not None: + new_object["number"] = params.get( + "number") + return new_object + + def get_all(self, params): + new_object = {} + if params.get("networkId") is not None: + new_object["networkId"] = params.get( + "networkId") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + id = self._task.args.get("number") + if id: + response = meraki.exec_meraki( + family="appliance", + function='getNetworkApplianceSsid', + params=self.get_object(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result + if not id: + response = meraki.exec_meraki( + family="appliance", + function='getNetworkApplianceSsids', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_appliance_static_routes.py b/ansible_collections/cisco/meraki/plugins/action/networks_appliance_static_routes.py new file mode 100644 index 000000000..a14a6d646 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_appliance_static_routes.py @@ -0,0 +1,345 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or +# https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, + meraki_compare_equality, + get_dict_result, +) +from ansible_collections.cisco.meraki.plugins.plugin_utils.exceptions import ( + InconsistentParameters, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + state=dict(type="str", default="present", choices=["present", "absent"]), + name=dict(type="str"), + subnet=dict(type="str"), + gatewayIp=dict(type="str"), + gatewayVlanId=dict(type="str"), + networkId=dict(type="str"), + staticRouteId=dict(type="str"), + enabled=dict(type="bool"), + fixedIpAssignments=dict(type="dict"), + reservedIpRanges=dict(type="list"), +)) + +required_if = [ + ("state", "present", ["name", "networkId", "staticRouteId"], True), + ("state", "absent", ["name", "networkId", "staticRouteId"], True), +] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class NetworksApplianceStaticRoutes(object): + def __init__(self, params, meraki): + self.meraki = meraki + self.new_object = dict( + name=params.get("name"), + subnet=params.get("subnet"), + gatewayIp=params.get("gatewayIp"), + gatewayVlanId=params.get("gatewayVlanId"), + networkId=params.get("networkId"), + staticRouteId=params.get("staticRouteId"), + enabled=params.get("enabled"), + fixedIpAssignments=params.get("fixedIpAssignments"), + reservedIpRanges=params.get("reservedIpRanges"), + ) + + def get_all_params(self, name=None, id=None): + new_object_params = {} + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + return new_object_params + + def get_params_by_id(self, name=None, id=None): + new_object_params = {} + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + if self.new_object.get('staticRouteId') is not None or self.new_object.get('static_route_id') is not None: + new_object_params['staticRouteId'] = self.new_object.get('staticRouteId') or \ + self.new_object.get('static_route_id') + return new_object_params + + def create_params(self): + new_object_params = {} + if self.new_object.get('name') is not None or self.new_object.get('name') is not None: + new_object_params['name'] = self.new_object.get('name') or \ + self.new_object.get('name') + if self.new_object.get('subnet') is not None or self.new_object.get('subnet') is not None: + new_object_params['subnet'] = self.new_object.get('subnet') or \ + self.new_object.get('subnet') + if self.new_object.get('gatewayIp') is not None or self.new_object.get('gateway_ip') is not None: + new_object_params['gatewayIp'] = self.new_object.get('gatewayIp') or \ + self.new_object.get('gateway_ip') + if self.new_object.get('gatewayVlanId') is not None or self.new_object.get('gateway_vlan_id') is not None: + new_object_params['gatewayVlanId'] = self.new_object.get('gatewayVlanId') or \ + self.new_object.get('gateway_vlan_id') + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + return new_object_params + + def delete_by_id_params(self): + new_object_params = {} + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + if self.new_object.get('staticRouteId') is not None or self.new_object.get('static_route_id') is not None: + new_object_params['staticRouteId'] = self.new_object.get('staticRouteId') or \ + self.new_object.get('static_route_id') + return new_object_params + + def update_by_id_params(self): + new_object_params = {} + if self.new_object.get('name') is not None or self.new_object.get('name') is not None: + new_object_params['name'] = self.new_object.get('name') or \ + self.new_object.get('name') + if self.new_object.get('subnet') is not None or self.new_object.get('subnet') is not None: + new_object_params['subnet'] = self.new_object.get('subnet') or \ + self.new_object.get('subnet') + if self.new_object.get('gatewayIp') is not None or self.new_object.get('gateway_ip') is not None: + new_object_params['gatewayIp'] = self.new_object.get('gatewayIp') or \ + self.new_object.get('gateway_ip') + if self.new_object.get('gatewayVlanId') is not None or self.new_object.get('gateway_vlan_id') is not None: + new_object_params['gatewayVlanId'] = self.new_object.get('gatewayVlanId') or \ + self.new_object.get('gateway_vlan_id') + if self.new_object.get('enabled') is not None or self.new_object.get('enabled') is not None: + new_object_params['enabled'] = self.new_object.get('enabled') + if self.new_object.get('fixedIpAssignments') is not None or self.new_object.get('fixed_ip_assignments') is not None: + new_object_params['fixedIpAssignments'] = self.new_object.get('fixedIpAssignments') or \ + self.new_object.get('fixed_ip_assignments') + if self.new_object.get('reservedIpRanges') is not None or self.new_object.get('reserved_ip_ranges') is not None: + new_object_params['reservedIpRanges'] = self.new_object.get('reservedIpRanges') or \ + self.new_object.get('reserved_ip_ranges') + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + if self.new_object.get('staticRouteId') is not None or self.new_object.get('static_route_id') is not None: + new_object_params['staticRouteId'] = self.new_object.get('staticRouteId') or \ + self.new_object.get('static_route_id') + return new_object_params + + def get_object_by_name(self, name): + result = None + # NOTE: Does not have a get by name method or it is in another action + try: + items = self.meraki.exec_meraki( + family="appliance", + function="getNetworkApplianceStaticRoutes", + params=self.get_all_params(name=name), + ) + if isinstance(items, dict): + if 'response' in items: + items = items.get('response') + result = get_dict_result(items, 'name', name) + if result is None: + result = items + except Exception as e: + print("Error: ", e) + result = None + return result + + def get_object_by_id(self, id): + result = None + try: + items = self.meraki.exec_meraki( + family="appliance", + function="getNetworkApplianceStaticRoute", + params=self.get_params_by_id() + ) + if isinstance(items, dict): + if 'response' in items: + items = items.get('response') + result = items + except Exception: + result = None + return result + + def exists(self): + id_exists = False + name_exists = False + prev_obj = None + o_id = self.new_object.get("id") + o_id = o_id or self.new_object.get( + "static_route_id") or self.new_object.get("staticRouteId") + name = self.new_object.get("name") + if o_id: + prev_obj = self.get_object_by_id(o_id) + id_exists = prev_obj is not None and isinstance(prev_obj, dict) + if not id_exists and name: + prev_obj = self.get_object_by_name(name) + name_exists = prev_obj is not None and isinstance(prev_obj, dict) + if name_exists: + _id = prev_obj.get("id") + _id = _id or prev_obj.get("staticRouteId") + if id_exists and name_exists and o_id != _id: + raise InconsistentParameters( + "The 'id' and 'name' params don't refer to the same object") + if _id: + self.new_object.update(dict(id=_id)) + self.new_object.update(dict(staticRouteId=_id)) + if _id: + prev_obj = self.get_object_by_id(_id) + it_exists = prev_obj is not None and isinstance(prev_obj, dict) + return (it_exists, prev_obj) + + def requires_update(self, current_obj): + requested_obj = self.new_object + + obj_params = [ + ("name", "name"), + ("subnet", "subnet"), + ("gatewayIp", "gatewayIp"), + ("gatewayVlanId", "gatewayVlanId"), + ("networkId", "networkId"), + ("staticRouteId", "staticRouteId"), + ("enabled", "enabled"), + ("fixedIpAssignments", "fixedIpAssignments"), + ("reservedIpRanges", "reservedIpRanges"), + ] + # Method 1. Params present in request (Ansible) obj are the same as the current (DNAC) params + # If any does not have eq params, it requires update + return any(not meraki_compare_equality(current_obj.get(meraki_param), + requested_obj.get(ansible_param)) + for (meraki_param, ansible_param) in obj_params) + + def create(self): + result = self.meraki.exec_meraki( + family="appliance", + function="createNetworkApplianceStaticRoute", + params=self.create_params(), + op_modifies=True, + ) + return result + + def update(self): + id = self.new_object.get("id") + id = id or self.new_object.get("staticRouteId") + name = self.new_object.get("name") + result = None + if not id: + prev_obj_name = self.get_object_by_name(name) + id_ = None + if prev_obj_name: + id_ = prev_obj_name.get("id") + id_ = id_ or prev_obj_name.get("staticRouteId") + if id_: + self.new_object.update(dict(staticRouteId=id_)) + result = self.meraki.exec_meraki( + family="appliance", + function="updateNetworkApplianceStaticRoute", + params=self.update_by_id_params(), + op_modifies=True, + ) + return result + + def delete(self): + id = self.new_object.get("id") + id = id or self.new_object.get("staticRouteId") + name = self.new_object.get("name") + result = None + if not id: + prev_obj_name = self.get_object_by_name(name) + id_ = None + if prev_obj_name: + id_ = prev_obj_name.get("id") + id_ = id_ or prev_obj_name.get("staticRouteId") + if id_: + self.new_object.update(dict(staticRouteId=id_)) + result = self.meraki.exec_meraki( + family="appliance", + function="deleteNetworkApplianceStaticRoute", + params=self.delete_by_id_params(), + ) + return result + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = False + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + meraki = MERAKI(self._task.args) + obj = NetworksApplianceStaticRoutes(self._task.args, meraki) + + state = self._task.args.get("state") + + response = None + + if state == "present": + (obj_exists, prev_obj) = obj.exists() + if obj_exists: + if obj.requires_update(prev_obj): + response = obj.update() + meraki.object_updated() + else: + response = prev_obj + meraki.object_already_present() + else: + response = obj.create() + meraki.object_created() + + elif state == "absent": + (obj_exists, prev_obj) = obj.exists() + if obj_exists: + response = obj.delete() + meraki.object_deleted() + else: + meraki.object_already_absent() + + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_appliance_static_routes_info.py b/ansible_collections/cisco/meraki/plugins/action/networks_appliance_static_routes_info.py new file mode 100644 index 000000000..53b1d274c --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_appliance_static_routes_info.py @@ -0,0 +1,112 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + networkId=dict(type="str"), + staticRouteId=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_object(self, params): + new_object = {} + if params.get("networkId") is not None: + new_object["networkId"] = params.get( + "networkId") + if params.get("staticRouteId") is not None: + new_object["staticRouteId"] = params.get( + "staticRouteId") + return new_object + + def get_all(self, params): + new_object = {} + if params.get("networkId") is not None: + new_object["networkId"] = params.get( + "networkId") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + id = self._task.args.get("staticRouteId") + if id: + response = meraki.exec_meraki( + family="appliance", + function='getNetworkApplianceStaticRoute', + params=self.get_object(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result + if not id: + response = meraki.exec_meraki( + family="appliance", + function='getNetworkApplianceStaticRoutes', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_appliance_traffic_shaping.py b/ansible_collections/cisco/meraki/plugins/action/networks_appliance_traffic_shaping.py new file mode 100644 index 000000000..49390ff03 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_appliance_traffic_shaping.py @@ -0,0 +1,200 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or +# https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, + meraki_compare_equality, + get_dict_result, +) +from ansible_collections.cisco.meraki.plugins.plugin_utils.exceptions import ( + InconsistentParameters, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + state=dict(type="str", default="present", choices=["present"]), + globalBandwidthLimits=dict(type="dict"), + networkId=dict(type="str"), +)) + +required_if = [ + ("state", "present", ["networkId"], True), +] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class NetworksApplianceTrafficShaping(object): + def __init__(self, params, meraki): + self.meraki = meraki + self.new_object = dict( + globalBandwidthLimits=params.get("globalBandwidthLimits"), + network_id=params.get("networkId"), + ) + + def get_all_params(self, name=None, id=None): + new_object_params = {} + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + return new_object_params + + def update_all_params(self): + new_object_params = {} + if self.new_object.get('globalBandwidthLimits') is not None or self.new_object.get('global_bandwidth_limits') is not None: + new_object_params['globalBandwidthLimits'] = self.new_object.get('globalBandwidthLimits') or \ + self.new_object.get('global_bandwidth_limits') + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + return new_object_params + + def get_object_by_name(self, name): + result = None + # NOTE: Does not have a get by name method, using get all + try: + items = self.meraki.exec_meraki( + family="appliance", + function="getNetworkApplianceTrafficShaping", + params=self.get_all_params(name=name), + ) + if isinstance(items, dict): + if 'response' in items: + items = items.get('response') + result = get_dict_result(items, 'name', name) + if result is None: + result = items + except Exception as e: + print("Error: ", e) + result = None + return result + + def get_object_by_id(self, id): + result = None + # NOTE: Does not have a get by id method or it is in another action + return result + + def exists(self): + prev_obj = None + id_exists = False + name_exists = False + o_id = self.new_object.get("networkId") or self.new_object.get("network_id") + name = self.new_object.get("name") + if o_id: + prev_obj = self.get_object_by_name(o_id) + id_exists = prev_obj is not None and isinstance(prev_obj, dict) + if not id_exists and name: + prev_obj = self.get_object_by_name(name) + name_exists = prev_obj is not None and isinstance(prev_obj, dict) + if name_exists: + _id = prev_obj.get("id") + if id_exists and name_exists and o_id != _id: + raise InconsistentParameters( + "The 'id' and 'name' params don't refer to the same object") + if _id: + self.new_object.update(dict(id=_id)) + it_exists = prev_obj is not None and isinstance(prev_obj, dict) + return (it_exists, prev_obj) + + def requires_update(self, current_obj): + requested_obj = self.new_object + + obj_params = [ + ("globalBandwidthLimits", "globalBandwidthLimits"), + ("networkId", "networkId"), + ] + # Method 1. Params present in request (Ansible) obj are the same as the current (ISE) params + # If any does not have eq params, it requires update + return any(not meraki_compare_equality(current_obj.get(meraki_param), + requested_obj.get(ansible_param)) + for (meraki_param, ansible_param) in obj_params) + + def update(self): + id = self.new_object.get("id") + name = self.new_object.get("name") + result = None + result = self.meraki.exec_meraki( + family="appliance", + function="updateNetworkApplianceTrafficShaping", + params=self.update_all_params(), + op_modifies=True, + ) + return result + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = False + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + meraki = MERAKI(self._task.args) + obj = NetworksApplianceTrafficShaping(self._task.args, meraki) + + state = self._task.args.get("state") + + response = None + if state == "present": + (obj_exists, prev_obj) = obj.exists() + if obj_exists: + if obj.requires_update(prev_obj): + response = obj.update() + meraki.object_updated() + else: + response = prev_obj + meraki.object_already_present() + else: + meraki.fail_json( + "Object does not exists, plugin only has update") + + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_appliance_traffic_shaping_custom_performance_classes.py b/ansible_collections/cisco/meraki/plugins/action/networks_appliance_traffic_shaping_custom_performance_classes.py new file mode 100644 index 000000000..4331bc9b2 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_appliance_traffic_shaping_custom_performance_classes.py @@ -0,0 +1,95 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguements specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + name=dict(type="str"), + maxLatency=dict(type="int"), + maxJitter=dict(type="int"), + maxLossPercentage=dict(type="int"), + networkId=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = False + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_object(self, params): + new_object = dict( + name=params.get("name"), + maxLatency=params.get("maxLatency"), + maxJitter=params.get("maxJitter"), + maxLossPercentage=params.get("maxLossPercentage"), + networkId=params.get("networkId"), + ) + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="appliance", + function='createNetworkApplianceTrafficShapingCustomPerformanceClass', + op_modifies=True, + params=self.get_object(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_appliance_traffic_shaping_info.py b/ansible_collections/cisco/meraki/plugins/action/networks_appliance_traffic_shaping_info.py new file mode 100644 index 000000000..dab14799b --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_appliance_traffic_shaping_info.py @@ -0,0 +1,90 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + networkId=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_all(self, params): + new_object = {} + if params.get("networkId") is not None: + new_object["networkId"] = params.get( + "networkId") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="appliance", + function='getNetworkApplianceTrafficShaping', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_appliance_traffic_shaping_rules.py b/ansible_collections/cisco/meraki/plugins/action/networks_appliance_traffic_shaping_rules.py new file mode 100644 index 000000000..db0abee6d --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_appliance_traffic_shaping_rules.py @@ -0,0 +1,205 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or +# https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, + meraki_compare_equality, + get_dict_result, +) +from ansible_collections.cisco.meraki.plugins.plugin_utils.exceptions import ( + InconsistentParameters, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + state=dict(type="str", default="present", choices=["present"]), + defaultRulesEnabled=dict(type="bool"), + rules=dict(type="list"), + networkId=dict(type="str"), +)) + +required_if = [ + ("state", "present", ["networkId"], True), +] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class NetworksApplianceTrafficShapingRules(object): + def __init__(self, params, meraki): + self.meraki = meraki + self.new_object = dict( + defaultRulesEnabled=params.get("defaultRulesEnabled"), + rules=params.get("rules"), + network_id=params.get("networkId"), + ) + + def get_all_params(self, name=None, id=None): + new_object_params = {} + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + return new_object_params + + def update_all_params(self): + new_object_params = {} + if self.new_object.get('defaultRulesEnabled') is not None or self.new_object.get('default_rules_enabled') is not None: + new_object_params['defaultRulesEnabled'] = self.new_object.get('defaultRulesEnabled') + if self.new_object.get('rules') is not None or self.new_object.get('rules') is not None: + new_object_params['rules'] = self.new_object.get('rules') or \ + self.new_object.get('rules') + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + return new_object_params + + def get_object_by_name(self, name): + result = None + # NOTE: Does not have a get by name method, using get all + try: + items = self.meraki.exec_meraki( + family="appliance", + function="getNetworkApplianceTrafficShapingRules", + params=self.get_all_params(name=name), + ) + if isinstance(items, dict): + if 'response' in items: + items = items.get('response') + result = get_dict_result(items, 'name', name) + if result is None: + result = items + except Exception as e: + print("Error: ", e) + result = None + return result + + def get_object_by_id(self, id): + result = None + # NOTE: Does not have a get by id method or it is in another action + return result + + def exists(self): + prev_obj = None + id_exists = False + name_exists = False + o_id = self.new_object.get("networkId") or self.new_object.get("network_id") + name = self.new_object.get("name") + if o_id: + prev_obj = self.get_object_by_name(o_id) + id_exists = prev_obj is not None and isinstance(prev_obj, dict) + if not id_exists and name: + prev_obj = self.get_object_by_name(name) + name_exists = prev_obj is not None and isinstance(prev_obj, dict) + if name_exists: + _id = prev_obj.get("id") + if id_exists and name_exists and o_id != _id: + raise InconsistentParameters( + "The 'id' and 'name' params don't refer to the same object") + if _id: + self.new_object.update(dict(id=_id)) + it_exists = prev_obj is not None and isinstance(prev_obj, dict) + return (it_exists, prev_obj) + + def requires_update(self, current_obj): + requested_obj = self.new_object + + obj_params = [ + ("defaultRulesEnabled", "defaultRulesEnabled"), + ("rules", "rules"), + ("networkId", "networkId"), + ] + # Method 1. Params present in request (Ansible) obj are the same as the current (ISE) params + # If any does not have eq params, it requires update + return any(not meraki_compare_equality(current_obj.get(meraki_param), + requested_obj.get(ansible_param)) + for (meraki_param, ansible_param) in obj_params) + + def update(self): + id = self.new_object.get("id") + name = self.new_object.get("name") + result = None + result = self.meraki.exec_meraki( + family="appliance", + function="updateNetworkApplianceTrafficShapingRules", + params=self.update_all_params(), + op_modifies=True, + ) + return result + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = False + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + meraki = MERAKI(self._task.args) + obj = NetworksApplianceTrafficShapingRules(self._task.args, meraki) + + state = self._task.args.get("state") + + response = None + if state == "present": + (obj_exists, prev_obj) = obj.exists() + if obj_exists: + if obj.requires_update(prev_obj): + response = obj.update() + meraki.object_updated() + else: + response = prev_obj + meraki.object_already_present() + else: + meraki.fail_json( + "Object does not exists, plugin only has update") + + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_appliance_traffic_shaping_rules_info.py b/ansible_collections/cisco/meraki/plugins/action/networks_appliance_traffic_shaping_rules_info.py new file mode 100644 index 000000000..6e0c7b048 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_appliance_traffic_shaping_rules_info.py @@ -0,0 +1,90 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + networkId=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_all(self, params): + new_object = {} + if params.get("networkId") is not None: + new_object["networkId"] = params.get( + "networkId") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="appliance", + function='getNetworkApplianceTrafficShapingRules', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_appliance_traffic_shaping_uplink_bandwidth.py b/ansible_collections/cisco/meraki/plugins/action/networks_appliance_traffic_shaping_uplink_bandwidth.py new file mode 100644 index 000000000..f6700b1e4 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_appliance_traffic_shaping_uplink_bandwidth.py @@ -0,0 +1,200 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or +# https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, + meraki_compare_equality, + get_dict_result, +) +from ansible_collections.cisco.meraki.plugins.plugin_utils.exceptions import ( + InconsistentParameters, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + state=dict(type="str", default="present", choices=["present"]), + bandwidthLimits=dict(type="dict"), + networkId=dict(type="str"), +)) + +required_if = [ + ("state", "present", ["networkId"], True), +] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class NetworksApplianceTrafficShapingUplinkBandwidth(object): + def __init__(self, params, meraki): + self.meraki = meraki + self.new_object = dict( + bandwidthLimits=params.get("bandwidthLimits"), + network_id=params.get("networkId"), + ) + + def get_all_params(self, name=None, id=None): + new_object_params = {} + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + return new_object_params + + def update_all_params(self): + new_object_params = {} + if self.new_object.get('bandwidthLimits') is not None or self.new_object.get('bandwidth_limits') is not None: + new_object_params['bandwidthLimits'] = self.new_object.get('bandwidthLimits') or \ + self.new_object.get('bandwidth_limits') + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + return new_object_params + + def get_object_by_name(self, name): + result = None + # NOTE: Does not have a get by name method, using get all + try: + items = self.meraki.exec_meraki( + family="appliance", + function="getNetworkApplianceTrafficShapingUplinkBandwidth", + params=self.get_all_params(name=name), + ) + if isinstance(items, dict): + if 'bandwidthLimits' in items: + items = items.get('bandwidthLimits') + result = get_dict_result(items, 'name', name) + if result is None: + result = items + except Exception as e: + print("Error: ", e) + result = None + return result + + def get_object_by_id(self, id): + result = None + # NOTE: Does not have a get by id method or it is in another action + return result + + def exists(self): + prev_obj = None + id_exists = False + name_exists = False + o_id = self.new_object.get("networkId") or self.new_object.get("network_id") + name = self.new_object.get("name") + if o_id: + prev_obj = self.get_object_by_name(o_id) + id_exists = prev_obj is not None and isinstance(prev_obj, dict) + if not id_exists and name: + prev_obj = self.get_object_by_name(name) + name_exists = prev_obj is not None and isinstance(prev_obj, dict) + if name_exists: + _id = prev_obj.get("id") + if id_exists and name_exists and o_id != _id: + raise InconsistentParameters( + "The 'id' and 'name' params don't refer to the same object") + if _id: + self.new_object.update(dict(id=_id)) + it_exists = prev_obj is not None and isinstance(prev_obj, dict) + return (it_exists, prev_obj) + + def requires_update(self, current_obj): + requested_obj = self.new_object + + obj_params = [ + ("bandwidthLimits", "bandwidthLimits"), + ("networkId", "networkId"), + ] + # Method 1. Params present in request (Ansible) obj are the same as the current (ISE) params + # If any does not have eq params, it requires update + return any(not meraki_compare_equality(current_obj.get(meraki_param), + requested_obj.get(ansible_param)) + for (meraki_param, ansible_param) in obj_params) + + def update(self): + id = self.new_object.get("id") + name = self.new_object.get("name") + result = None + result = self.meraki.exec_meraki( + family="appliance", + function="updateNetworkApplianceTrafficShapingUplinkBandwidth", + params=self.update_all_params(), + op_modifies=True, + ) + return result + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = False + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + meraki = MERAKI(self._task.args) + obj = NetworksApplianceTrafficShapingUplinkBandwidth(self._task.args, meraki) + + state = self._task.args.get("state") + + response = None + if state == "present": + (obj_exists, prev_obj) = obj.exists() + if obj_exists: + if obj.requires_update(prev_obj): + response = obj.update() + meraki.object_updated() + else: + response = prev_obj + meraki.object_already_present() + else: + meraki.fail_json( + "Object does not exists, plugin only has update") + + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_appliance_traffic_shaping_uplink_bandwidth_info.py b/ansible_collections/cisco/meraki/plugins/action/networks_appliance_traffic_shaping_uplink_bandwidth_info.py new file mode 100644 index 000000000..fc8283efa --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_appliance_traffic_shaping_uplink_bandwidth_info.py @@ -0,0 +1,90 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + networkId=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_all(self, params): + new_object = {} + if params.get("networkId") is not None: + new_object["networkId"] = params.get( + "networkId") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="appliance", + function='getNetworkApplianceTrafficShapingUplinkBandwidth', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_appliance_traffic_shaping_uplink_selection.py b/ansible_collections/cisco/meraki/plugins/action/networks_appliance_traffic_shaping_uplink_selection.py new file mode 100644 index 000000000..79b737a1e --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_appliance_traffic_shaping_uplink_selection.py @@ -0,0 +1,228 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or +# https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, + meraki_compare_equality, + get_dict_result, +) +from ansible_collections.cisco.meraki.plugins.plugin_utils.exceptions import ( + InconsistentParameters, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + state=dict(type="str", default="present", choices=["present"]), + activeActiveAutoVpnEnabled=dict(type="bool"), + defaultUplink=dict(type="str"), + loadBalancingEnabled=dict(type="bool"), + failoverAndFailback=dict(type="dict"), + wanTrafficUplinkPreferences=dict(type="list"), + vpnTrafficUplinkPreferences=dict(type="list"), + networkId=dict(type="str"), +)) + +required_if = [ + ("state", "present", ["networkId"], True), +] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class NetworksApplianceTrafficShapingUplinkSelection(object): + def __init__(self, params, meraki): + self.meraki = meraki + self.new_object = dict( + activeActiveAutoVpnEnabled=params.get("activeActiveAutoVpnEnabled"), + defaultUplink=params.get("defaultUplink"), + loadBalancingEnabled=params.get("loadBalancingEnabled"), + failoverAndFailback=params.get("failoverAndFailback"), + wanTrafficUplinkPreferences=params.get("wanTrafficUplinkPreferences"), + vpnTrafficUplinkPreferences=params.get("vpnTrafficUplinkPreferences"), + network_id=params.get("networkId"), + ) + + def get_all_params(self, name=None, id=None): + new_object_params = {} + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + return new_object_params + + def update_all_params(self): + new_object_params = {} + if self.new_object.get('activeActiveAutoVpnEnabled') is not None or self.new_object.get('active_active_auto_vpn_enabled') is not None: + new_object_params['activeActiveAutoVpnEnabled'] = self.new_object.get('activeActiveAutoVpnEnabled') + if self.new_object.get('defaultUplink') is not None or self.new_object.get('default_uplink') is not None: + new_object_params['defaultUplink'] = self.new_object.get('defaultUplink') or \ + self.new_object.get('default_uplink') + if self.new_object.get('loadBalancingEnabled') is not None or self.new_object.get('load_balancing_enabled') is not None: + new_object_params['loadBalancingEnabled'] = self.new_object.get('loadBalancingEnabled') + if self.new_object.get('failoverAndFailback') is not None or self.new_object.get('failover_and_failback') is not None: + new_object_params['failoverAndFailback'] = self.new_object.get('failoverAndFailback') or \ + self.new_object.get('failover_and_failback') + if self.new_object.get('wanTrafficUplinkPreferences') is not None or self.new_object.get('wan_traffic_uplink_preferences') is not None: + new_object_params['wanTrafficUplinkPreferences'] = self.new_object.get('wanTrafficUplinkPreferences') or \ + self.new_object.get('wan_traffic_uplink_preferences') + if self.new_object.get('vpnTrafficUplinkPreferences') is not None or self.new_object.get('vpn_traffic_uplink_preferences') is not None: + new_object_params['vpnTrafficUplinkPreferences'] = self.new_object.get('vpnTrafficUplinkPreferences') or \ + self.new_object.get('vpn_traffic_uplink_preferences') + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + return new_object_params + + def get_object_by_name(self, name): + result = None + # NOTE: Does not have a get by name method, using get all + try: + items = self.meraki.exec_meraki( + family="appliance", + function="getNetworkApplianceTrafficShapingUplinkSelection", + params=self.get_all_params(name=name), + ) + if isinstance(items, dict): + if 'response' in items: + items = items.get('response') + result = get_dict_result(items, 'name', name) + if result is None: + result = items + except Exception as e: + print("Error: ", e) + result = None + return result + + def get_object_by_id(self, id): + result = None + # NOTE: Does not have a get by id method or it is in another action + return result + + def exists(self): + prev_obj = None + id_exists = False + name_exists = False + o_id = self.new_object.get("networkId") or self.new_object.get("network_id") + name = self.new_object.get("name") + if o_id: + prev_obj = self.get_object_by_name(o_id) + id_exists = prev_obj is not None and isinstance(prev_obj, dict) + if not id_exists and name: + prev_obj = self.get_object_by_name(name) + name_exists = prev_obj is not None and isinstance(prev_obj, dict) + if name_exists: + _id = prev_obj.get("id") + if id_exists and name_exists and o_id != _id: + raise InconsistentParameters( + "The 'id' and 'name' params don't refer to the same object") + if _id: + self.new_object.update(dict(id=_id)) + it_exists = prev_obj is not None and isinstance(prev_obj, dict) + return (it_exists, prev_obj) + + def requires_update(self, current_obj): + requested_obj = self.new_object + + obj_params = [ + ("activeActiveAutoVpnEnabled", "activeActiveAutoVpnEnabled"), + ("defaultUplink", "defaultUplink"), + ("loadBalancingEnabled", "loadBalancingEnabled"), + ("failoverAndFailback", "failoverAndFailback"), + ("wanTrafficUplinkPreferences", "wanTrafficUplinkPreferences"), + ("vpnTrafficUplinkPreferences", "vpnTrafficUplinkPreferences"), + ("networkId", "networkId"), + ] + # Method 1. Params present in request (Ansible) obj are the same as the current (ISE) params + # If any does not have eq params, it requires update + return any(not meraki_compare_equality(current_obj.get(meraki_param), + requested_obj.get(ansible_param)) + for (meraki_param, ansible_param) in obj_params) + + def update(self): + id = self.new_object.get("id") + name = self.new_object.get("name") + result = None + result = self.meraki.exec_meraki( + family="appliance", + function="updateNetworkApplianceTrafficShapingUplinkSelection", + params=self.update_all_params(), + op_modifies=True, + ) + return result + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = False + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + meraki = MERAKI(self._task.args) + obj = NetworksApplianceTrafficShapingUplinkSelection(self._task.args, meraki) + + state = self._task.args.get("state") + + response = None + if state == "present": + (obj_exists, prev_obj) = obj.exists() + if obj_exists: + if obj.requires_update(prev_obj): + response = obj.update() + meraki.object_updated() + else: + response = prev_obj + meraki.object_already_present() + else: + meraki.fail_json( + "Object does not exists, plugin only has update") + + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_appliance_traffic_shaping_uplink_selection_info.py b/ansible_collections/cisco/meraki/plugins/action/networks_appliance_traffic_shaping_uplink_selection_info.py new file mode 100644 index 000000000..e3f53c24b --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_appliance_traffic_shaping_uplink_selection_info.py @@ -0,0 +1,90 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + networkId=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_all(self, params): + new_object = {} + if params.get("networkId") is not None: + new_object["networkId"] = params.get( + "networkId") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="appliance", + function='getNetworkApplianceTrafficShapingUplinkSelection', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_appliance_vlans.py b/ansible_collections/cisco/meraki/plugins/action/networks_appliance_vlans.py new file mode 100644 index 000000000..ba4835a9d --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_appliance_vlans.py @@ -0,0 +1,446 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or +# https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, + meraki_compare_equality, + get_dict_result, +) +from ansible_collections.cisco.meraki.plugins.plugin_utils.exceptions import ( + InconsistentParameters, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + state=dict(type="str", default="present", choices=["present", "absent"]), + id=dict(type="str"), + name=dict(type="str"), + subnet=dict(type="str"), + applianceIp=dict(type="str"), + groupPolicyId=dict(type="str"), + templateVlanType=dict(type="str"), + cidr=dict(type="str"), + mask=dict(type="int"), + ipv6=dict(type="dict"), + mandatoryDhcp=dict(type="dict"), + networkId=dict(type="str"), + vlanId=dict(type="str"), + vpnNatSubnet=dict(type="str"), + dhcpHandling=dict(type="str"), + dhcpRelayServerIps=dict(type="list"), + dhcpLeaseTime=dict(type="str"), + dhcpBootOptionsEnabled=dict(type="bool"), + dhcpBootNextServer=dict(type="str"), + dhcpBootFilename=dict(type="str"), + fixedIpAssignments=dict(type="dict"), + reservedIpRanges=dict(type="list"), + dnsNameservers=dict(type="str"), + dhcpOptions=dict(type="list"), +)) + +required_if = [ + ("state", "present", ["name", "networkId", "vlanId"], True), + ("state", "absent", ["name", "networkId", "vlanId"], True), +] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class NetworksApplianceVlans(object): + def __init__(self, params, meraki): + self.meraki = meraki + self.new_object = dict( + id=params.get("id"), + name=params.get("name"), + subnet=params.get("subnet"), + applianceIp=params.get("applianceIp"), + groupPolicyId=params.get("groupPolicyId"), + templateVlanType=params.get("templateVlanType"), + cidr=params.get("cidr"), + mask=params.get("mask"), + ipv6=params.get("ipv6"), + mandatoryDhcp=params.get("mandatoryDhcp"), + networkId=params.get("networkId"), + vlanId=params.get("vlanId"), + vpnNatSubnet=params.get("vpnNatSubnet"), + dhcpHandling=params.get("dhcpHandling"), + dhcpRelayServerIps=params.get("dhcpRelayServerIps"), + dhcpLeaseTime=params.get("dhcpLeaseTime"), + dhcpBootOptionsEnabled=params.get("dhcpBootOptionsEnabled"), + dhcpBootNextServer=params.get("dhcpBootNextServer"), + dhcpBootFilename=params.get("dhcpBootFilename"), + fixedIpAssignments=params.get("fixedIpAssignments"), + reservedIpRanges=params.get("reservedIpRanges"), + dnsNameservers=params.get("dnsNameservers"), + dhcpOptions=params.get("dhcpOptions"), + ) + + def get_all_params(self, name=None, id=None): + new_object_params = {} + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + return new_object_params + + def get_params_by_id(self, name=None, id=None): + new_object_params = {} + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + if self.new_object.get('vlanId') is not None or self.new_object.get('vlan_id') is not None or self.new_object.get('id') is not None: + new_object_params['vlanId'] = self.new_object.get('vlanId') or \ + self.new_object.get('vlan_id') or self.new_object.get('id') + return new_object_params + + def create_params(self): + new_object_params = {} + if self.new_object.get('id') is not None or self.new_object.get('id') is not None: + new_object_params['id'] = self.new_object.get('id') or \ + self.new_object.get('id') + if self.new_object.get('name') is not None or self.new_object.get('name') is not None: + new_object_params['name'] = self.new_object.get('name') or \ + self.new_object.get('name') + if self.new_object.get('subnet') is not None or self.new_object.get('subnet') is not None: + new_object_params['subnet'] = self.new_object.get('subnet') or \ + self.new_object.get('subnet') + if self.new_object.get('applianceIp') is not None or self.new_object.get('appliance_ip') is not None: + new_object_params['applianceIp'] = self.new_object.get('applianceIp') or \ + self.new_object.get('appliance_ip') + if self.new_object.get('groupPolicyId') is not None or self.new_object.get('group_policy_id') is not None: + new_object_params['groupPolicyId'] = self.new_object.get('groupPolicyId') or \ + self.new_object.get('group_policy_id') + if self.new_object.get('templateVlanType') is not None or self.new_object.get('template_vlan_type') is not None: + new_object_params['templateVlanType'] = self.new_object.get('templateVlanType') or \ + self.new_object.get('template_vlan_type') + if self.new_object.get('cidr') is not None or self.new_object.get('cidr') is not None: + new_object_params['cidr'] = self.new_object.get('cidr') or \ + self.new_object.get('cidr') + if self.new_object.get('mask') is not None or self.new_object.get('mask') is not None: + new_object_params['mask'] = self.new_object.get('mask') or \ + self.new_object.get('mask') + if self.new_object.get('ipv6') is not None or self.new_object.get('ipv6') is not None: + new_object_params['ipv6'] = self.new_object.get('ipv6') or \ + self.new_object.get('ipv6') + if self.new_object.get('mandatoryDhcp') is not None or self.new_object.get('mandatory_dhcp') is not None: + new_object_params['mandatoryDhcp'] = self.new_object.get('mandatoryDhcp') or \ + self.new_object.get('mandatory_dhcp') + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + return new_object_params + + def delete_by_id_params(self): + new_object_params = {} + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + if self.new_object.get('vlanId') is not None or self.new_object.get('vlan_id') is not None is not None or self.new_object.get('id') is not None: + new_object_params['vlanId'] = self.new_object.get('vlanId') or \ + self.new_object.get('vlan_id') or self.new_object.get('id') + return new_object_params + + def update_by_id_params(self): + new_object_params = {} + if self.new_object.get('name') is not None or self.new_object.get('name') is not None: + new_object_params['name'] = self.new_object.get('name') or \ + self.new_object.get('name') + if self.new_object.get('subnet') is not None or self.new_object.get('subnet') is not None: + new_object_params['subnet'] = self.new_object.get('subnet') or \ + self.new_object.get('subnet') + if self.new_object.get('applianceIp') is not None or self.new_object.get('appliance_ip') is not None: + new_object_params['applianceIp'] = self.new_object.get('applianceIp') or \ + self.new_object.get('appliance_ip') + if self.new_object.get('groupPolicyId') is not None or self.new_object.get('group_policy_id') is not None: + new_object_params['groupPolicyId'] = self.new_object.get('groupPolicyId') or \ + self.new_object.get('group_policy_id') + if self.new_object.get('vpnNatSubnet') is not None or self.new_object.get('vpn_nat_subnet') is not None: + new_object_params['vpnNatSubnet'] = self.new_object.get('vpnNatSubnet') or \ + self.new_object.get('vpn_nat_subnet') + if self.new_object.get('dhcpHandling') is not None or self.new_object.get('dhcp_handling') is not None: + new_object_params['dhcpHandling'] = self.new_object.get('dhcpHandling') or \ + self.new_object.get('dhcp_handling') + if self.new_object.get('dhcpRelayServerIps') is not None or self.new_object.get('dhcp_relay_server_ips') is not None: + new_object_params['dhcpRelayServerIps'] = self.new_object.get('dhcpRelayServerIps') or \ + self.new_object.get('dhcp_relay_server_ips') + if self.new_object.get('dhcpLeaseTime') is not None or self.new_object.get('dhcp_lease_time') is not None: + new_object_params['dhcpLeaseTime'] = self.new_object.get('dhcpLeaseTime') or \ + self.new_object.get('dhcp_lease_time') + if self.new_object.get('dhcpBootOptionsEnabled') is not None or self.new_object.get('dhcp_boot_options_enabled') is not None: + new_object_params['dhcpBootOptionsEnabled'] = self.new_object.get( + 'dhcpBootOptionsEnabled') + if self.new_object.get('dhcpBootNextServer') is not None or self.new_object.get('dhcp_boot_next_server') is not None: + new_object_params['dhcpBootNextServer'] = self.new_object.get('dhcpBootNextServer') or \ + self.new_object.get('dhcp_boot_next_server') + if self.new_object.get('dhcpBootFilename') is not None or self.new_object.get('dhcp_boot_filename') is not None: + new_object_params['dhcpBootFilename'] = self.new_object.get('dhcpBootFilename') or \ + self.new_object.get('dhcp_boot_filename') + if self.new_object.get('fixedIpAssignments') is not None or self.new_object.get('fixed_ip_assignments') is not None: + new_object_params['fixedIpAssignments'] = self.new_object.get('fixedIpAssignments') or \ + self.new_object.get('fixed_ip_assignments') + if self.new_object.get('reservedIpRanges') is not None or self.new_object.get('reserved_ip_ranges') is not None: + new_object_params['reservedIpRanges'] = self.new_object.get('reservedIpRanges') or \ + self.new_object.get('reserved_ip_ranges') + if self.new_object.get('dnsNameservers') is not None or self.new_object.get('dns_nameservers') is not None: + new_object_params['dnsNameservers'] = self.new_object.get('dnsNameservers') or \ + self.new_object.get('dns_nameservers') + if self.new_object.get('dhcpOptions') is not None or self.new_object.get('dhcp_options') is not None: + new_object_params['dhcpOptions'] = self.new_object.get('dhcpOptions') or \ + self.new_object.get('dhcp_options') + if self.new_object.get('templateVlanType') is not None or self.new_object.get('template_vlan_type') is not None: + new_object_params['templateVlanType'] = self.new_object.get('templateVlanType') or \ + self.new_object.get('template_vlan_type') + if self.new_object.get('cidr') is not None or self.new_object.get('cidr') is not None: + new_object_params['cidr'] = self.new_object.get('cidr') or \ + self.new_object.get('cidr') + if self.new_object.get('mask') is not None or self.new_object.get('mask') is not None: + new_object_params['mask'] = self.new_object.get('mask') or \ + self.new_object.get('mask') + if self.new_object.get('ipv6') is not None or self.new_object.get('ipv6') is not None: + new_object_params['ipv6'] = self.new_object.get('ipv6') or \ + self.new_object.get('ipv6') + if self.new_object.get('mandatoryDhcp') is not None or self.new_object.get('mandatory_dhcp') is not None: + new_object_params['mandatoryDhcp'] = self.new_object.get('mandatoryDhcp') or \ + self.new_object.get('mandatory_dhcp') + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + if self.new_object.get('vlanId') is not None or self.new_object.get('vlan_id') is not None is not None or self.new_object.get('id') is not None: + new_object_params['vlanId'] = self.new_object.get('vlanId') or \ + self.new_object.get('vlan_id') or self.new_object.get('id') + return new_object_params + + def get_object_by_name(self, name): + result = None + # NOTE: Does not have a get by name method or it is in another action + try: + items = self.meraki.exec_meraki( + family="appliance", + function="getNetworkApplianceVlans", + params=self.get_all_params(name=name), + ) + if isinstance(items, dict): + if 'response' in items: + items = items.get('response') + result = get_dict_result(items, 'name', name) + if result is None: + result = items + except Exception as e: + print("Error: ", e) + result = None + return result + + def get_object_by_id(self, id): + result = None + try: + items = self.meraki.exec_meraki( + family="appliance", + function="getNetworkApplianceVlan", + params=self.get_params_by_id() + ) + if isinstance(items, dict): + if 'response' in items: + items = items.get('response') + result = get_dict_result(items, 'vlanId', id) + except Exception as e: + print("Error: ", e) + result = None + return result + + def exists(self): + id_exists = False + name_exists = False + prev_obj = None + o_id = self.new_object.get("id") + o_id = o_id or self.new_object.get( + "vlan_id") or self.new_object.get("vlanId") + name = self.new_object.get("name") + if o_id: + prev_obj = self.get_object_by_id(o_id) + id_exists = prev_obj is not None and isinstance(prev_obj, dict) + if not id_exists and name: + prev_obj = self.get_object_by_name(name) + name_exists = prev_obj is not None and isinstance(prev_obj, dict) + if name_exists: + _id = prev_obj.get("id") + _id = _id or prev_obj.get("vlanId") + if id_exists and name_exists and o_id != _id: + raise InconsistentParameters( + "The 'id' and 'name' params don't refer to the same object") + if _id: + self.new_object.update(dict(id=_id)) + self.new_object.update(dict(vlanId=_id)) + if _id: + prev_obj = self.get_object_by_id(_id) + it_exists = prev_obj is not None and isinstance(prev_obj, dict) + return (it_exists, prev_obj) + + def requires_update(self, current_obj): + requested_obj = self.new_object + + obj_params = [ + ("id", "id"), + ("name", "name"), + ("subnet", "subnet"), + ("applianceIp", "applianceIp"), + ("groupPolicyId", "groupPolicyId"), + ("templateVlanType", "templateVlanType"), + ("cidr", "cidr"), + ("mask", "mask"), + ("ipv6", "ipv6"), + ("mandatoryDhcp", "mandatoryDhcp"), + ("networkId", "networkId"), + ("vlanId", "vlanId"), + ("vpnNatSubnet", "vpnNatSubnet"), + ("dhcpHandling", "dhcpHandling"), + ("dhcpRelayServerIps", "dhcpRelayServerIps"), + ("dhcpLeaseTime", "dhcpLeaseTime"), + ("dhcpBootOptionsEnabled", "dhcpBootOptionsEnabled"), + ("dhcpBootNextServer", "dhcpBootNextServer"), + ("dhcpBootFilename", "dhcpBootFilename"), + ("fixedIpAssignments", "fixedIpAssignments"), + ("reservedIpRanges", "reservedIpRanges"), + ("dnsNameservers", "dnsNameservers"), + ("dhcpOptions", "dhcpOptions"), + ] + # Method 1. Params present in request (Ansible) obj are the same as the current (DNAC) params + # If any does not have eq params, it requires update + return any(not meraki_compare_equality(current_obj.get(meraki_param), + requested_obj.get(ansible_param)) + for (meraki_param, ansible_param) in obj_params) + + def create(self): + result = self.meraki.exec_meraki( + family="appliance", + function="createNetworkApplianceVlan", + params=self.create_params(), + op_modifies=True, + ) + return result + + def update(self): + id = self.new_object.get("id") + id = id or self.new_object.get("vlanId") + name = self.new_object.get("name") + result = None + if not id: + prev_obj_name = self.get_object_by_name(name) + id_ = None + if prev_obj_name: + id_ = prev_obj_name.get("id") + id_ = id_ or prev_obj_name.get("vlanId") + if id_: + self.new_object.update(dict(vlanId=id_)) + result = self.meraki.exec_meraki( + family="appliance", + function="updateNetworkApplianceVlan", + params=self.update_by_id_params(), + op_modifies=True, + ) + return result + + def delete(self): + id = self.new_object.get("id") + id = id or self.new_object.get("vlanId") + name = self.new_object.get("name") + result = None + if not id: + prev_obj_name = self.get_object_by_name(name) + id_ = None + if prev_obj_name: + id_ = prev_obj_name.get("id") + id_ = id_ or prev_obj_name.get("vlanId") + if id_: + self.new_object.update(dict(vlanId=id_)) + result = self.meraki.exec_meraki( + family="appliance", + function="deleteNetworkApplianceVlan", + params=self.delete_by_id_params(), + ) + return result + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = False + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + meraki = MERAKI(self._task.args) + obj = NetworksApplianceVlans(self._task.args, meraki) + + state = self._task.args.get("state") + + response = None + + if state == "present": + (obj_exists, prev_obj) = obj.exists() + if obj_exists: + if obj.requires_update(prev_obj): + response = obj.update() + meraki.object_updated() + else: + response = prev_obj + meraki.object_already_present() + else: + response = obj.create() + meraki.object_created() + + elif state == "absent": + (obj_exists, prev_obj) = obj.exists() + if obj_exists: + response = obj.delete() + meraki.object_deleted() + else: + meraki.object_already_absent() + + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_appliance_vlans_info.py b/ansible_collections/cisco/meraki/plugins/action/networks_appliance_vlans_info.py new file mode 100644 index 000000000..4ab0f3e15 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_appliance_vlans_info.py @@ -0,0 +1,112 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + networkId=dict(type="str"), + vlanId=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_object(self, params): + new_object = {} + if params.get("networkId") is not None: + new_object["networkId"] = params.get( + "networkId") + if params.get("vlanId") is not None: + new_object["vlanId"] = params.get( + "vlanId") + return new_object + + def get_all(self, params): + new_object = {} + if params.get("networkId") is not None: + new_object["networkId"] = params.get( + "networkId") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + id = self._task.args.get("vlanId") + if id: + response = meraki.exec_meraki( + family="appliance", + function='getNetworkApplianceVlan', + params=self.get_object(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result + if not id: + response = meraki.exec_meraki( + family="appliance", + function='getNetworkApplianceVlans', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_appliance_vlans_settings.py b/ansible_collections/cisco/meraki/plugins/action/networks_appliance_vlans_settings.py new file mode 100644 index 000000000..8ef703a65 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_appliance_vlans_settings.py @@ -0,0 +1,199 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or +# https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, + meraki_compare_equality, + get_dict_result, +) +from ansible_collections.cisco.meraki.plugins.plugin_utils.exceptions import ( + InconsistentParameters, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + state=dict(type="str", default="present", choices=["present"]), + vlansEnabled=dict(type="bool"), + networkId=dict(type="str"), +)) + +required_if = [ + ("state", "present", ["networkId"], True), +] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class NetworksApplianceVlansSettings(object): + def __init__(self, params, meraki): + self.meraki = meraki + self.new_object = dict( + vlansEnabled=params.get("vlansEnabled"), + network_id=params.get("networkId"), + ) + + def get_all_params(self, name=None, id=None): + new_object_params = {} + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + return new_object_params + + def update_all_params(self): + new_object_params = {} + if self.new_object.get('vlansEnabled') is not None or self.new_object.get('vlans_enabled') is not None: + new_object_params['vlansEnabled'] = self.new_object.get('vlansEnabled') + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + return new_object_params + + def get_object_by_name(self, name): + result = None + # NOTE: Does not have a get by name method, using get all + try: + items = self.meraki.exec_meraki( + family="appliance", + function="getNetworkApplianceVlansSettings", + params=self.get_all_params(name=name), + ) + if isinstance(items, dict): + if 'response' in items: + items = items.get('response') + result = get_dict_result(items, 'name', name) + if result is None: + result = items + except Exception as e: + print("Error: ", e) + result = None + return result + + def get_object_by_id(self, id): + result = None + # NOTE: Does not have a get by id method or it is in another action + return result + + def exists(self): + prev_obj = None + id_exists = False + name_exists = False + o_id = self.new_object.get("networkId") or self.new_object.get("network_id") + name = self.new_object.get("name") + if o_id: + prev_obj = self.get_object_by_name(o_id) + id_exists = prev_obj is not None and isinstance(prev_obj, dict) + if not id_exists and name: + prev_obj = self.get_object_by_name(name) + name_exists = prev_obj is not None and isinstance(prev_obj, dict) + if name_exists: + _id = prev_obj.get("id") + if id_exists and name_exists and o_id != _id: + raise InconsistentParameters( + "The 'id' and 'name' params don't refer to the same object") + if _id: + self.new_object.update(dict(id=_id)) + it_exists = prev_obj is not None and isinstance(prev_obj, dict) + return (it_exists, prev_obj) + + def requires_update(self, current_obj): + requested_obj = self.new_object + + obj_params = [ + ("vlansEnabled", "vlansEnabled"), + ("networkId", "networkId"), + ] + # Method 1. Params present in request (Ansible) obj are the same as the current (ISE) params + # If any does not have eq params, it requires update + return any(not meraki_compare_equality(current_obj.get(meraki_param), + requested_obj.get(ansible_param)) + for (meraki_param, ansible_param) in obj_params) + + def update(self): + id = self.new_object.get("id") + name = self.new_object.get("name") + result = None + result = self.meraki.exec_meraki( + family="appliance", + function="updateNetworkApplianceVlansSettings", + params=self.update_all_params(), + op_modifies=True, + ) + return result + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = False + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + meraki = MERAKI(self._task.args) + obj = NetworksApplianceVlansSettings(self._task.args, meraki) + + state = self._task.args.get("state") + + response = None + if state == "present": + (obj_exists, prev_obj) = obj.exists() + if obj_exists: + if obj.requires_update(prev_obj): + response = obj.update() + meraki.object_updated() + else: + response = prev_obj + meraki.object_already_present() + else: + meraki.fail_json( + "Object does not exists, plugin only has update") + + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_appliance_vlans_settings_info.py b/ansible_collections/cisco/meraki/plugins/action/networks_appliance_vlans_settings_info.py new file mode 100644 index 000000000..edd0265c9 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_appliance_vlans_settings_info.py @@ -0,0 +1,90 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + networkId=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_all(self, params): + new_object = {} + if params.get("networkId") is not None: + new_object["networkId"] = params.get( + "networkId") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="appliance", + function='getNetworkApplianceVlansSettings', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_appliance_vpn_bgp.py b/ansible_collections/cisco/meraki/plugins/action/networks_appliance_vpn_bgp.py new file mode 100644 index 000000000..e3eba8000 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_appliance_vpn_bgp.py @@ -0,0 +1,217 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or +# https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, + meraki_compare_equality, + get_dict_result, +) +from ansible_collections.cisco.meraki.plugins.plugin_utils.exceptions import ( + InconsistentParameters, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + state=dict(type="str", default="present", choices=["present"]), + enabled=dict(type="bool"), + asNumber=dict(type="int"), + ibgpHoldTimer=dict(type="int"), + neighbors=dict(type="list"), + networkId=dict(type="str"), +)) + +required_if = [ + ("state", "present", ["networkId"], True), +] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class NetworksApplianceVpnBgp(object): + def __init__(self, params, meraki): + self.meraki = meraki + self.new_object = dict( + enabled=params.get("enabled"), + asNumber=params.get("asNumber"), + ibgpHoldTimer=params.get("ibgpHoldTimer"), + neighbors=params.get("neighbors"), + network_id=params.get("networkId"), + ) + + def get_all_params(self, name=None, id=None): + new_object_params = {} + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + return new_object_params + + def update_all_params(self): + new_object_params = {} + if self.new_object.get('enabled') is not None or self.new_object.get('enabled') is not None: + new_object_params['enabled'] = self.new_object.get('enabled') + if self.new_object.get('asNumber') is not None or self.new_object.get('as_number') is not None: + new_object_params['asNumber'] = self.new_object.get('asNumber') or \ + self.new_object.get('as_number') + if self.new_object.get('ibgpHoldTimer') is not None or self.new_object.get('ibgp_hold_timer') is not None: + new_object_params['ibgpHoldTimer'] = self.new_object.get('ibgpHoldTimer') or \ + self.new_object.get('ibgp_hold_timer') + if self.new_object.get('neighbors') is not None or self.new_object.get('neighbors') is not None: + new_object_params['neighbors'] = self.new_object.get('neighbors') or \ + self.new_object.get('neighbors') + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + return new_object_params + + def get_object_by_name(self, name): + result = None + # NOTE: Does not have a get by name method, using get all + try: + items = self.meraki.exec_meraki( + family="appliance", + function="getNetworkApplianceVpnBgp", + params=self.get_all_params(name=name), + ) + if isinstance(items, dict): + if 'response' in items: + items = items.get('response') + result = get_dict_result(items, 'name', name) + if result is None: + result = items + except Exception as e: + print("Error: ", e) + result = None + return result + + def get_object_by_id(self, id): + result = None + # NOTE: Does not have a get by id method or it is in another action + return result + + def exists(self): + prev_obj = None + id_exists = False + name_exists = False + o_id = self.new_object.get("networkId") or self.new_object.get("network_id") + name = self.new_object.get("name") + if o_id: + prev_obj = self.get_object_by_name(o_id) + id_exists = prev_obj is not None and isinstance(prev_obj, dict) + if not id_exists and name: + prev_obj = self.get_object_by_name(name) + name_exists = prev_obj is not None and isinstance(prev_obj, dict) + if name_exists: + _id = prev_obj.get("id") + if id_exists and name_exists and o_id != _id: + raise InconsistentParameters( + "The 'id' and 'name' params don't refer to the same object") + if _id: + self.new_object.update(dict(id=_id)) + it_exists = prev_obj is not None and isinstance(prev_obj, dict) + return (it_exists, prev_obj) + + def requires_update(self, current_obj): + requested_obj = self.new_object + + obj_params = [ + ("enabled", "enabled"), + ("asNumber", "asNumber"), + ("ibgpHoldTimer", "ibgpHoldTimer"), + ("neighbors", "neighbors"), + ("networkId", "networkId"), + ] + # Method 1. Params present in request (Ansible) obj are the same as the current (ISE) params + # If any does not have eq params, it requires update + return any(not meraki_compare_equality(current_obj.get(meraki_param), + requested_obj.get(ansible_param)) + for (meraki_param, ansible_param) in obj_params) + + def update(self): + id = self.new_object.get("id") + name = self.new_object.get("name") + result = None + result = self.meraki.exec_meraki( + family="appliance", + function="updateNetworkApplianceVpnBgp", + params=self.update_all_params(), + op_modifies=True, + ) + return result + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = False + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + meraki = MERAKI(self._task.args) + obj = NetworksApplianceVpnBgp(self._task.args, meraki) + + state = self._task.args.get("state") + + response = None + if state == "present": + (obj_exists, prev_obj) = obj.exists() + if obj_exists: + if obj.requires_update(prev_obj): + response = obj.update() + meraki.object_updated() + else: + response = prev_obj + meraki.object_already_present() + else: + meraki.fail_json( + "Object does not exists, plugin only has update") + + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_appliance_vpn_bgp_info.py b/ansible_collections/cisco/meraki/plugins/action/networks_appliance_vpn_bgp_info.py new file mode 100644 index 000000000..a743e610d --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_appliance_vpn_bgp_info.py @@ -0,0 +1,90 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + networkId=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_all(self, params): + new_object = {} + if params.get("networkId") is not None: + new_object["networkId"] = params.get( + "networkId") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="appliance", + function='getNetworkApplianceVpnBgp', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_appliance_vpn_site_to_site_vpn.py b/ansible_collections/cisco/meraki/plugins/action/networks_appliance_vpn_site_to_site_vpn.py new file mode 100644 index 000000000..1a73bb08d --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_appliance_vpn_site_to_site_vpn.py @@ -0,0 +1,212 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or +# https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, + meraki_compare_equality, + get_dict_result, +) +from ansible_collections.cisco.meraki.plugins.plugin_utils.exceptions import ( + InconsistentParameters, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + state=dict(type="str", default="present", choices=["present"]), + mode=dict(type="str"), + hubs=dict(type="list"), + subnets=dict(type="list"), + networkId=dict(type="str"), +)) + +required_if = [ + ("state", "present", ["networkId"], True), +] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class NetworksApplianceVpnSiteToSiteVpn(object): + def __init__(self, params, meraki): + self.meraki = meraki + self.new_object = dict( + mode=params.get("mode"), + hubs=params.get("hubs"), + subnets=params.get("subnets"), + network_id=params.get("networkId"), + ) + + def get_all_params(self, name=None, id=None): + new_object_params = {} + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + return new_object_params + + def update_all_params(self): + new_object_params = {} + if self.new_object.get('mode') is not None or self.new_object.get('mode') is not None: + new_object_params['mode'] = self.new_object.get('mode') or \ + self.new_object.get('mode') + if self.new_object.get('hubs') is not None or self.new_object.get('hubs') is not None: + new_object_params['hubs'] = self.new_object.get('hubs') or \ + self.new_object.get('hubs') + if self.new_object.get('subnets') is not None or self.new_object.get('subnets') is not None: + new_object_params['subnets'] = self.new_object.get('subnets') or \ + self.new_object.get('subnets') + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + return new_object_params + + def get_object_by_name(self, name): + result = None + # NOTE: Does not have a get by name method, using get all + try: + items = self.meraki.exec_meraki( + family="appliance", + function="getNetworkApplianceVpnSiteToSiteVpn", + params=self.get_all_params(name=name), + ) + if isinstance(items, dict): + if 'response' in items: + items = items.get('response') + result = get_dict_result(items, 'name', name) + if result is None: + result = items + except Exception as e: + print("Error: ", e) + result = None + return result + + def get_object_by_id(self, id): + result = None + # NOTE: Does not have a get by id method or it is in another action + return result + + def exists(self): + prev_obj = None + id_exists = False + name_exists = False + o_id = self.new_object.get("networkId") or self.new_object.get("network_id") + name = self.new_object.get("name") + if o_id: + prev_obj = self.get_object_by_name(o_id) + id_exists = prev_obj is not None and isinstance(prev_obj, dict) + if not id_exists and name: + prev_obj = self.get_object_by_name(name) + name_exists = prev_obj is not None and isinstance(prev_obj, dict) + if name_exists: + _id = prev_obj.get("id") + if id_exists and name_exists and o_id != _id: + raise InconsistentParameters( + "The 'id' and 'name' params don't refer to the same object") + if _id: + self.new_object.update(dict(id=_id)) + it_exists = prev_obj is not None and isinstance(prev_obj, dict) + return (it_exists, prev_obj) + + def requires_update(self, current_obj): + requested_obj = self.new_object + + obj_params = [ + ("mode", "mode"), + ("hubs", "hubs"), + ("subnets", "subnets"), + ("networkId", "networkId"), + ] + # Method 1. Params present in request (Ansible) obj are the same as the current (ISE) params + # If any does not have eq params, it requires update + return any(not meraki_compare_equality(current_obj.get(meraki_param), + requested_obj.get(ansible_param)) + for (meraki_param, ansible_param) in obj_params) + + def update(self): + id = self.new_object.get("id") + name = self.new_object.get("name") + result = None + result = self.meraki.exec_meraki( + family="appliance", + function="updateNetworkApplianceVpnSiteToSiteVpn", + params=self.update_all_params(), + op_modifies=True, + ) + return result + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = False + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + meraki = MERAKI(self._task.args) + obj = NetworksApplianceVpnSiteToSiteVpn(self._task.args, meraki) + + state = self._task.args.get("state") + + response = None + if state == "present": + (obj_exists, prev_obj) = obj.exists() + if obj_exists: + if obj.requires_update(prev_obj): + response = obj.update() + meraki.object_updated() + else: + response = prev_obj + meraki.object_already_present() + else: + meraki.fail_json( + "Object does not exists, plugin only has update") + + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_appliance_vpn_site_to_site_vpn_info.py b/ansible_collections/cisco/meraki/plugins/action/networks_appliance_vpn_site_to_site_vpn_info.py new file mode 100644 index 000000000..1b95a0d7f --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_appliance_vpn_site_to_site_vpn_info.py @@ -0,0 +1,90 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + networkId=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_all(self, params): + new_object = {} + if params.get("networkId") is not None: + new_object["networkId"] = params.get( + "networkId") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="appliance", + function='getNetworkApplianceVpnSiteToSiteVpn', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_appliance_warm_spare.py b/ansible_collections/cisco/meraki/plugins/action/networks_appliance_warm_spare.py new file mode 100644 index 000000000..36e818951 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_appliance_warm_spare.py @@ -0,0 +1,223 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or +# https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, + meraki_compare_equality, + get_dict_result, +) +from ansible_collections.cisco.meraki.plugins.plugin_utils.exceptions import ( + InconsistentParameters, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + state=dict(type="str", default="present", choices=["present"]), + enabled=dict(type="bool"), + spareSerial=dict(type="str"), + uplinkMode=dict(type="str"), + virtualIp1=dict(type="str"), + virtualIp2=dict(type="str"), + networkId=dict(type="str"), +)) + +required_if = [ + ("state", "present", ["networkId"], True), +] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class NetworksApplianceWarmSpare(object): + def __init__(self, params, meraki): + self.meraki = meraki + self.new_object = dict( + enabled=params.get("enabled"), + spareSerial=params.get("spareSerial"), + uplinkMode=params.get("uplinkMode"), + virtualIp1=params.get("virtualIp1"), + virtualIp2=params.get("virtualIp2"), + network_id=params.get("networkId"), + ) + + def get_all_params(self, name=None, id=None): + new_object_params = {} + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + return new_object_params + + def update_all_params(self): + new_object_params = {} + if self.new_object.get('enabled') is not None or self.new_object.get('enabled') is not None: + new_object_params['enabled'] = self.new_object.get('enabled') + if self.new_object.get('spareSerial') is not None or self.new_object.get('spare_serial') is not None: + new_object_params['spareSerial'] = self.new_object.get('spareSerial') or \ + self.new_object.get('spare_serial') + if self.new_object.get('uplinkMode') is not None or self.new_object.get('uplink_mode') is not None: + new_object_params['uplinkMode'] = self.new_object.get('uplinkMode') or \ + self.new_object.get('uplink_mode') + if self.new_object.get('virtualIp1') is not None or self.new_object.get('virtual_ip1') is not None: + new_object_params['virtualIp1'] = self.new_object.get('virtualIp1') or \ + self.new_object.get('virtual_ip1') + if self.new_object.get('virtualIp2') is not None or self.new_object.get('virtual_ip2') is not None: + new_object_params['virtualIp2'] = self.new_object.get('virtualIp2') or \ + self.new_object.get('virtual_ip2') + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + return new_object_params + + def get_object_by_name(self, name): + result = None + # NOTE: Does not have a get by name method, using get all + try: + items = self.meraki.exec_meraki( + family="appliance", + function="getNetworkApplianceWarmSpare", + params=self.get_all_params(name=name), + ) + if isinstance(items, dict): + if 'response' in items: + items = items.get('response') + result = get_dict_result(items, 'name', name) + if result is None: + result = items + except Exception as e: + print("Error: ", e) + result = None + return result + + def get_object_by_id(self, id): + result = None + # NOTE: Does not have a get by id method or it is in another action + return result + + def exists(self): + prev_obj = None + id_exists = False + name_exists = False + o_id = self.new_object.get("networkId") or self.new_object.get("network_id") + name = self.new_object.get("name") + if o_id: + prev_obj = self.get_object_by_name(o_id) + id_exists = prev_obj is not None and isinstance(prev_obj, dict) + if not id_exists and name: + prev_obj = self.get_object_by_name(name) + name_exists = prev_obj is not None and isinstance(prev_obj, dict) + if name_exists: + _id = prev_obj.get("id") + if id_exists and name_exists and o_id != _id: + raise InconsistentParameters( + "The 'id' and 'name' params don't refer to the same object") + if _id: + self.new_object.update(dict(id=_id)) + it_exists = prev_obj is not None and isinstance(prev_obj, dict) + return (it_exists, prev_obj) + + def requires_update(self, current_obj): + requested_obj = self.new_object + + obj_params = [ + ("enabled", "enabled"), + ("spareSerial", "spareSerial"), + ("uplinkMode", "uplinkMode"), + ("virtualIp1", "virtualIp1"), + ("virtualIp2", "virtualIp2"), + ("networkId", "networkId"), + ] + # Method 1. Params present in request (Ansible) obj are the same as the current (ISE) params + # If any does not have eq params, it requires update + return any(not meraki_compare_equality(current_obj.get(meraki_param), + requested_obj.get(ansible_param)) + for (meraki_param, ansible_param) in obj_params) + + def update(self): + id = self.new_object.get("id") + name = self.new_object.get("name") + result = None + result = self.meraki.exec_meraki( + family="appliance", + function="updateNetworkApplianceWarmSpare", + params=self.update_all_params(), + op_modifies=True, + ) + return result + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = False + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + meraki = MERAKI(self._task.args) + obj = NetworksApplianceWarmSpare(self._task.args, meraki) + + state = self._task.args.get("state") + + response = None + if state == "present": + (obj_exists, prev_obj) = obj.exists() + if obj_exists: + if obj.requires_update(prev_obj): + response = obj.update() + meraki.object_updated() + else: + response = prev_obj + meraki.object_already_present() + else: + meraki.fail_json( + "Object does not exists, plugin only has update") + + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_appliance_warm_spare_info.py b/ansible_collections/cisco/meraki/plugins/action/networks_appliance_warm_spare_info.py new file mode 100644 index 000000000..7a08388fc --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_appliance_warm_spare_info.py @@ -0,0 +1,90 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + networkId=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_all(self, params): + new_object = {} + if params.get("networkId") is not None: + new_object["networkId"] = params.get( + "networkId") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="appliance", + function='getNetworkApplianceWarmSpare', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_appliance_warm_spare_swap.py b/ansible_collections/cisco/meraki/plugins/action/networks_appliance_warm_spare_swap.py new file mode 100644 index 000000000..cbd1f159e --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_appliance_warm_spare_swap.py @@ -0,0 +1,87 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguements specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + networkId=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = False + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_object(self, params): + new_object = dict( + networkId=params.get("networkId"), + ) + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="appliance", + function='swapNetworkApplianceWarmSpare', + op_modifies=True, + params=self.get_object(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_bind.py b/ansible_collections/cisco/meraki/plugins/action/networks_bind.py new file mode 100644 index 000000000..2e65eefb3 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_bind.py @@ -0,0 +1,91 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguements specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + configTemplateId=dict(type="str"), + autoBind=dict(type="bool"), + networkId=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = False + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_object(self, params): + new_object = dict( + configTemplateId=params.get("configTemplateId"), + autoBind=params.get("autoBind"), + networkId=params.get("networkId"), + ) + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="networks", + function='bindNetwork', + op_modifies=True, + params=self.get_object(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_bluetooth_clients_info.py b/ansible_collections/cisco/meraki/plugins/action/networks_bluetooth_clients_info.py new file mode 100644 index 000000000..b2c34a79e --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_bluetooth_clients_info.py @@ -0,0 +1,110 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + networkId=dict(type="str"), + bluetoothClientId=dict(type="str"), + includeConnectivityHistory=dict(type="bool"), + connectivityHistoryTimespan=dict(type="int"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_object(self, params): + new_object = {} + if params.get("networkId") is not None: + new_object["networkId"] = params.get( + "networkId") + if params.get("bluetoothClientId") is not None: + new_object["bluetoothClientId"] = params.get( + "bluetoothClientId") + if params.get("includeConnectivityHistory") is not None: + new_object["includeConnectivityHistory"] = params.get( + "includeConnectivityHistory") + if params.get("connectivityHistoryTimespan") is not None: + new_object["connectivityHistoryTimespan"] = params.get( + "connectivityHistoryTimespan") + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + id = self._task.args.get("bluetoothClientId") + if id: + response = meraki.exec_meraki( + family="networks", + function='getNetworkBluetoothClient', + params=self.get_object(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result + if not id: + # NOTE: Does not have a get all method or it is in another action + response = None + meraki.object_modify_result(changed=False, result="Module does not have get all, check arguments of module") + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_camera_quality_retention_profiles.py b/ansible_collections/cisco/meraki/plugins/action/networks_camera_quality_retention_profiles.py new file mode 100644 index 000000000..29e1aae17 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_camera_quality_retention_profiles.py @@ -0,0 +1,366 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or +# https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, + meraki_compare_equality, + get_dict_result, +) +from ansible_collections.cisco.meraki.plugins.plugin_utils.exceptions import ( + InconsistentParameters, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + state=dict(type="str", default="present", choices=["present", "absent"]), + name=dict(type="str"), + motionBasedRetentionEnabled=dict(type="bool"), + restrictedBandwidthModeEnabled=dict(type="bool"), + audioRecordingEnabled=dict(type="bool"), + cloudArchiveEnabled=dict(type="bool"), + motionDetectorVersion=dict(type="int"), + scheduleId=dict(type="str"), + maxRetentionDays=dict(type="int"), + videoSettings=dict(type="dict"), + networkId=dict(type="str"), + qualityRetentionProfileId=dict(type="str"), +)) + +required_if = [ + ("state", "present", ["name", "networkId", "qualityRetentionProfileId"], True), + ("state", "absent", ["name", "networkId", "qualityRetentionProfileId"], True), +] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class NetworksCameraQualityRetentionProfiles(object): + def __init__(self, params, meraki): + self.meraki = meraki + self.new_object = dict( + name=params.get("name"), + motionBasedRetentionEnabled=params.get("motionBasedRetentionEnabled"), + restrictedBandwidthModeEnabled=params.get("restrictedBandwidthModeEnabled"), + audioRecordingEnabled=params.get("audioRecordingEnabled"), + cloudArchiveEnabled=params.get("cloudArchiveEnabled"), + motionDetectorVersion=params.get("motionDetectorVersion"), + scheduleId=params.get("scheduleId"), + maxRetentionDays=params.get("maxRetentionDays"), + videoSettings=params.get("videoSettings"), + networkId=params.get("networkId"), + qualityRetentionProfileId=params.get("qualityRetentionProfileId"), + ) + + def get_all_params(self, name=None, id=None): + new_object_params = {} + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + return new_object_params + + def get_params_by_id(self, name=None, id=None): + new_object_params = {} + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + if self.new_object.get('qualityRetentionProfileId') is not None or self.new_object.get('quality_retention_profile_id') is not None: + new_object_params['qualityRetentionProfileId'] = self.new_object.get('qualityRetentionProfileId') or \ + self.new_object.get('quality_retention_profile_id') + return new_object_params + + def create_params(self): + new_object_params = {} + if self.new_object.get('name') is not None or self.new_object.get('name') is not None: + new_object_params['name'] = self.new_object.get('name') or \ + self.new_object.get('name') + if self.new_object.get('motionBasedRetentionEnabled') is not None or self.new_object.get('motion_based_retention_enabled') is not None: + new_object_params['motionBasedRetentionEnabled'] = self.new_object.get('motionBasedRetentionEnabled') + if self.new_object.get('restrictedBandwidthModeEnabled') is not None or self.new_object.get('restricted_bandwidth_mode_enabled') is not None: + new_object_params['restrictedBandwidthModeEnabled'] = self.new_object.get('restrictedBandwidthModeEnabled') + if self.new_object.get('audioRecordingEnabled') is not None or self.new_object.get('audio_recording_enabled') is not None: + new_object_params['audioRecordingEnabled'] = self.new_object.get('audioRecordingEnabled') + if self.new_object.get('cloudArchiveEnabled') is not None or self.new_object.get('cloud_archive_enabled') is not None: + new_object_params['cloudArchiveEnabled'] = self.new_object.get('cloudArchiveEnabled') + if self.new_object.get('motionDetectorVersion') is not None or self.new_object.get('motion_detector_version') is not None: + new_object_params['motionDetectorVersion'] = self.new_object.get('motionDetectorVersion') or \ + self.new_object.get('motion_detector_version') + if self.new_object.get('scheduleId') is not None or self.new_object.get('schedule_id') is not None: + new_object_params['scheduleId'] = self.new_object.get('scheduleId') or \ + self.new_object.get('schedule_id') + if self.new_object.get('maxRetentionDays') is not None or self.new_object.get('max_retention_days') is not None: + new_object_params['maxRetentionDays'] = self.new_object.get('maxRetentionDays') or \ + self.new_object.get('max_retention_days') + if self.new_object.get('videoSettings') is not None or self.new_object.get('video_settings') is not None: + new_object_params['videoSettings'] = self.new_object.get('videoSettings') or \ + self.new_object.get('video_settings') + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + return new_object_params + + def delete_by_id_params(self): + new_object_params = {} + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + if self.new_object.get('qualityRetentionProfileId') is not None or self.new_object.get('quality_retention_profile_id') is not None: + new_object_params['qualityRetentionProfileId'] = self.new_object.get('qualityRetentionProfileId') or \ + self.new_object.get('quality_retention_profile_id') + return new_object_params + + def update_by_id_params(self): + new_object_params = {} + if self.new_object.get('name') is not None or self.new_object.get('name') is not None: + new_object_params['name'] = self.new_object.get('name') or \ + self.new_object.get('name') + if self.new_object.get('motionBasedRetentionEnabled') is not None or self.new_object.get('motion_based_retention_enabled') is not None: + new_object_params['motionBasedRetentionEnabled'] = self.new_object.get('motionBasedRetentionEnabled') + if self.new_object.get('restrictedBandwidthModeEnabled') is not None or self.new_object.get('restricted_bandwidth_mode_enabled') is not None: + new_object_params['restrictedBandwidthModeEnabled'] = self.new_object.get('restrictedBandwidthModeEnabled') + if self.new_object.get('audioRecordingEnabled') is not None or self.new_object.get('audio_recording_enabled') is not None: + new_object_params['audioRecordingEnabled'] = self.new_object.get('audioRecordingEnabled') + if self.new_object.get('cloudArchiveEnabled') is not None or self.new_object.get('cloud_archive_enabled') is not None: + new_object_params['cloudArchiveEnabled'] = self.new_object.get('cloudArchiveEnabled') + if self.new_object.get('motionDetectorVersion') is not None or self.new_object.get('motion_detector_version') is not None: + new_object_params['motionDetectorVersion'] = self.new_object.get('motionDetectorVersion') or \ + self.new_object.get('motion_detector_version') + if self.new_object.get('scheduleId') is not None or self.new_object.get('schedule_id') is not None: + new_object_params['scheduleId'] = self.new_object.get('scheduleId') or \ + self.new_object.get('schedule_id') + if self.new_object.get('maxRetentionDays') is not None or self.new_object.get('max_retention_days') is not None: + new_object_params['maxRetentionDays'] = self.new_object.get('maxRetentionDays') or \ + self.new_object.get('max_retention_days') + if self.new_object.get('videoSettings') is not None or self.new_object.get('video_settings') is not None: + new_object_params['videoSettings'] = self.new_object.get('videoSettings') or \ + self.new_object.get('video_settings') + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + if self.new_object.get('qualityRetentionProfileId') is not None or self.new_object.get('quality_retention_profile_id') is not None: + new_object_params['qualityRetentionProfileId'] = self.new_object.get('qualityRetentionProfileId') or \ + self.new_object.get('quality_retention_profile_id') + return new_object_params + + def get_object_by_name(self, name): + result = None + # NOTE: Does not have a get by name method or it is in another action + try: + items = self.meraki.exec_meraki( + family="camera", + function="getNetworkCameraQualityRetentionProfiles", + params=self.get_all_params(name=name), + ) + if isinstance(items, dict): + if 'response' in items: + items = items.get('response') + result = get_dict_result(items, 'name', name) + if result is None: + result = items + except Exception as e: + print("Error: ", e) + result = None + return result + + def get_object_by_id(self, id): + result = None + try: + items = self.meraki.exec_meraki( + family="camera", + function="getNetworkCameraQualityRetentionProfile", + params=self.get_params_by_id() + ) + if isinstance(items, dict): + if 'response' in items: + items = items.get('response') + result = get_dict_result(items, 'qualityRetentionProfileId', id) + except Exception as e: + print("Error: ", e) + result = None + return result + + def exists(self): + id_exists = False + name_exists = False + prev_obj = None + o_id = self.new_object.get("id") + o_id = o_id or self.new_object.get( + "quality_retention_profile_id") or self.new_object.get("qualityRetentionProfileId") + name = self.new_object.get("name") + if o_id: + prev_obj = self.get_object_by_id(o_id) + id_exists = prev_obj is not None and isinstance(prev_obj, dict) + if not id_exists and name: + prev_obj = self.get_object_by_name(name) + name_exists = prev_obj is not None and isinstance(prev_obj, dict) + if name_exists: + _id = prev_obj.get("id") + _id = _id or prev_obj.get("qualityRetentionProfileId") + if id_exists and name_exists and o_id != _id: + raise InconsistentParameters( + "The 'id' and 'name' params don't refer to the same object") + if _id: + self.new_object.update(dict(id=_id)) + self.new_object.update(dict(qualityRetentionProfileId=_id)) + if _id: + prev_obj = self.get_object_by_id(_id) + it_exists = prev_obj is not None and isinstance(prev_obj, dict) + return (it_exists, prev_obj) + + def requires_update(self, current_obj): + requested_obj = self.new_object + + obj_params = [ + ("name", "name"), + ("motionBasedRetentionEnabled", "motionBasedRetentionEnabled"), + ("restrictedBandwidthModeEnabled", "restrictedBandwidthModeEnabled"), + ("audioRecordingEnabled", "audioRecordingEnabled"), + ("cloudArchiveEnabled", "cloudArchiveEnabled"), + ("motionDetectorVersion", "motionDetectorVersion"), + ("scheduleId", "scheduleId"), + ("maxRetentionDays", "maxRetentionDays"), + ("videoSettings", "videoSettings"), + ("networkId", "networkId"), + ("qualityRetentionProfileId", "qualityRetentionProfileId"), + ] + # Method 1. Params present in request (Ansible) obj are the same as the current (DNAC) params + # If any does not have eq params, it requires update + return any(not meraki_compare_equality(current_obj.get(meraki_param), + requested_obj.get(ansible_param)) + for (meraki_param, ansible_param) in obj_params) + + def create(self): + result = self.meraki.exec_meraki( + family="camera", + function="createNetworkCameraQualityRetentionProfile", + params=self.create_params(), + op_modifies=True, + ) + return result + + def update(self): + id = self.new_object.get("id") + id = id or self.new_object.get("qualityRetentionProfileId") + name = self.new_object.get("name") + result = None + if not id: + prev_obj_name = self.get_object_by_name(name) + id_ = None + if prev_obj_name: + id_ = prev_obj_name.get("id") + id_ = id_ or prev_obj_name.get("qualityRetentionProfileId") + if id_: + self.new_object.update(dict(qualityRetentionProfileId=id_)) + result = self.meraki.exec_meraki( + family="camera", + function="updateNetworkCameraQualityRetentionProfile", + params=self.update_by_id_params(), + op_modifies=True, + ) + return result + + def delete(self): + id = self.new_object.get("id") + id = id or self.new_object.get("qualityRetentionProfileId") + name = self.new_object.get("name") + result = None + if not id: + prev_obj_name = self.get_object_by_name(name) + id_ = None + if prev_obj_name: + id_ = prev_obj_name.get("id") + id_ = id_ or prev_obj_name.get("qualityRetentionProfileId") + if id_: + self.new_object.update(dict(qualityRetentionProfileId=id_)) + result = self.meraki.exec_meraki( + family="camera", + function="deleteNetworkCameraQualityRetentionProfile", + params=self.delete_by_id_params(), + ) + return result + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = False + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + meraki = MERAKI(self._task.args) + obj = NetworksCameraQualityRetentionProfiles(self._task.args, meraki) + + state = self._task.args.get("state") + + response = None + + if state == "present": + (obj_exists, prev_obj) = obj.exists() + if obj_exists: + if obj.requires_update(prev_obj): + response = obj.update() + meraki.object_updated() + else: + response = prev_obj + meraki.object_already_present() + else: + response = obj.create() + meraki.object_created() + + elif state == "absent": + (obj_exists, prev_obj) = obj.exists() + if obj_exists: + response = obj.delete() + meraki.object_deleted() + else: + meraki.object_already_absent() + + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_camera_quality_retention_profiles_info.py b/ansible_collections/cisco/meraki/plugins/action/networks_camera_quality_retention_profiles_info.py new file mode 100644 index 000000000..9e6ac1eb4 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_camera_quality_retention_profiles_info.py @@ -0,0 +1,112 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + networkId=dict(type="str"), + qualityRetentionProfileId=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_object(self, params): + new_object = {} + if params.get("networkId") is not None: + new_object["networkId"] = params.get( + "networkId") + if params.get("qualityRetentionProfileId") is not None: + new_object["qualityRetentionProfileId"] = params.get( + "qualityRetentionProfileId") + return new_object + + def get_all(self, params): + new_object = {} + if params.get("networkId") is not None: + new_object["networkId"] = params.get( + "networkId") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + id = self._task.args.get("qualityRetentionProfileId") + if id: + response = meraki.exec_meraki( + family="camera", + function='getNetworkCameraQualityRetentionProfile', + params=self.get_object(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result + if not id: + response = meraki.exec_meraki( + family="camera", + function='getNetworkCameraQualityRetentionProfiles', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_camera_wireless_profiles.py b/ansible_collections/cisco/meraki/plugins/action/networks_camera_wireless_profiles.py new file mode 100644 index 000000000..4aedf37c2 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_camera_wireless_profiles.py @@ -0,0 +1,320 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or +# https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, + meraki_compare_equality, + get_dict_result, +) +from ansible_collections.cisco.meraki.plugins.plugin_utils.exceptions import ( + InconsistentParameters, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + state=dict(type="str", default="present", choices=["present", "absent"]), + name=dict(type="str"), + ssid=dict(type="dict"), + identity=dict(type="dict"), + networkId=dict(type="str"), + wirelessProfileId=dict(type="str"), +)) + +required_if = [ + ("state", "present", ["name", "networkId", "wirelessProfileId"], True), + ("state", "absent", ["name", "networkId", "wirelessProfileId"], True), +] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class NetworksCameraWirelessProfiles(object): + def __init__(self, params, meraki): + self.meraki = meraki + self.new_object = dict( + name=params.get("name"), + ssid=params.get("ssid"), + identity=params.get("identity"), + networkId=params.get("networkId"), + wirelessProfileId=params.get("wirelessProfileId"), + ) + + def get_all_params(self, name=None, id=None): + new_object_params = {} + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + return new_object_params + + def get_params_by_id(self, name=None, id=None): + new_object_params = {} + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + if self.new_object.get('wirelessProfileId') is not None or self.new_object.get('wireless_profile_id') is not None: + new_object_params['wirelessProfileId'] = self.new_object.get('wirelessProfileId') or \ + self.new_object.get('wireless_profile_id') + return new_object_params + + def create_params(self): + new_object_params = {} + if self.new_object.get('name') is not None or self.new_object.get('name') is not None: + new_object_params['name'] = self.new_object.get('name') or \ + self.new_object.get('name') + if self.new_object.get('ssid') is not None or self.new_object.get('ssid') is not None: + new_object_params['ssid'] = self.new_object.get('ssid') or \ + self.new_object.get('ssid') + if self.new_object.get('identity') is not None or self.new_object.get('identity') is not None: + new_object_params['identity'] = self.new_object.get('identity') or \ + self.new_object.get('identity') + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + return new_object_params + + def delete_by_id_params(self): + new_object_params = {} + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + if self.new_object.get('wirelessProfileId') is not None or self.new_object.get('wireless_profile_id') is not None: + new_object_params['wirelessProfileId'] = self.new_object.get('wirelessProfileId') or \ + self.new_object.get('wireless_profile_id') + return new_object_params + + def update_by_id_params(self): + new_object_params = {} + if self.new_object.get('name') is not None or self.new_object.get('name') is not None: + new_object_params['name'] = self.new_object.get('name') or \ + self.new_object.get('name') + if self.new_object.get('ssid') is not None or self.new_object.get('ssid') is not None: + new_object_params['ssid'] = self.new_object.get('ssid') or \ + self.new_object.get('ssid') + if self.new_object.get('identity') is not None or self.new_object.get('identity') is not None: + new_object_params['identity'] = self.new_object.get('identity') or \ + self.new_object.get('identity') + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + if self.new_object.get('wirelessProfileId') is not None or self.new_object.get('wireless_profile_id') is not None: + new_object_params['wirelessProfileId'] = self.new_object.get('wirelessProfileId') or \ + self.new_object.get('wireless_profile_id') + return new_object_params + + def get_object_by_name(self, name): + result = None + # NOTE: Does not have a get by name method or it is in another action + try: + items = self.meraki.exec_meraki( + family="camera", + function="getNetworkCameraWirelessProfiles", + params=self.get_all_params(name=name), + ) + if isinstance(items, dict): + if 'response' in items: + items = items.get('response') + result = get_dict_result(items, 'name', name) + if result is None: + result = items + except Exception as e: + print("Error: ", e) + result = None + return result + + def get_object_by_id(self, id): + result = None + try: + items = self.meraki.exec_meraki( + family="camera", + function="getNetworkCameraWirelessProfile", + params=self.get_params_by_id() + ) + if isinstance(items, dict): + if 'response' in items: + items = items.get('response') + result = get_dict_result(items, 'wirelessProfileId', id) + except Exception as e: + print("Error: ", e) + result = None + return result + + def exists(self): + id_exists = False + name_exists = False + prev_obj = None + o_id = self.new_object.get("id") + o_id = o_id or self.new_object.get( + "wireless_profile_id") or self.new_object.get("wirelessProfileId") + name = self.new_object.get("name") + if o_id: + prev_obj = self.get_object_by_id(o_id) + id_exists = prev_obj is not None and isinstance(prev_obj, dict) + if not id_exists and name: + prev_obj = self.get_object_by_name(name) + name_exists = prev_obj is not None and isinstance(prev_obj, dict) + if name_exists: + _id = prev_obj.get("id") + _id = _id or prev_obj.get("wirelessProfileId") + if id_exists and name_exists and o_id != _id: + raise InconsistentParameters( + "The 'id' and 'name' params don't refer to the same object") + if _id: + self.new_object.update(dict(id=_id)) + self.new_object.update(dict(wirelessProfileId=_id)) + if _id: + prev_obj = self.get_object_by_id(_id) + it_exists = prev_obj is not None and isinstance(prev_obj, dict) + return (it_exists, prev_obj) + + def requires_update(self, current_obj): + requested_obj = self.new_object + + obj_params = [ + ("name", "name"), + ("ssid", "ssid"), + ("identity", "identity"), + ("networkId", "networkId"), + ("wirelessProfileId", "wirelessProfileId"), + ] + # Method 1. Params present in request (Ansible) obj are the same as the current (DNAC) params + # If any does not have eq params, it requires update + return any(not meraki_compare_equality(current_obj.get(meraki_param), + requested_obj.get(ansible_param)) + for (meraki_param, ansible_param) in obj_params) + + def create(self): + result = self.meraki.exec_meraki( + family="camera", + function="createNetworkCameraWirelessProfile", + params=self.create_params(), + op_modifies=True, + ) + return result + + def update(self): + id = self.new_object.get("id") + id = id or self.new_object.get("wirelessProfileId") + name = self.new_object.get("name") + result = None + if not id: + prev_obj_name = self.get_object_by_name(name) + id_ = None + if prev_obj_name: + id_ = prev_obj_name.get("id") + id_ = id_ or prev_obj_name.get("wirelessProfileId") + if id_: + self.new_object.update(dict(wirelessProfileId=id_)) + result = self.meraki.exec_meraki( + family="camera", + function="updateNetworkCameraWirelessProfile", + params=self.update_by_id_params(), + op_modifies=True, + ) + return result + + def delete(self): + id = self.new_object.get("id") + id = id or self.new_object.get("wirelessProfileId") + name = self.new_object.get("name") + result = None + if not id: + prev_obj_name = self.get_object_by_name(name) + id_ = None + if prev_obj_name: + id_ = prev_obj_name.get("id") + id_ = id_ or prev_obj_name.get("wirelessProfileId") + if id_: + self.new_object.update(dict(wirelessProfileId=id_)) + result = self.meraki.exec_meraki( + family="camera", + function="deleteNetworkCameraWirelessProfile", + params=self.delete_by_id_params(), + ) + return result + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = False + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + meraki = MERAKI(self._task.args) + obj = NetworksCameraWirelessProfiles(self._task.args, meraki) + + state = self._task.args.get("state") + + response = None + + if state == "present": + (obj_exists, prev_obj) = obj.exists() + if obj_exists: + if obj.requires_update(prev_obj): + response = obj.update() + meraki.object_updated() + else: + response = prev_obj + meraki.object_already_present() + else: + response = obj.create() + meraki.object_created() + + elif state == "absent": + (obj_exists, prev_obj) = obj.exists() + if obj_exists: + response = obj.delete() + meraki.object_deleted() + else: + meraki.object_already_absent() + + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_camera_wireless_profiles_info.py b/ansible_collections/cisco/meraki/plugins/action/networks_camera_wireless_profiles_info.py new file mode 100644 index 000000000..692bc8320 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_camera_wireless_profiles_info.py @@ -0,0 +1,112 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + networkId=dict(type="str"), + wirelessProfileId=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_object(self, params): + new_object = {} + if params.get("networkId") is not None: + new_object["networkId"] = params.get( + "networkId") + if params.get("wirelessProfileId") is not None: + new_object["wirelessProfileId"] = params.get( + "wirelessProfileId") + return new_object + + def get_all(self, params): + new_object = {} + if params.get("networkId") is not None: + new_object["networkId"] = params.get( + "networkId") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + id = self._task.args.get("wirelessProfileId") + if id: + response = meraki.exec_meraki( + family="camera", + function='getNetworkCameraWirelessProfile', + params=self.get_object(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result + if not id: + response = meraki.exec_meraki( + family="camera", + function='getNetworkCameraWirelessProfiles', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_cellular_gateway_connectivity_monitoring_destinations.py b/ansible_collections/cisco/meraki/plugins/action/networks_cellular_gateway_connectivity_monitoring_destinations.py new file mode 100644 index 000000000..672f71221 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_cellular_gateway_connectivity_monitoring_destinations.py @@ -0,0 +1,200 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or +# https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, + meraki_compare_equality, + get_dict_result, +) +from ansible_collections.cisco.meraki.plugins.plugin_utils.exceptions import ( + InconsistentParameters, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + state=dict(type="str", default="present", choices=["present"]), + destinations=dict(type="list"), + networkId=dict(type="str"), +)) + +required_if = [ + ("state", "present", ["networkId"], True), +] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class NetworksCellularGatewayConnectivityMonitoringDestinations(object): + def __init__(self, params, meraki): + self.meraki = meraki + self.new_object = dict( + destinations=params.get("destinations"), + network_id=params.get("networkId"), + ) + + def get_all_params(self, name=None, id=None): + new_object_params = {} + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + return new_object_params + + def update_all_params(self): + new_object_params = {} + if self.new_object.get('destinations') is not None or self.new_object.get('destinations') is not None: + new_object_params['destinations'] = self.new_object.get('destinations') or \ + self.new_object.get('destinations') + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + return new_object_params + + def get_object_by_name(self, name): + result = None + # NOTE: Does not have a get by name method, using get all + try: + items = self.meraki.exec_meraki( + family="cellulargateway", + function="getNetworkCellularGatewayConnectivityMonitoringDestinations", + params=self.get_all_params(name=name), + ) + if isinstance(items, dict): + if 'response' in items: + items = items.get('response') + result = get_dict_result(items, 'name', name) + if result is None: + result = items + except Exception as e: + print("Error: ", e) + result = None + return result + + def get_object_by_id(self, id): + result = None + # NOTE: Does not have a get by id method or it is in another action + return result + + def exists(self): + prev_obj = None + id_exists = False + name_exists = False + o_id = self.new_object.get("networkId") or self.new_object.get("network_id") + name = self.new_object.get("name") + if o_id: + prev_obj = self.get_object_by_name(o_id) + id_exists = prev_obj is not None and isinstance(prev_obj, dict) + if not id_exists and name: + prev_obj = self.get_object_by_name(name) + name_exists = prev_obj is not None and isinstance(prev_obj, dict) + if name_exists: + _id = prev_obj.get("id") + if id_exists and name_exists and o_id != _id: + raise InconsistentParameters( + "The 'id' and 'name' params don't refer to the same object") + if _id: + self.new_object.update(dict(id=_id)) + it_exists = prev_obj is not None and isinstance(prev_obj, dict) + return (it_exists, prev_obj) + + def requires_update(self, current_obj): + requested_obj = self.new_object + + obj_params = [ + ("destinations", "destinations"), + ("networkId", "networkId"), + ] + # Method 1. Params present in request (Ansible) obj are the same as the current (ISE) params + # If any does not have eq params, it requires update + return any(not meraki_compare_equality(current_obj.get(meraki_param), + requested_obj.get(ansible_param)) + for (meraki_param, ansible_param) in obj_params) + + def update(self): + id = self.new_object.get("id") + name = self.new_object.get("name") + result = None + result = self.meraki.exec_meraki( + family="cellulargateway", + function="updateNetworkCellularGatewayConnectivityMonitoringDestinations", + params=self.update_all_params(), + op_modifies=True, + ) + return result + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = False + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + meraki = MERAKI(self._task.args) + obj = NetworksCellularGatewayConnectivityMonitoringDestinations(self._task.args, meraki) + + state = self._task.args.get("state") + + response = None + if state == "present": + (obj_exists, prev_obj) = obj.exists() + if obj_exists: + if obj.requires_update(prev_obj): + response = obj.update() + meraki.object_updated() + else: + response = prev_obj + meraki.object_already_present() + else: + meraki.fail_json( + "Object does not exists, plugin only has update") + + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_cellular_gateway_connectivity_monitoring_destinations_info.py b/ansible_collections/cisco/meraki/plugins/action/networks_cellular_gateway_connectivity_monitoring_destinations_info.py new file mode 100644 index 000000000..ad158b2d4 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_cellular_gateway_connectivity_monitoring_destinations_info.py @@ -0,0 +1,90 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + networkId=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_all(self, params): + new_object = {} + if params.get("networkId") is not None: + new_object["networkId"] = params.get( + "networkId") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="cellular_gateway", + function='getNetworkCellularGatewayConnectivityMonitoringDestinations', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_cellular_gateway_dhcp.py b/ansible_collections/cisco/meraki/plugins/action/networks_cellular_gateway_dhcp.py new file mode 100644 index 000000000..a02d4c4d4 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_cellular_gateway_dhcp.py @@ -0,0 +1,212 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or +# https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, + meraki_compare_equality, + get_dict_result, +) +from ansible_collections.cisco.meraki.plugins.plugin_utils.exceptions import ( + InconsistentParameters, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + state=dict(type="str", default="present", choices=["present"]), + dhcpLeaseTime=dict(type="str"), + dnsNameservers=dict(type="str"), + dnsCustomNameservers=dict(type="list"), + networkId=dict(type="str"), +)) + +required_if = [ + ("state", "present", ["networkId"], True), +] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class NetworksCellularGatewayDhcp(object): + def __init__(self, params, meraki): + self.meraki = meraki + self.new_object = dict( + dhcpLeaseTime=params.get("dhcpLeaseTime"), + dnsNameservers=params.get("dnsNameservers"), + dnsCustomNameservers=params.get("dnsCustomNameservers"), + network_id=params.get("networkId"), + ) + + def get_all_params(self, name=None, id=None): + new_object_params = {} + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + return new_object_params + + def update_all_params(self): + new_object_params = {} + if self.new_object.get('dhcpLeaseTime') is not None or self.new_object.get('dhcp_lease_time') is not None: + new_object_params['dhcpLeaseTime'] = self.new_object.get('dhcpLeaseTime') or \ + self.new_object.get('dhcp_lease_time') + if self.new_object.get('dnsNameservers') is not None or self.new_object.get('dns_nameservers') is not None: + new_object_params['dnsNameservers'] = self.new_object.get('dnsNameservers') or \ + self.new_object.get('dns_nameservers') + if self.new_object.get('dnsCustomNameservers') is not None or self.new_object.get('dns_custom_nameservers') is not None: + new_object_params['dnsCustomNameservers'] = self.new_object.get('dnsCustomNameservers') or \ + self.new_object.get('dns_custom_nameservers') + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + return new_object_params + + def get_object_by_name(self, name): + result = None + # NOTE: Does not have a get by name method, using get all + try: + items = self.meraki.exec_meraki( + family="cellulargateway", + function="getNetworkCellularGatewayDhcp", + params=self.get_all_params(name=name), + ) + if isinstance(items, dict): + if 'response' in items: + items = items.get('response') + result = get_dict_result(items, 'name', name) + if result is None: + result = items + except Exception as e: + print("Error: ", e) + result = None + return result + + def get_object_by_id(self, id): + result = None + # NOTE: Does not have a get by id method or it is in another action + return result + + def exists(self): + prev_obj = None + id_exists = False + name_exists = False + o_id = self.new_object.get("networkId") or self.new_object.get("network_id") + name = self.new_object.get("name") + if o_id: + prev_obj = self.get_object_by_name(o_id) + id_exists = prev_obj is not None and isinstance(prev_obj, dict) + if not id_exists and name: + prev_obj = self.get_object_by_name(name) + name_exists = prev_obj is not None and isinstance(prev_obj, dict) + if name_exists: + _id = prev_obj.get("id") + if id_exists and name_exists and o_id != _id: + raise InconsistentParameters( + "The 'id' and 'name' params don't refer to the same object") + if _id: + self.new_object.update(dict(id=_id)) + it_exists = prev_obj is not None and isinstance(prev_obj, dict) + return (it_exists, prev_obj) + + def requires_update(self, current_obj): + requested_obj = self.new_object + + obj_params = [ + ("dhcpLeaseTime", "dhcpLeaseTime"), + ("dnsNameservers", "dnsNameservers"), + ("dnsCustomNameservers", "dnsCustomNameservers"), + ("networkId", "networkId"), + ] + # Method 1. Params present in request (Ansible) obj are the same as the current (ISE) params + # If any does not have eq params, it requires update + return any(not meraki_compare_equality(current_obj.get(meraki_param), + requested_obj.get(ansible_param)) + for (meraki_param, ansible_param) in obj_params) + + def update(self): + id = self.new_object.get("id") + name = self.new_object.get("name") + result = None + result = self.meraki.exec_meraki( + family="cellulargateway", + function="updateNetworkCellularGatewayDhcp", + params=self.update_all_params(), + op_modifies=True, + ) + return result + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = False + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + meraki = MERAKI(self._task.args) + obj = NetworksCellularGatewayDhcp(self._task.args, meraki) + + state = self._task.args.get("state") + + response = None + if state == "present": + (obj_exists, prev_obj) = obj.exists() + if obj_exists: + if obj.requires_update(prev_obj): + response = obj.update() + meraki.object_updated() + else: + response = prev_obj + meraki.object_already_present() + else: + meraki.fail_json( + "Object does not exists, plugin only has update") + + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_cellular_gateway_dhcp_info.py b/ansible_collections/cisco/meraki/plugins/action/networks_cellular_gateway_dhcp_info.py new file mode 100644 index 000000000..9fbc55ddb --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_cellular_gateway_dhcp_info.py @@ -0,0 +1,90 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + networkId=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_all(self, params): + new_object = {} + if params.get("networkId") is not None: + new_object["networkId"] = params.get( + "networkId") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="cellular_gateway", + function='getNetworkCellularGatewayDhcp', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_cellular_gateway_subnet_pool.py b/ansible_collections/cisco/meraki/plugins/action/networks_cellular_gateway_subnet_pool.py new file mode 100644 index 000000000..4af5e75ad --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_cellular_gateway_subnet_pool.py @@ -0,0 +1,206 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or +# https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, + meraki_compare_equality, + get_dict_result, +) +from ansible_collections.cisco.meraki.plugins.plugin_utils.exceptions import ( + InconsistentParameters, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + state=dict(type="str", default="present", choices=["present"]), + mask=dict(type="int"), + cidr=dict(type="str"), + networkId=dict(type="str"), +)) + +required_if = [ + ("state", "present", ["networkId"], True), +] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class NetworksCellularGatewaySubnetPool(object): + def __init__(self, params, meraki): + self.meraki = meraki + self.new_object = dict( + mask=params.get("mask"), + cidr=params.get("cidr"), + network_id=params.get("networkId"), + ) + + def get_all_params(self, name=None, id=None): + new_object_params = {} + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + return new_object_params + + def update_all_params(self): + new_object_params = {} + if self.new_object.get('mask') is not None or self.new_object.get('mask') is not None: + new_object_params['mask'] = self.new_object.get('mask') or \ + self.new_object.get('mask') + if self.new_object.get('cidr') is not None or self.new_object.get('cidr') is not None: + new_object_params['cidr'] = self.new_object.get('cidr') or \ + self.new_object.get('cidr') + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + return new_object_params + + def get_object_by_name(self, name): + result = None + # NOTE: Does not have a get by name method, using get all + try: + items = self.meraki.exec_meraki( + family="cellulargateway", + function="getNetworkCellularGatewaySubnetPool", + params=self.get_all_params(name=name), + ) + if isinstance(items, dict): + if 'response' in items: + items = items.get('response') + result = get_dict_result(items, 'name', name) + if result is None: + result = items + except Exception as e: + print("Error: ", e) + result = None + return result + + def get_object_by_id(self, id): + result = None + # NOTE: Does not have a get by id method or it is in another action + return result + + def exists(self): + prev_obj = None + id_exists = False + name_exists = False + o_id = self.new_object.get("networkId") or self.new_object.get("network_id") + name = self.new_object.get("name") + if o_id: + prev_obj = self.get_object_by_name(o_id) + id_exists = prev_obj is not None and isinstance(prev_obj, dict) + if not id_exists and name: + prev_obj = self.get_object_by_name(name) + name_exists = prev_obj is not None and isinstance(prev_obj, dict) + if name_exists: + _id = prev_obj.get("id") + if id_exists and name_exists and o_id != _id: + raise InconsistentParameters( + "The 'id' and 'name' params don't refer to the same object") + if _id: + self.new_object.update(dict(id=_id)) + it_exists = prev_obj is not None and isinstance(prev_obj, dict) + return (it_exists, prev_obj) + + def requires_update(self, current_obj): + requested_obj = self.new_object + + obj_params = [ + ("mask", "mask"), + ("cidr", "cidr"), + ("networkId", "networkId"), + ] + # Method 1. Params present in request (Ansible) obj are the same as the current (ISE) params + # If any does not have eq params, it requires update + return any(not meraki_compare_equality(current_obj.get(meraki_param), + requested_obj.get(ansible_param)) + for (meraki_param, ansible_param) in obj_params) + + def update(self): + id = self.new_object.get("id") + name = self.new_object.get("name") + result = None + result = self.meraki.exec_meraki( + family="cellulargateway", + function="updateNetworkCellularGatewaySubnetPool", + params=self.update_all_params(), + op_modifies=True, + ) + return result + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = False + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + meraki = MERAKI(self._task.args) + obj = NetworksCellularGatewaySubnetPool(self._task.args, meraki) + + state = self._task.args.get("state") + + response = None + if state == "present": + (obj_exists, prev_obj) = obj.exists() + if obj_exists: + if obj.requires_update(prev_obj): + response = obj.update() + meraki.object_updated() + else: + response = prev_obj + meraki.object_already_present() + else: + meraki.fail_json( + "Object does not exists, plugin only has update") + + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_cellular_gateway_subnet_pool_info.py b/ansible_collections/cisco/meraki/plugins/action/networks_cellular_gateway_subnet_pool_info.py new file mode 100644 index 000000000..bb1355322 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_cellular_gateway_subnet_pool_info.py @@ -0,0 +1,90 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + networkId=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_all(self, params): + new_object = {} + if params.get("networkId") is not None: + new_object["networkId"] = params.get( + "networkId") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="cellular_gateway", + function='getNetworkCellularGatewaySubnetPool', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_cellular_gateway_uplink.py b/ansible_collections/cisco/meraki/plugins/action/networks_cellular_gateway_uplink.py new file mode 100644 index 000000000..ee99407ef --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_cellular_gateway_uplink.py @@ -0,0 +1,200 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or +# https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, + meraki_compare_equality, + get_dict_result, +) +from ansible_collections.cisco.meraki.plugins.plugin_utils.exceptions import ( + InconsistentParameters, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + state=dict(type="str", default="present", choices=["present"]), + bandwidthLimits=dict(type="dict"), + networkId=dict(type="str"), +)) + +required_if = [ + ("state", "present", ["networkId"], True), +] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class NetworksCellularGatewayUplink(object): + def __init__(self, params, meraki): + self.meraki = meraki + self.new_object = dict( + bandwidthLimits=params.get("bandwidthLimits"), + network_id=params.get("networkId"), + ) + + def get_all_params(self, name=None, id=None): + new_object_params = {} + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + return new_object_params + + def update_all_params(self): + new_object_params = {} + if self.new_object.get('bandwidthLimits') is not None or self.new_object.get('bandwidth_limits') is not None: + new_object_params['bandwidthLimits'] = self.new_object.get('bandwidthLimits') or \ + self.new_object.get('bandwidth_limits') + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + return new_object_params + + def get_object_by_name(self, name): + result = None + # NOTE: Does not have a get by name method, using get all + try: + items = self.meraki.exec_meraki( + family="cellulargateway", + function="getNetworkCellularGatewayUplink", + params=self.get_all_params(name=name), + ) + if isinstance(items, dict): + if 'response' in items: + items = items.get('response') + result = get_dict_result(items, 'name', name) + if result is None: + result = items + except Exception as e: + print("Error: ", e) + result = None + return result + + def get_object_by_id(self, id): + result = None + # NOTE: Does not have a get by id method or it is in another action + return result + + def exists(self): + prev_obj = None + id_exists = False + name_exists = False + o_id = self.new_object.get("networkId") or self.new_object.get("network_id") + name = self.new_object.get("name") + if o_id: + prev_obj = self.get_object_by_name(o_id) + id_exists = prev_obj is not None and isinstance(prev_obj, dict) + if not id_exists and name: + prev_obj = self.get_object_by_name(name) + name_exists = prev_obj is not None and isinstance(prev_obj, dict) + if name_exists: + _id = prev_obj.get("id") + if id_exists and name_exists and o_id != _id: + raise InconsistentParameters( + "The 'id' and 'name' params don't refer to the same object") + if _id: + self.new_object.update(dict(id=_id)) + it_exists = prev_obj is not None and isinstance(prev_obj, dict) + return (it_exists, prev_obj) + + def requires_update(self, current_obj): + requested_obj = self.new_object + + obj_params = [ + ("bandwidthLimits", "bandwidthLimits"), + ("networkId", "networkId"), + ] + # Method 1. Params present in request (Ansible) obj are the same as the current (ISE) params + # If any does not have eq params, it requires update + return any(not meraki_compare_equality(current_obj.get(meraki_param), + requested_obj.get(ansible_param)) + for (meraki_param, ansible_param) in obj_params) + + def update(self): + id = self.new_object.get("id") + name = self.new_object.get("name") + result = None + result = self.meraki.exec_meraki( + family="cellulargateway", + function="updateNetworkCellularGatewayUplink", + params=self.update_all_params(), + op_modifies=True, + ) + return result + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = False + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + meraki = MERAKI(self._task.args) + obj = NetworksCellularGatewayUplink(self._task.args, meraki) + + state = self._task.args.get("state") + + response = None + if state == "present": + (obj_exists, prev_obj) = obj.exists() + if obj_exists: + if obj.requires_update(prev_obj): + response = obj.update() + meraki.object_updated() + else: + response = prev_obj + meraki.object_already_present() + else: + meraki.fail_json( + "Object does not exists, plugin only has update") + + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_cellular_gateway_uplink_info.py b/ansible_collections/cisco/meraki/plugins/action/networks_cellular_gateway_uplink_info.py new file mode 100644 index 000000000..d1cbf3748 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_cellular_gateway_uplink_info.py @@ -0,0 +1,90 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + networkId=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_all(self, params): + new_object = {} + if params.get("networkId") is not None: + new_object["networkId"] = params.get( + "networkId") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="cellular_gateway", + function='getNetworkCellularGatewayUplink', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_client_info.py b/ansible_collections/cisco/meraki/plugins/action/networks_client_info.py new file mode 100644 index 000000000..cb865220d --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_client_info.py @@ -0,0 +1,102 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + networkId=dict(type="str"), + clientId=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_object(self, params): + new_object = {} + if params.get("networkId") is not None: + new_object["networkId"] = params.get( + "networkId") + if params.get("clientId") is not None: + new_object["clientId"] = params.get( + "clientId") + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + id = self._task.args.get("clientId") + if id: + response = meraki.exec_meraki( + family="networks", + function='getNetworkClient', + params=self.get_object(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result + if not id: + # NOTE: Does not have a get all method or it is in another action + response = None + meraki.object_modify_result(changed=False, result="Module does not have get all, check arguments of module") + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_clients_info.py b/ansible_collections/cisco/meraki/plugins/action/networks_clients_info.py new file mode 100644 index 000000000..7f6eae8dc --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_clients_info.py @@ -0,0 +1,156 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + networkId=dict(type="str"), + t0=dict(type="str"), + timespan=dict(type="float"), + perPage=dict(type="int"), + total_pages=dict(type="int"), + direction=dict(type="str"), + startingAfter=dict(type="str"), + endingBefore=dict(type="str"), + statuses=dict(type="list"), + ip=dict(type="str"), + ip6=dict(type="str"), + ip6Local=dict(type="str"), + mac=dict(type="str"), + os=dict(type="str"), + pskGroup=dict(type="str"), + description=dict(type="str"), + vlan=dict(type="str"), + recentDeviceConnections=dict(type="list"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_all(self, params): + new_object = {} + if params.get("networkId") is not None: + new_object["networkId"] = params.get( + "networkId") + if params.get("t0") is not None: + new_object["t0"] = params.get( + "t0") + if params.get("timespan") is not None: + new_object["timespan"] = params.get( + "timespan") + if params.get("perPage") is not None: + new_object["perPage"] = params.get( + "perPage") + new_object['total_pages'] = params.get( + "total_pages") or 1 + new_object['direction'] = params.get( + "direction") or "next" + if params.get("startingAfter") is not None: + new_object["startingAfter"] = params.get( + "startingAfter") + if params.get("endingBefore") is not None: + new_object["endingBefore"] = params.get( + "endingBefore") + if params.get("statuses") is not None: + new_object["statuses"] = params.get( + "statuses") + if params.get("ip") is not None: + new_object["ip"] = params.get( + "ip") + if params.get("ip6") is not None: + new_object["ip6"] = params.get( + "ip6") + if params.get("ip6Local") is not None: + new_object["ip6Local"] = params.get( + "ip6Local") + if params.get("mac") is not None: + new_object["mac"] = params.get( + "mac") + if params.get("os") is not None: + new_object["os"] = params.get( + "os") + if params.get("pskGroup") is not None: + new_object["pskGroup"] = params.get( + "pskGroup") + if params.get("description") is not None: + new_object["description"] = params.get( + "description") + if params.get("vlan") is not None: + new_object["vlan"] = params.get( + "vlan") + if params.get("recentDeviceConnections") is not None: + new_object["recentDeviceConnections"] = params.get( + "recentDeviceConnections") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="networks", + function='getNetworkClients', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_clients_overview_info.py b/ansible_collections/cisco/meraki/plugins/action/networks_clients_overview_info.py new file mode 100644 index 000000000..2cc18c14b --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_clients_overview_info.py @@ -0,0 +1,106 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + networkId=dict(type="str"), + t0=dict(type="str"), + t1=dict(type="str"), + timespan=dict(type="float"), + resolution=dict(type="int"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_all(self, params): + new_object = {} + if params.get("networkId") is not None: + new_object["networkId"] = params.get( + "networkId") + if params.get("t0") is not None: + new_object["t0"] = params.get( + "t0") + if params.get("t1") is not None: + new_object["t1"] = params.get( + "t1") + if params.get("timespan") is not None: + new_object["timespan"] = params.get( + "timespan") + if params.get("resolution") is not None: + new_object["resolution"] = params.get( + "resolution") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="networks", + function='getNetworkClientsOverview', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_clients_policy.py b/ansible_collections/cisco/meraki/plugins/action/networks_clients_policy.py new file mode 100644 index 000000000..63c61f3c4 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_clients_policy.py @@ -0,0 +1,215 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or +# https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, + meraki_compare_equality, + get_dict_result, +) +from ansible_collections.cisco.meraki.plugins.plugin_utils.exceptions import ( + InconsistentParameters, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + state=dict(type="str", default="present", choices=["present"]), + devicePolicy=dict(type="str"), + groupPolicyId=dict(type="str"), + networkId=dict(type="str"), + clientId=dict(type="str"), +)) + +required_if = [ + ("state", "present", ["clientId", "networkId"], True), +] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class NetworksClientsPolicy(object): + def __init__(self, params, meraki): + self.meraki = meraki + self.new_object = dict( + devicePolicy=params.get("devicePolicy"), + groupPolicyId=params.get("groupPolicyId"), + network_id=params.get("networkId"), + client_id=params.get("clientId"), + ) + + def get_all_params(self, name=None, id=None): + new_object_params = {} + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + if self.new_object.get('clientId') is not None or self.new_object.get('client_id') is not None: + new_object_params['clientId'] = self.new_object.get('clientId') or \ + self.new_object.get('client_id') + return new_object_params + + def update_all_params(self): + new_object_params = {} + if self.new_object.get('devicePolicy') is not None or self.new_object.get('device_policy') is not None: + new_object_params['devicePolicy'] = self.new_object.get('devicePolicy') or \ + self.new_object.get('device_policy') + if self.new_object.get('groupPolicyId') is not None or self.new_object.get('group_policy_id') is not None: + new_object_params['groupPolicyId'] = self.new_object.get('groupPolicyId') or \ + self.new_object.get('group_policy_id') + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + if self.new_object.get('clientId') is not None or self.new_object.get('client_id') is not None: + new_object_params['clientId'] = self.new_object.get('clientId') or \ + self.new_object.get('client_id') + return new_object_params + + def get_object_by_name(self, name): + result = None + # NOTE: Does not have a get by name method, using get all + try: + items = self.meraki.exec_meraki( + family="networks", + function="getNetworkClientPolicy", + params=self.get_all_params(name=name), + ) + if isinstance(items, dict): + if 'response' in items: + items = items.get('response') + result = get_dict_result(items, 'name', name) + if result is None: + result = items + except Exception as e: + print("Error: ", e) + result = None + return result + + def get_object_by_id(self, id): + result = None + # NOTE: Does not have a get by id method or it is in another action + return result + + def exists(self): + prev_obj = None + id_exists = False + name_exists = False + o_id = self.new_object.get("networkId") or self.new_object.get("network_id") + name = self.new_object.get("name") + if o_id: + prev_obj = self.get_object_by_name(o_id) + id_exists = prev_obj is not None and isinstance(prev_obj, dict) + if not id_exists and name: + prev_obj = self.get_object_by_name(name) + name_exists = prev_obj is not None and isinstance(prev_obj, dict) + if name_exists: + _id = prev_obj.get("id") + if id_exists and name_exists and o_id != _id: + raise InconsistentParameters( + "The 'id' and 'name' params don't refer to the same object") + if _id: + self.new_object.update(dict(id=_id)) + it_exists = prev_obj is not None and isinstance(prev_obj, dict) + return (it_exists, prev_obj) + + def requires_update(self, current_obj): + requested_obj = self.new_object + + obj_params = [ + ("devicePolicy", "devicePolicy"), + ("groupPolicyId", "groupPolicyId"), + ("networkId", "networkId"), + ("clientId", "clientId"), + ] + # Method 1. Params present in request (Ansible) obj are the same as the current (ISE) params + # If any does not have eq params, it requires update + return any(not meraki_compare_equality(current_obj.get(meraki_param), + requested_obj.get(ansible_param)) + for (meraki_param, ansible_param) in obj_params) + + def update(self): + id = self.new_object.get("id") + name = self.new_object.get("name") + result = None + result = self.meraki.exec_meraki( + family="networks", + function="updateNetworkClientPolicy", + params=self.update_all_params(), + op_modifies=True, + ) + return result + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = False + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + meraki = MERAKI(self._task.args) + obj = NetworksClientsPolicy(self._task.args, meraki) + + state = self._task.args.get("state") + + response = None + if state == "present": + (obj_exists, prev_obj) = obj.exists() + if obj_exists: + if obj.requires_update(prev_obj): + response = obj.update() + meraki.object_updated() + else: + response = prev_obj + meraki.object_already_present() + else: + meraki.fail_json( + "Object does not exists, plugin only has update") + + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_clients_policy_info.py b/ansible_collections/cisco/meraki/plugins/action/networks_clients_policy_info.py new file mode 100644 index 000000000..209479c8d --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_clients_policy_info.py @@ -0,0 +1,94 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + networkId=dict(type="str"), + clientId=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_all(self, params): + new_object = {} + if params.get("networkId") is not None: + new_object["networkId"] = params.get( + "networkId") + if params.get("clientId") is not None: + new_object["clientId"] = params.get( + "clientId") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="networks", + function='getNetworkClientPolicy', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_clients_provision.py b/ansible_collections/cisco/meraki/plugins/action/networks_clients_provision.py new file mode 100644 index 000000000..3530895a4 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_clients_provision.py @@ -0,0 +1,97 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguements specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + clients=dict(type="list"), + devicePolicy=dict(type="str"), + groupPolicyId=dict(type="str"), + policiesBySecurityAppliance=dict(type="dict"), + policiesBySsid=dict(type="dict"), + networkId=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = False + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_object(self, params): + new_object = dict( + clients=params.get("clients"), + devicePolicy=params.get("devicePolicy"), + groupPolicyId=params.get("groupPolicyId"), + policiesBySecurityAppliance=params.get("policiesBySecurityAppliance"), + policiesBySsid=params.get("policiesBySsid"), + networkId=params.get("networkId"), + ) + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="networks", + function='provisionNetworkClients', + op_modifies=True, + params=self.get_object(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_clients_splash_authorization_status.py b/ansible_collections/cisco/meraki/plugins/action/networks_clients_splash_authorization_status.py new file mode 100644 index 000000000..7f11b91f8 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_clients_splash_authorization_status.py @@ -0,0 +1,209 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or +# https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, + meraki_compare_equality, + get_dict_result, +) +from ansible_collections.cisco.meraki.plugins.plugin_utils.exceptions import ( + InconsistentParameters, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + state=dict(type="str", default="present", choices=["present"]), + ssids=dict(type="dict"), + networkId=dict(type="str"), + clientId=dict(type="str"), +)) + +required_if = [ + ("state", "present", ["clientId", "networkId"], True), +] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class NetworksClientsSplashAuthorizationStatus(object): + def __init__(self, params, meraki): + self.meraki = meraki + self.new_object = dict( + ssids=params.get("ssids"), + network_id=params.get("networkId"), + client_id=params.get("clientId"), + ) + + def get_all_params(self, name=None, id=None): + new_object_params = {} + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + if self.new_object.get('clientId') is not None or self.new_object.get('client_id') is not None: + new_object_params['clientId'] = self.new_object.get('clientId') or \ + self.new_object.get('client_id') + return new_object_params + + def update_all_params(self): + new_object_params = {} + if self.new_object.get('ssids') is not None or self.new_object.get('ssids') is not None: + new_object_params['ssids'] = self.new_object.get('ssids') or \ + self.new_object.get('ssids') + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + if self.new_object.get('clientId') is not None or self.new_object.get('client_id') is not None: + new_object_params['clientId'] = self.new_object.get('clientId') or \ + self.new_object.get('client_id') + return new_object_params + + def get_object_by_name(self, name): + result = None + # NOTE: Does not have a get by name method, using get all + try: + items = self.meraki.exec_meraki( + family="networks", + function="getNetworkClientSplashAuthorizationStatus", + params=self.get_all_params(name=name), + ) + if isinstance(items, dict): + if 'response' in items: + items = items.get('response') + result = get_dict_result(items, 'name', name) + if result is None: + result = items + except Exception as e: + print("Error: ", e) + result = None + return result + + def get_object_by_id(self, id): + result = None + # NOTE: Does not have a get by id method or it is in another action + return result + + def exists(self): + prev_obj = None + id_exists = False + name_exists = False + o_id = self.new_object.get("networkId") or self.new_object.get("network_id") + name = self.new_object.get("name") + if o_id: + prev_obj = self.get_object_by_name(o_id) + id_exists = prev_obj is not None and isinstance(prev_obj, dict) + if not id_exists and name: + prev_obj = self.get_object_by_name(name) + name_exists = prev_obj is not None and isinstance(prev_obj, dict) + if name_exists: + _id = prev_obj.get("id") + if id_exists and name_exists and o_id != _id: + raise InconsistentParameters( + "The 'id' and 'name' params don't refer to the same object") + if _id: + self.new_object.update(dict(id=_id)) + it_exists = prev_obj is not None and isinstance(prev_obj, dict) + return (it_exists, prev_obj) + + def requires_update(self, current_obj): + requested_obj = self.new_object + + obj_params = [ + ("ssids", "ssids"), + ("networkId", "networkId"), + ("clientId", "clientId"), + ] + # Method 1. Params present in request (Ansible) obj are the same as the current (ISE) params + # If any does not have eq params, it requires update + return any(not meraki_compare_equality(current_obj.get(meraki_param), + requested_obj.get(ansible_param)) + for (meraki_param, ansible_param) in obj_params) + + def update(self): + id = self.new_object.get("id") + name = self.new_object.get("name") + result = None + result = self.meraki.exec_meraki( + family="networks", + function="updateNetworkClientSplashAuthorizationStatus", + params=self.update_all_params(), + op_modifies=True, + ) + return result + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = False + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + meraki = MERAKI(self._task.args) + obj = NetworksClientsSplashAuthorizationStatus(self._task.args, meraki) + + state = self._task.args.get("state") + + response = None + if state == "present": + (obj_exists, prev_obj) = obj.exists() + if obj_exists: + if obj.requires_update(prev_obj): + response = obj.update() + meraki.object_updated() + else: + response = prev_obj + meraki.object_already_present() + else: + meraki.fail_json( + "Object does not exists, plugin only has update") + + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_clients_splash_authorization_status_info.py b/ansible_collections/cisco/meraki/plugins/action/networks_clients_splash_authorization_status_info.py new file mode 100644 index 000000000..694a44dec --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_clients_splash_authorization_status_info.py @@ -0,0 +1,94 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + networkId=dict(type="str"), + clientId=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_all(self, params): + new_object = {} + if params.get("networkId") is not None: + new_object["networkId"] = params.get( + "networkId") + if params.get("clientId") is not None: + new_object["clientId"] = params.get( + "clientId") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="networks", + function='getNetworkClientSplashAuthorizationStatus', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_devices_claim.py b/ansible_collections/cisco/meraki/plugins/action/networks_devices_claim.py new file mode 100644 index 000000000..315861ee6 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_devices_claim.py @@ -0,0 +1,89 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguements specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + serials=dict(type="list"), + networkId=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = False + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_object(self, params): + new_object = dict( + serials=params.get("serials"), + networkId=params.get("networkId"), + ) + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="networks", + function='claimNetworkDevices', + op_modifies=True, + params=self.get_object(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_devices_claim_vmx.py b/ansible_collections/cisco/meraki/plugins/action/networks_devices_claim_vmx.py new file mode 100644 index 000000000..583effdc5 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_devices_claim_vmx.py @@ -0,0 +1,89 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguements specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + size=dict(type="str"), + networkId=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = False + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_object(self, params): + new_object = dict( + size=params.get("size"), + networkId=params.get("networkId"), + ) + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="networks", + function='vmxNetworkDevicesClaim', + op_modifies=True, + params=self.get_object(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_devices_remove.py b/ansible_collections/cisco/meraki/plugins/action/networks_devices_remove.py new file mode 100644 index 000000000..8d0963da0 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_devices_remove.py @@ -0,0 +1,89 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguements specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + serial=dict(type="str"), + networkId=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = False + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_object(self, params): + new_object = dict( + serial=params.get("serial"), + networkId=params.get("networkId"), + ) + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="networks", + function='removeNetworkDevices', + op_modifies=True, + params=self.get_object(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_events_event_types_info.py b/ansible_collections/cisco/meraki/plugins/action/networks_events_event_types_info.py new file mode 100644 index 000000000..69b595927 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_events_event_types_info.py @@ -0,0 +1,90 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + networkId=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_all(self, params): + new_object = {} + if params.get("networkId") is not None: + new_object["networkId"] = params.get( + "networkId") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="networks", + function='getNetworkEventsEventTypes', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_events_info.py b/ansible_collections/cisco/meraki/plugins/action/networks_events_info.py new file mode 100644 index 000000000..edeb8010b --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_events_info.py @@ -0,0 +1,152 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + networkId=dict(type="str"), + productType=dict(type="str"), + includedEventTypes=dict(type="list"), + excludedEventTypes=dict(type="list"), + deviceMac=dict(type="str"), + deviceSerial=dict(type="str"), + deviceName=dict(type="str"), + clientIp=dict(type="str"), + clientMac=dict(type="str"), + clientName=dict(type="str"), + smDeviceMac=dict(type="str"), + smDeviceName=dict(type="str"), + perPage=dict(type="int"), + total_pages=dict(type="int"), + direction=dict(type="str"), + startingAfter=dict(type="str"), + endingBefore=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_all(self, params): + new_object = {} + if params.get("networkId") is not None: + new_object["networkId"] = params.get( + "networkId") + if params.get("productType") is not None: + new_object["productType"] = params.get( + "productType") + if params.get("includedEventTypes") is not None: + new_object["includedEventTypes"] = params.get( + "includedEventTypes") + if params.get("excludedEventTypes") is not None: + new_object["excludedEventTypes"] = params.get( + "excludedEventTypes") + if params.get("deviceMac") is not None: + new_object["deviceMac"] = params.get( + "deviceMac") + if params.get("deviceSerial") is not None: + new_object["deviceSerial"] = params.get( + "deviceSerial") + if params.get("deviceName") is not None: + new_object["deviceName"] = params.get( + "deviceName") + if params.get("clientIp") is not None: + new_object["clientIp"] = params.get( + "clientIp") + if params.get("clientMac") is not None: + new_object["clientMac"] = params.get( + "clientMac") + if params.get("clientName") is not None: + new_object["clientName"] = params.get( + "clientName") + if params.get("smDeviceMac") is not None: + new_object["smDeviceMac"] = params.get( + "smDeviceMac") + if params.get("smDeviceName") is not None: + new_object["smDeviceName"] = params.get( + "smDeviceName") + if params.get("perPage") is not None: + new_object["perPage"] = params.get( + "perPage") + new_object['total_pages'] = params.get( + "total_pages") or 1 + new_object['direction'] = params.get( + "direction") or "next" + if params.get("startingAfter") is not None: + new_object["startingAfter"] = params.get( + "startingAfter") + if params.get("endingBefore") is not None: + new_object["endingBefore"] = params.get( + "endingBefore") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="networks", + function='getNetworkEvents', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_firmware_upgrades.py b/ansible_collections/cisco/meraki/plugins/action/networks_firmware_upgrades.py new file mode 100644 index 000000000..d60217404 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_firmware_upgrades.py @@ -0,0 +1,212 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or +# https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, + meraki_compare_equality, + get_dict_result, +) +from ansible_collections.cisco.meraki.plugins.plugin_utils.exceptions import ( + InconsistentParameters, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + state=dict(type="str", default="present", choices=["present"]), + upgradeWindow=dict(type="dict"), + timezone=dict(type="str"), + products=dict(type="dict"), + networkId=dict(type="str"), +)) + +required_if = [ + ("state", "present", ["networkId"], True), +] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class NetworksFirmwareUpgrades(object): + def __init__(self, params, meraki): + self.meraki = meraki + self.new_object = dict( + upgradeWindow=params.get("upgradeWindow"), + timezone=params.get("timezone"), + products=params.get("products"), + network_id=params.get("networkId"), + ) + + def get_all_params(self, name=None, id=None): + new_object_params = {} + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + return new_object_params + + def update_all_params(self): + new_object_params = {} + if self.new_object.get('upgradeWindow') is not None or self.new_object.get('upgrade_window') is not None: + new_object_params['upgradeWindow'] = self.new_object.get('upgradeWindow') or \ + self.new_object.get('upgrade_window') + if self.new_object.get('timezone') is not None or self.new_object.get('timezone') is not None: + new_object_params['timezone'] = self.new_object.get('timezone') or \ + self.new_object.get('timezone') + if self.new_object.get('products') is not None or self.new_object.get('products') is not None: + new_object_params['products'] = self.new_object.get('products') or \ + self.new_object.get('products') + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + return new_object_params + + def get_object_by_name(self, name): + result = None + # NOTE: Does not have a get by name method, using get all + try: + items = self.meraki.exec_meraki( + family="networks", + function="getNetworkFirmwareUpgrades", + params=self.get_all_params(name=name), + ) + if isinstance(items, dict): + if 'response' in items: + items = items.get('response') + result = get_dict_result(items, 'name', name) + if result is None: + result = items + except Exception as e: + print("Error: ", e) + result = None + return result + + def get_object_by_id(self, id): + result = None + # NOTE: Does not have a get by id method or it is in another action + return result + + def exists(self): + prev_obj = None + id_exists = False + name_exists = False + o_id = self.new_object.get("networkId") or self.new_object.get("network_id") + name = self.new_object.get("name") + if o_id: + prev_obj = self.get_object_by_name(o_id) + id_exists = prev_obj is not None and isinstance(prev_obj, dict) + if not id_exists and name: + prev_obj = self.get_object_by_name(name) + name_exists = prev_obj is not None and isinstance(prev_obj, dict) + if name_exists: + _id = prev_obj.get("id") + if id_exists and name_exists and o_id != _id: + raise InconsistentParameters( + "The 'id' and 'name' params don't refer to the same object") + if _id: + self.new_object.update(dict(id=_id)) + it_exists = prev_obj is not None and isinstance(prev_obj, dict) + return (it_exists, prev_obj) + + def requires_update(self, current_obj): + requested_obj = self.new_object + + obj_params = [ + ("upgradeWindow", "upgradeWindow"), + ("timezone", "timezone"), + ("products", "products"), + ("networkId", "networkId"), + ] + # Method 1. Params present in request (Ansible) obj are the same as the current (ISE) params + # If any does not have eq params, it requires update + return any(not meraki_compare_equality(current_obj.get(meraki_param), + requested_obj.get(ansible_param)) + for (meraki_param, ansible_param) in obj_params) + + def update(self): + id = self.new_object.get("id") + name = self.new_object.get("name") + result = None + result = self.meraki.exec_meraki( + family="networks", + function="updateNetworkFirmwareUpgrades", + params=self.update_all_params(), + op_modifies=True, + ) + return result + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = False + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + meraki = MERAKI(self._task.args) + obj = NetworksFirmwareUpgrades(self._task.args, meraki) + + state = self._task.args.get("state") + + response = None + if state == "present": + (obj_exists, prev_obj) = obj.exists() + if obj_exists: + if obj.requires_update(prev_obj): + response = obj.update() + meraki.object_updated() + else: + response = prev_obj + meraki.object_already_present() + else: + meraki.fail_json( + "Object does not exists, plugin only has update") + + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_firmware_upgrades_info.py b/ansible_collections/cisco/meraki/plugins/action/networks_firmware_upgrades_info.py new file mode 100644 index 000000000..ddda3bddf --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_firmware_upgrades_info.py @@ -0,0 +1,90 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + networkId=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_all(self, params): + new_object = {} + if params.get("networkId") is not None: + new_object["networkId"] = params.get( + "networkId") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="networks", + function='getNetworkFirmwareUpgrades', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_firmware_upgrades_rollbacks.py b/ansible_collections/cisco/meraki/plugins/action/networks_firmware_upgrades_rollbacks.py new file mode 100644 index 000000000..02dd7a060 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_firmware_upgrades_rollbacks.py @@ -0,0 +1,95 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguements specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + product=dict(type="str"), + time=dict(type="str"), + reasons=dict(type="list"), + toVersion=dict(type="dict"), + networkId=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = False + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_object(self, params): + new_object = dict( + product=params.get("product"), + time=params.get("time"), + reasons=params.get("reasons"), + toVersion=params.get("toVersion"), + networkId=params.get("networkId"), + ) + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="networks", + function='createNetworkFirmwareUpgradesRollback', + op_modifies=True, + params=self.get_object(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_firmware_upgrades_staged_events.py b/ansible_collections/cisco/meraki/plugins/action/networks_firmware_upgrades_staged_events.py new file mode 100644 index 000000000..b6d1f45c1 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_firmware_upgrades_staged_events.py @@ -0,0 +1,225 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or +# https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, + meraki_compare_equality, + get_dict_result, +) +from ansible_collections.cisco.meraki.plugins.plugin_utils.exceptions import ( + InconsistentParameters, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + state=dict(type="str", default="present", choices=["present"]), + products=dict(type="dict"), + stages=dict(type="list"), + networkId=dict(type="str"), +)) + +required_if = [ + ("state", "present", ["networkId"], True), +] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class NetworksFirmwareUpgradesStagedEvents(object): + def __init__(self, params, meraki): + self.meraki = meraki + self.new_object = dict( + products=params.get("products"), + stages=params.get("stages"), + network_id=params.get("networkId"), + ) + + def get_all_params(self, name=None, id=None): + new_object_params = {} + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + return new_object_params + + def create_params(self): + new_object_params = {} + if self.new_object.get('products') is not None or self.new_object.get('products') is not None: + new_object_params['products'] = self.new_object.get('products') or \ + self.new_object.get('products') + if self.new_object.get('stages') is not None or self.new_object.get('stages') is not None: + new_object_params['stages'] = self.new_object.get('stages') or \ + self.new_object.get('stages') + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + return new_object_params + + def update_all_params(self): + new_object_params = {} + if self.new_object.get('stages') is not None or self.new_object.get('stages') is not None: + new_object_params['stages'] = self.new_object.get('stages') or \ + self.new_object.get('stages') + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + return new_object_params + + def get_object_by_name(self, name): + result = None + # NOTE: Does not have a get by name method, using get all + try: + items = self.meraki.exec_meraki( + family="networks", + function="getNetworkFirmwareUpgradesStagedEvents", + params=self.get_all_params(name=name), + ) + if isinstance(items, dict): + if 'response' in items: + items = items.get('response') + result = get_dict_result(items, 'name', name) + if result is None: + result = items + except Exception as e: + print("Error: ", e) + result = None + return result + + def get_object_by_id(self, id): + result = None + # NOTE: Does not have a get by id method or it is in another action + return result + + def exists(self): + prev_obj = None + id_exists = False + name_exists = False + o_id = self.new_object.get("networkId") or self.new_object.get("network_id") + name = self.new_object.get("name") + if o_id: + prev_obj = self.get_object_by_name(o_id) + id_exists = prev_obj is not None and isinstance(prev_obj, dict) + if not id_exists and name: + prev_obj = self.get_object_by_name(name) + name_exists = prev_obj is not None and isinstance(prev_obj, dict) + if name_exists: + _id = prev_obj.get("id") + if id_exists and name_exists and o_id != _id: + raise InconsistentParameters( + "The 'id' and 'name' params don't refer to the same object") + if _id: + self.new_object.update(dict(id=_id)) + it_exists = prev_obj is not None and isinstance(prev_obj, dict) + return (it_exists, prev_obj) + + def requires_update(self, current_obj): + requested_obj = self.new_object + + obj_params = [ + ("products", "products"), + ("stages", "stages"), + ("networkId", "networkId"), + ] + # Method 1. Params present in request (Ansible) obj are the same as the current (ISE) params + # If any does not have eq params, it requires update + return any(not meraki_compare_equality(current_obj.get(meraki_param), + requested_obj.get(ansible_param)) + for (meraki_param, ansible_param) in obj_params) + + def create(self): + result = self.meraki.exec_meraki( + family="networks", + function="createNetworkFirmwareUpgradesStagedEvent", + params=self.create_params(), + op_modifies=True, + ) + return result + + def update(self): + id = self.new_object.get("id") + name = self.new_object.get("name") + result = None + result = self.meraki.exec_meraki( + family="networks", + function="updateNetworkFirmwareUpgradesStagedEvents", + params=self.update_all_params(), + op_modifies=True, + ) + return result + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = False + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + meraki = MERAKI(self._task.args) + obj = NetworksFirmwareUpgradesStagedEvents(self._task.args, meraki) + + state = self._task.args.get("state") + + response = None + if state == "present": + (obj_exists, prev_obj) = obj.exists() + if obj_exists: + if obj.requires_update(prev_obj): + response = obj.update() + meraki.object_updated() + else: + response = prev_obj + meraki.object_already_present() + else: + response = obj.create() + meraki.object_created() + + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_firmware_upgrades_staged_events_defer.py b/ansible_collections/cisco/meraki/plugins/action/networks_firmware_upgrades_staged_events_defer.py new file mode 100644 index 000000000..db07326b4 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_firmware_upgrades_staged_events_defer.py @@ -0,0 +1,87 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguements specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + networkId=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = False + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_object(self, params): + new_object = dict( + network_id=params.get("networkId"), + ) + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="networks", + function='deferNetworkFirmwareUpgradesStagedEvents', + op_modifies=True, + params=self.get_object(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_firmware_upgrades_staged_events_info.py b/ansible_collections/cisco/meraki/plugins/action/networks_firmware_upgrades_staged_events_info.py new file mode 100644 index 000000000..eb9a93dcb --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_firmware_upgrades_staged_events_info.py @@ -0,0 +1,90 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + networkId=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_all(self, params): + new_object = {} + if params.get("networkId") is not None: + new_object["networkId"] = params.get( + "networkId") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="networks", + function='getNetworkFirmwareUpgradesStagedEvents', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_firmware_upgrades_staged_events_rollbacks.py b/ansible_collections/cisco/meraki/plugins/action/networks_firmware_upgrades_staged_events_rollbacks.py new file mode 100644 index 000000000..72ab2abcc --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_firmware_upgrades_staged_events_rollbacks.py @@ -0,0 +1,91 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguements specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + stages=dict(type="list"), + reasons=dict(type="list"), + networkId=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = False + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_object(self, params): + new_object = dict( + stages=params.get("stages"), + reasons=params.get("reasons"), + networkId=params.get("networkId"), + ) + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="networks", + function='rollbacksNetworkFirmwareUpgradesStagedEvents', + op_modifies=True, + params=self.get_object(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_firmware_upgrades_staged_groups.py b/ansible_collections/cisco/meraki/plugins/action/networks_firmware_upgrades_staged_groups.py new file mode 100644 index 000000000..ea0902e37 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_firmware_upgrades_staged_groups.py @@ -0,0 +1,327 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or +# https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, + meraki_compare_equality, + get_dict_result, +) +from ansible_collections.cisco.meraki.plugins.plugin_utils.exceptions import ( + InconsistentParameters, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + state=dict(type="str", default="present", choices=["present", "absent"]), + name=dict(type="str"), + description=dict(type="str"), + isDefault=dict(type="bool"), + assignedDevices=dict(type="dict"), + networkId=dict(type="str"), + groupId=dict(type="str"), +)) + +required_if = [ + ("state", "present", ["groupId", "name", "networkId"], True), + ("state", "absent", ["groupId", "name", "networkId"], True), +] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class NetworksFirmwareUpgradesStagedGroups(object): + def __init__(self, params, meraki): + self.meraki = meraki + self.new_object = dict( + name=params.get("name"), + description=params.get("description"), + isDefault=params.get("isDefault"), + assignedDevices=params.get("assignedDevices"), + networkId=params.get("networkId"), + groupId=params.get("groupId"), + ) + + def get_all_params(self, name=None, id=None): + new_object_params = {} + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + return new_object_params + + def get_params_by_id(self, name=None, id=None): + new_object_params = {} + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + if self.new_object.get('groupId') is not None or self.new_object.get('group_id') is not None: + new_object_params['groupId'] = self.new_object.get('groupId') or \ + self.new_object.get('group_id') + return new_object_params + + def create_params(self): + new_object_params = {} + if self.new_object.get('name') is not None or self.new_object.get('name') is not None: + new_object_params['name'] = self.new_object.get('name') or \ + self.new_object.get('name') + if self.new_object.get('description') is not None or self.new_object.get('description') is not None: + new_object_params['description'] = self.new_object.get('description') or \ + self.new_object.get('description') + if self.new_object.get('isDefault') is not None or self.new_object.get('is_default') is not None: + new_object_params['isDefault'] = self.new_object.get('isDefault') + if self.new_object.get('assignedDevices') is not None or self.new_object.get('assigned_devices') is not None: + new_object_params['assignedDevices'] = self.new_object.get('assignedDevices') or \ + self.new_object.get('assigned_devices') + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + return new_object_params + + def delete_by_id_params(self): + new_object_params = {} + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + if self.new_object.get('groupId') is not None or self.new_object.get('group_id') is not None: + new_object_params['groupId'] = self.new_object.get('groupId') or \ + self.new_object.get('group_id') + return new_object_params + + def update_by_id_params(self): + new_object_params = {} + if self.new_object.get('name') is not None or self.new_object.get('name') is not None: + new_object_params['name'] = self.new_object.get('name') or \ + self.new_object.get('name') + if self.new_object.get('description') is not None or self.new_object.get('description') is not None: + new_object_params['description'] = self.new_object.get('description') or \ + self.new_object.get('description') + if self.new_object.get('isDefault') is not None or self.new_object.get('is_default') is not None: + new_object_params['isDefault'] = self.new_object.get('isDefault') + if self.new_object.get('assignedDevices') is not None or self.new_object.get('assigned_devices') is not None: + new_object_params['assignedDevices'] = self.new_object.get('assignedDevices') or \ + self.new_object.get('assigned_devices') + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + if self.new_object.get('groupId') is not None or self.new_object.get('group_id') is not None: + new_object_params['groupId'] = self.new_object.get('groupId') or \ + self.new_object.get('group_id') + return new_object_params + + def get_object_by_name(self, name): + result = None + # NOTE: Does not have a get by name method or it is in another action + try: + items = self.meraki.exec_meraki( + family="networks", + function="getNetworkFirmwareUpgradesStagedGroups", + params=self.get_all_params(name=name), + ) + if isinstance(items, dict): + if 'response' in items: + items = items.get('response') + result = get_dict_result(items, 'name', name) + if result is None: + result = items + except Exception as e: + print("Error: ", e) + result = None + return result + + def get_object_by_id(self, id): + result = None + try: + items = self.meraki.exec_meraki( + family="networks", + function="getNetworkFirmwareUpgradesStagedGroup", + params=self.get_params_by_id() + ) + if isinstance(items, dict): + if 'response' in items: + items = items.get('response') + result = get_dict_result(items, 'groupId', id) + except Exception as e: + print("Error: ", e) + result = None + return result + + def exists(self): + id_exists = False + name_exists = False + prev_obj = None + o_id = self.new_object.get("id") + o_id = o_id or self.new_object.get( + "group_id") or self.new_object.get("groupId") + name = self.new_object.get("name") + if o_id: + prev_obj = self.get_object_by_id(o_id) + id_exists = prev_obj is not None and isinstance(prev_obj, dict) + if not id_exists and name: + prev_obj = self.get_object_by_name(name) + name_exists = prev_obj is not None and isinstance(prev_obj, dict) + if name_exists: + _id = prev_obj.get("id") + _id = _id or prev_obj.get("groupId") + if id_exists and name_exists and o_id != _id: + raise InconsistentParameters( + "The 'id' and 'name' params don't refer to the same object") + if _id: + self.new_object.update(dict(id=_id)) + self.new_object.update(dict(groupId=_id)) + if _id: + prev_obj = self.get_object_by_id(_id) + it_exists = prev_obj is not None and isinstance(prev_obj, dict) + return (it_exists, prev_obj) + + def requires_update(self, current_obj): + requested_obj = self.new_object + + obj_params = [ + ("name", "name"), + ("description", "description"), + ("isDefault", "isDefault"), + ("assignedDevices", "assignedDevices"), + ("networkId", "networkId"), + ("groupId", "groupId"), + ] + # Method 1. Params present in request (Ansible) obj are the same as the current (DNAC) params + # If any does not have eq params, it requires update + return any(not meraki_compare_equality(current_obj.get(meraki_param), + requested_obj.get(ansible_param)) + for (meraki_param, ansible_param) in obj_params) + + def create(self): + result = self.meraki.exec_meraki( + family="networks", + function="createNetworkFirmwareUpgradesStagedGroup", + params=self.create_params(), + op_modifies=True, + ) + return result + + def update(self): + id = self.new_object.get("id") + id = id or self.new_object.get("groupId") + name = self.new_object.get("name") + result = None + if not id: + prev_obj_name = self.get_object_by_name(name) + id_ = None + if prev_obj_name: + id_ = prev_obj_name.get("id") + id_ = id_ or prev_obj_name.get("groupId") + if id_: + self.new_object.update(dict(groupId=id_)) + result = self.meraki.exec_meraki( + family="networks", + function="updateNetworkFirmwareUpgradesStagedGroup", + params=self.update_by_id_params(), + op_modifies=True, + ) + return result + + def delete(self): + id = self.new_object.get("id") + id = id or self.new_object.get("groupId") + name = self.new_object.get("name") + result = None + if not id: + prev_obj_name = self.get_object_by_name(name) + id_ = None + if prev_obj_name: + id_ = prev_obj_name.get("id") + id_ = id_ or prev_obj_name.get("groupId") + if id_: + self.new_object.update(dict(groupId=id_)) + result = self.meraki.exec_meraki( + family="networks", + function="deleteNetworkFirmwareUpgradesStagedGroup", + params=self.delete_by_id_params(), + ) + return result + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = False + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + meraki = MERAKI(self._task.args) + obj = NetworksFirmwareUpgradesStagedGroups(self._task.args, meraki) + + state = self._task.args.get("state") + + response = None + + if state == "present": + (obj_exists, prev_obj) = obj.exists() + if obj_exists: + if obj.requires_update(prev_obj): + response = obj.update() + meraki.object_updated() + else: + response = prev_obj + meraki.object_already_present() + else: + response = obj.create() + meraki.object_created() + + elif state == "absent": + (obj_exists, prev_obj) = obj.exists() + if obj_exists: + response = obj.delete() + meraki.object_deleted() + else: + meraki.object_already_absent() + + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_firmware_upgrades_staged_groups_info.py b/ansible_collections/cisco/meraki/plugins/action/networks_firmware_upgrades_staged_groups_info.py new file mode 100644 index 000000000..1228ea383 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_firmware_upgrades_staged_groups_info.py @@ -0,0 +1,112 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + networkId=dict(type="str"), + groupId=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_object(self, params): + new_object = {} + if params.get("networkId") is not None: + new_object["networkId"] = params.get( + "networkId") + if params.get("groupId") is not None: + new_object["groupId"] = params.get( + "groupId") + return new_object + + def get_all(self, params): + new_object = {} + if params.get("networkId") is not None: + new_object["networkId"] = params.get( + "networkId") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + id = self._task.args.get("groupId") + if id: + response = meraki.exec_meraki( + family="networks", + function='getNetworkFirmwareUpgradesStagedGroup', + params=self.get_object(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result + if not id: + response = meraki.exec_meraki( + family="networks", + function='getNetworkFirmwareUpgradesStagedGroups', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_firmware_upgrades_staged_stages.py b/ansible_collections/cisco/meraki/plugins/action/networks_firmware_upgrades_staged_stages.py new file mode 100644 index 000000000..48f60959d --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_firmware_upgrades_staged_stages.py @@ -0,0 +1,200 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or +# https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, + meraki_compare_equality, + get_dict_result, +) +from ansible_collections.cisco.meraki.plugins.plugin_utils.exceptions import ( + InconsistentParameters, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + state=dict(type="str", default="present", choices=["present"]), + _json=dict(type="list"), + networkId=dict(type="str"), +)) + +required_if = [ + ("state", "present", ["networkId"], True), +] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class NetworksFirmwareUpgradesStagedStages(object): + def __init__(self, params, meraki): + self.meraki = meraki + self.new_object = dict( + _json=params.get("_json"), + network_id=params.get("networkId"), + ) + + def get_all_params(self, name=None, id=None): + new_object_params = {} + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + return new_object_params + + def update_all_params(self): + new_object_params = {} + if self.new_object.get('_json') is not None or self.new_object.get('_json') is not None: + new_object_params['_json'] = self.new_object.get('_json') or \ + self.new_object.get('_json') + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + return new_object_params + + def get_object_by_name(self, name): + result = None + # NOTE: Does not have a get by name method, using get all + try: + items = self.meraki.exec_meraki( + family="networks", + function="getNetworkFirmwareUpgradesStagedStages", + params=self.get_all_params(name=name), + ) + if isinstance(items, dict): + if 'response' in items: + items = items.get('response') + result = get_dict_result(items, 'name', name) + if result is None: + result = items + except Exception as e: + print("Error: ", e) + result = None + return result + + def get_object_by_id(self, id): + result = None + # NOTE: Does not have a get by id method or it is in another action + return result + + def exists(self): + prev_obj = None + id_exists = False + name_exists = False + o_id = self.new_object.get("networkId") or self.new_object.get("network_id") + name = self.new_object.get("name") + if o_id: + prev_obj = self.get_object_by_name(o_id) + id_exists = prev_obj is not None and isinstance(prev_obj, dict) + if not id_exists and name: + prev_obj = self.get_object_by_name(name) + name_exists = prev_obj is not None and isinstance(prev_obj, dict) + if name_exists: + _id = prev_obj.get("id") + if id_exists and name_exists and o_id != _id: + raise InconsistentParameters( + "The 'id' and 'name' params don't refer to the same object") + if _id: + self.new_object.update(dict(id=_id)) + it_exists = prev_obj is not None and isinstance(prev_obj, dict) + return (it_exists, prev_obj) + + def requires_update(self, current_obj): + requested_obj = self.new_object + + obj_params = [ + ("_json", "_json"), + ("networkId", "networkId"), + ] + # Method 1. Params present in request (Ansible) obj are the same as the current (ISE) params + # If any does not have eq params, it requires update + return any(not meraki_compare_equality(current_obj.get(meraki_param), + requested_obj.get(ansible_param)) + for (meraki_param, ansible_param) in obj_params) + + def update(self): + id = self.new_object.get("id") + name = self.new_object.get("name") + result = None + result = self.meraki.exec_meraki( + family="networks", + function="updateNetworkFirmwareUpgradesStagedStages", + params=self.update_all_params(), + op_modifies=True, + ) + return result + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = False + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + meraki = MERAKI(self._task.args) + obj = NetworksFirmwareUpgradesStagedStages(self._task.args, meraki) + + state = self._task.args.get("state") + + response = None + if state == "present": + (obj_exists, prev_obj) = obj.exists() + if obj_exists: + if obj.requires_update(prev_obj): + response = obj.update() + meraki.object_updated() + else: + response = prev_obj + meraki.object_already_present() + else: + meraki.fail_json( + "Object does not exists, plugin only has update") + + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_firmware_upgrades_staged_stages_info.py b/ansible_collections/cisco/meraki/plugins/action/networks_firmware_upgrades_staged_stages_info.py new file mode 100644 index 000000000..117db067c --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_firmware_upgrades_staged_stages_info.py @@ -0,0 +1,90 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + networkId=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_all(self, params): + new_object = {} + if params.get("networkId") is not None: + new_object["networkId"] = params.get( + "networkId") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="networks", + function='getNetworkFirmwareUpgradesStagedStages', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_floor_plans.py b/ansible_collections/cisco/meraki/plugins/action/networks_floor_plans.py new file mode 100644 index 000000000..0e1a40eec --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_floor_plans.py @@ -0,0 +1,356 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or +# https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, + meraki_compare_equality, + get_dict_result, +) +from ansible_collections.cisco.meraki.plugins.plugin_utils.exceptions import ( + InconsistentParameters, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + state=dict(type="str", default="present", choices=["present", "absent"]), + name=dict(type="str"), + center=dict(type="dict"), + bottomLeftCorner=dict(type="dict"), + bottomRightCorner=dict(type="dict"), + topLeftCorner=dict(type="dict"), + topRightCorner=dict(type="dict"), + imageContents=dict(type="str"), + networkId=dict(type="str"), + floorPlanId=dict(type="str"), +)) + +required_if = [ + ("state", "present", ["floorPlanId", "name", "networkId"], True), + ("state", "absent", ["floorPlanId", "name", "networkId"], True), +] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class NetworksFloorPlans(object): + def __init__(self, params, meraki): + self.meraki = meraki + self.new_object = dict( + name=params.get("name"), + center=params.get("center"), + bottomLeftCorner=params.get("bottomLeftCorner"), + bottomRightCorner=params.get("bottomRightCorner"), + topLeftCorner=params.get("topLeftCorner"), + topRightCorner=params.get("topRightCorner"), + imageContents=params.get("imageContents"), + networkId=params.get("networkId"), + floorPlanId=params.get("floorPlanId"), + ) + + def get_all_params(self, name=None, id=None): + new_object_params = {} + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + return new_object_params + + def get_params_by_id(self, name=None, id=None): + new_object_params = {} + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + if self.new_object.get('floorPlanId') is not None or self.new_object.get('floor_plan_id') is not None: + new_object_params['floorPlanId'] = self.new_object.get('floorPlanId') or \ + self.new_object.get('floor_plan_id') + return new_object_params + + def create_params(self): + new_object_params = {} + if self.new_object.get('name') is not None or self.new_object.get('name') is not None: + new_object_params['name'] = self.new_object.get('name') or \ + self.new_object.get('name') + if self.new_object.get('center') is not None or self.new_object.get('center') is not None: + new_object_params['center'] = self.new_object.get('center') or \ + self.new_object.get('center') + if self.new_object.get('bottomLeftCorner') is not None or self.new_object.get('bottom_left_corner') is not None: + new_object_params['bottomLeftCorner'] = self.new_object.get('bottomLeftCorner') or \ + self.new_object.get('bottom_left_corner') + if self.new_object.get('bottomRightCorner') is not None or self.new_object.get('bottom_right_corner') is not None: + new_object_params['bottomRightCorner'] = self.new_object.get('bottomRightCorner') or \ + self.new_object.get('bottom_right_corner') + if self.new_object.get('topLeftCorner') is not None or self.new_object.get('top_left_corner') is not None: + new_object_params['topLeftCorner'] = self.new_object.get('topLeftCorner') or \ + self.new_object.get('top_left_corner') + if self.new_object.get('topRightCorner') is not None or self.new_object.get('top_right_corner') is not None: + new_object_params['topRightCorner'] = self.new_object.get('topRightCorner') or \ + self.new_object.get('top_right_corner') + if self.new_object.get('imageContents') is not None or self.new_object.get('image_contents') is not None: + new_object_params['imageContents'] = self.new_object.get('imageContents') or \ + self.new_object.get('image_contents') + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + return new_object_params + + def delete_by_id_params(self): + new_object_params = {} + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + if self.new_object.get('floorPlanId') is not None or self.new_object.get('floor_plan_id') is not None: + new_object_params['floorPlanId'] = self.new_object.get('floorPlanId') or \ + self.new_object.get('floor_plan_id') + return new_object_params + + def update_by_id_params(self): + new_object_params = {} + if self.new_object.get('name') is not None or self.new_object.get('name') is not None: + new_object_params['name'] = self.new_object.get('name') or \ + self.new_object.get('name') + if self.new_object.get('center') is not None or self.new_object.get('center') is not None: + new_object_params['center'] = self.new_object.get('center') or \ + self.new_object.get('center') + if self.new_object.get('bottomLeftCorner') is not None or self.new_object.get('bottom_left_corner') is not None: + new_object_params['bottomLeftCorner'] = self.new_object.get('bottomLeftCorner') or \ + self.new_object.get('bottom_left_corner') + if self.new_object.get('bottomRightCorner') is not None or self.new_object.get('bottom_right_corner') is not None: + new_object_params['bottomRightCorner'] = self.new_object.get('bottomRightCorner') or \ + self.new_object.get('bottom_right_corner') + if self.new_object.get('topLeftCorner') is not None or self.new_object.get('top_left_corner') is not None: + new_object_params['topLeftCorner'] = self.new_object.get('topLeftCorner') or \ + self.new_object.get('top_left_corner') + if self.new_object.get('topRightCorner') is not None or self.new_object.get('top_right_corner') is not None: + new_object_params['topRightCorner'] = self.new_object.get('topRightCorner') or \ + self.new_object.get('top_right_corner') + if self.new_object.get('imageContents') is not None or self.new_object.get('image_contents') is not None: + new_object_params['imageContents'] = self.new_object.get('imageContents') or \ + self.new_object.get('image_contents') + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + if self.new_object.get('floorPlanId') is not None or self.new_object.get('floor_plan_id') is not None: + new_object_params['floorPlanId'] = self.new_object.get('floorPlanId') or \ + self.new_object.get('floor_plan_id') + return new_object_params + + def get_object_by_name(self, name): + result = None + # NOTE: Does not have a get by name method or it is in another action + try: + items = self.meraki.exec_meraki( + family="networks", + function="getNetworkFloorPlans", + params=self.get_all_params(name=name), + ) + if isinstance(items, dict): + if 'response' in items: + items = items.get('response') + result = get_dict_result(items, 'name', name) + if result is None: + result = items + except Exception as e: + print("Error: ", e) + result = None + return result + + def get_object_by_id(self, id): + result = None + try: + items = self.meraki.exec_meraki( + family="networks", + function="getNetworkFloorPlan", + params=self.get_params_by_id() + ) + if isinstance(items, dict): + if 'response' in items: + items = items.get('response') + result = get_dict_result(items, 'floorPlanId', id) + except Exception as e: + print("Error: ", e) + result = None + return result + + def exists(self): + id_exists = False + name_exists = False + prev_obj = None + o_id = self.new_object.get("id") + o_id = o_id or self.new_object.get( + "floor_plan_id") or self.new_object.get("floorPlanId") + name = self.new_object.get("name") + if o_id: + prev_obj = self.get_object_by_id(o_id) + id_exists = prev_obj is not None and isinstance(prev_obj, dict) + if not id_exists and name: + prev_obj = self.get_object_by_name(name) + name_exists = prev_obj is not None and isinstance(prev_obj, dict) + if name_exists: + _id = prev_obj.get("id") + _id = _id or prev_obj.get("floorPlanId") + if id_exists and name_exists and o_id != _id: + raise InconsistentParameters( + "The 'id' and 'name' params don't refer to the same object") + if _id: + self.new_object.update(dict(id=_id)) + self.new_object.update(dict(floorPlanId=_id)) + if _id: + prev_obj = self.get_object_by_id(_id) + it_exists = prev_obj is not None and isinstance(prev_obj, dict) + return (it_exists, prev_obj) + + def requires_update(self, current_obj): + requested_obj = self.new_object + + obj_params = [ + ("name", "name"), + ("center", "center"), + ("bottomLeftCorner", "bottomLeftCorner"), + ("bottomRightCorner", "bottomRightCorner"), + ("topLeftCorner", "topLeftCorner"), + ("topRightCorner", "topRightCorner"), + ("imageContents", "imageContents"), + ("networkId", "networkId"), + ("floorPlanId", "floorPlanId"), + ] + # Method 1. Params present in request (Ansible) obj are the same as the current (DNAC) params + # If any does not have eq params, it requires update + return any(not meraki_compare_equality(current_obj.get(meraki_param), + requested_obj.get(ansible_param)) + for (meraki_param, ansible_param) in obj_params) + + def create(self): + result = self.meraki.exec_meraki( + family="networks", + function="createNetworkFloorPlan", + params=self.create_params(), + op_modifies=True, + ) + return result + + def update(self): + id = self.new_object.get("id") + id = id or self.new_object.get("floorPlanId") + name = self.new_object.get("name") + result = None + if not id: + prev_obj_name = self.get_object_by_name(name) + id_ = None + if prev_obj_name: + id_ = prev_obj_name.get("id") + id_ = id_ or prev_obj_name.get("floorPlanId") + if id_: + self.new_object.update(dict(floorPlanId=id_)) + result = self.meraki.exec_meraki( + family="networks", + function="updateNetworkFloorPlan", + params=self.update_by_id_params(), + op_modifies=True, + ) + return result + + def delete(self): + id = self.new_object.get("id") + id = id or self.new_object.get("floorPlanId") + name = self.new_object.get("name") + result = None + if not id: + prev_obj_name = self.get_object_by_name(name) + id_ = None + if prev_obj_name: + id_ = prev_obj_name.get("id") + id_ = id_ or prev_obj_name.get("floorPlanId") + if id_: + self.new_object.update(dict(floorPlanId=id_)) + result = self.meraki.exec_meraki( + family="networks", + function="deleteNetworkFloorPlan", + params=self.delete_by_id_params(), + ) + return result + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = False + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + meraki = MERAKI(self._task.args) + obj = NetworksFloorPlans(self._task.args, meraki) + + state = self._task.args.get("state") + + response = None + + if state == "present": + (obj_exists, prev_obj) = obj.exists() + if obj_exists: + if obj.requires_update(prev_obj): + response = obj.update() + meraki.object_updated() + else: + response = prev_obj + meraki.object_already_present() + else: + response = obj.create() + meraki.object_created() + + elif state == "absent": + (obj_exists, prev_obj) = obj.exists() + if obj_exists: + response = obj.delete() + meraki.object_deleted() + else: + meraki.object_already_absent() + + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_floor_plans_info.py b/ansible_collections/cisco/meraki/plugins/action/networks_floor_plans_info.py new file mode 100644 index 000000000..2628e51e4 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_floor_plans_info.py @@ -0,0 +1,112 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + networkId=dict(type="str"), + floorPlanId=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_object(self, params): + new_object = {} + if params.get("networkId") is not None: + new_object["networkId"] = params.get( + "networkId") + if params.get("floorPlanId") is not None: + new_object["floorPlanId"] = params.get( + "floorPlanId") + return new_object + + def get_all(self, params): + new_object = {} + if params.get("networkId") is not None: + new_object["networkId"] = params.get( + "networkId") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + id = self._task.args.get("floorPlanId") + if id: + response = meraki.exec_meraki( + family="networks", + function='getNetworkFloorPlan', + params=self.get_object(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result + if not id: + response = meraki.exec_meraki( + family="networks", + function='getNetworkFloorPlans', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_group_policies.py b/ansible_collections/cisco/meraki/plugins/action/networks_group_policies.py new file mode 100644 index 000000000..c8f41fc81 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_group_policies.py @@ -0,0 +1,365 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or +# https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, + meraki_compare_equality, + get_dict_result, +) +from ansible_collections.cisco.meraki.plugins.plugin_utils.exceptions import ( + InconsistentParameters, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + state=dict(type="str", default="present", choices=["present", "absent"]), + name=dict(type="str"), + scheduling=dict(type="dict"), + bandwidth=dict(type="dict"), + firewallAndTrafficShaping=dict(type="dict"), + contentFiltering=dict(type="dict"), + splashAuthSettings=dict(type="str"), + vlanTagging=dict(type="dict"), + bonjourForwarding=dict(type="dict"), + networkId=dict(type="str"), + groupPolicyId=dict(type="str"), +)) + +required_if = [ + ("state", "present", ["groupPolicyId", "name", "networkId"], True), + ("state", "absent", ["groupPolicyId", "name", "networkId"], True), +] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class NetworksGroupPolicies(object): + def __init__(self, params, meraki): + self.meraki = meraki + self.new_object = dict( + name=params.get("name"), + scheduling=params.get("scheduling"), + bandwidth=params.get("bandwidth"), + firewallAndTrafficShaping=params.get("firewallAndTrafficShaping"), + contentFiltering=params.get("contentFiltering"), + splashAuthSettings=params.get("splashAuthSettings"), + vlanTagging=params.get("vlanTagging"), + bonjourForwarding=params.get("bonjourForwarding"), + networkId=params.get("networkId"), + groupPolicyId=params.get("groupPolicyId"), + ) + + def get_all_params(self, name=None, id=None): + new_object_params = {} + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + return new_object_params + + def get_params_by_id(self, name=None, id=None): + new_object_params = {} + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + if self.new_object.get('groupPolicyId') is not None or self.new_object.get('group_policy_id') is not None: + new_object_params['groupPolicyId'] = self.new_object.get('groupPolicyId') or \ + self.new_object.get('group_policy_id') + return new_object_params + + def create_params(self): + new_object_params = {} + if self.new_object.get('name') is not None or self.new_object.get('name') is not None: + new_object_params['name'] = self.new_object.get('name') or \ + self.new_object.get('name') + if self.new_object.get('scheduling') is not None or self.new_object.get('scheduling') is not None: + new_object_params['scheduling'] = self.new_object.get('scheduling') or \ + self.new_object.get('scheduling') + if self.new_object.get('bandwidth') is not None or self.new_object.get('bandwidth') is not None: + new_object_params['bandwidth'] = self.new_object.get('bandwidth') or \ + self.new_object.get('bandwidth') + if self.new_object.get('firewallAndTrafficShaping') is not None or self.new_object.get('firewall_and_traffic_shaping') is not None: + new_object_params['firewallAndTrafficShaping'] = self.new_object.get('firewallAndTrafficShaping') or \ + self.new_object.get('firewall_and_traffic_shaping') + if self.new_object.get('contentFiltering') is not None or self.new_object.get('content_filtering') is not None: + new_object_params['contentFiltering'] = self.new_object.get('contentFiltering') or \ + self.new_object.get('content_filtering') + if self.new_object.get('splashAuthSettings') is not None or self.new_object.get('splash_auth_settings') is not None: + new_object_params['splashAuthSettings'] = self.new_object.get('splashAuthSettings') or \ + self.new_object.get('splash_auth_settings') + if self.new_object.get('vlanTagging') is not None or self.new_object.get('vlan_tagging') is not None: + new_object_params['vlanTagging'] = self.new_object.get('vlanTagging') or \ + self.new_object.get('vlan_tagging') + if self.new_object.get('bonjourForwarding') is not None or self.new_object.get('bonjour_forwarding') is not None: + new_object_params['bonjourForwarding'] = self.new_object.get('bonjourForwarding') or \ + self.new_object.get('bonjour_forwarding') + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + return new_object_params + + def delete_by_id_params(self): + new_object_params = {} + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + if self.new_object.get('groupPolicyId') is not None or self.new_object.get('group_policy_id') is not None: + new_object_params['groupPolicyId'] = self.new_object.get('groupPolicyId') or \ + self.new_object.get('group_policy_id') + return new_object_params + + def update_by_id_params(self): + new_object_params = {} + if self.new_object.get('name') is not None or self.new_object.get('name') is not None: + new_object_params['name'] = self.new_object.get('name') or \ + self.new_object.get('name') + if self.new_object.get('scheduling') is not None or self.new_object.get('scheduling') is not None: + new_object_params['scheduling'] = self.new_object.get('scheduling') or \ + self.new_object.get('scheduling') + if self.new_object.get('bandwidth') is not None or self.new_object.get('bandwidth') is not None: + new_object_params['bandwidth'] = self.new_object.get('bandwidth') or \ + self.new_object.get('bandwidth') + if self.new_object.get('firewallAndTrafficShaping') is not None or self.new_object.get('firewall_and_traffic_shaping') is not None: + new_object_params['firewallAndTrafficShaping'] = self.new_object.get('firewallAndTrafficShaping') or \ + self.new_object.get('firewall_and_traffic_shaping') + if self.new_object.get('contentFiltering') is not None or self.new_object.get('content_filtering') is not None: + new_object_params['contentFiltering'] = self.new_object.get('contentFiltering') or \ + self.new_object.get('content_filtering') + if self.new_object.get('splashAuthSettings') is not None or self.new_object.get('splash_auth_settings') is not None: + new_object_params['splashAuthSettings'] = self.new_object.get('splashAuthSettings') or \ + self.new_object.get('splash_auth_settings') + if self.new_object.get('vlanTagging') is not None or self.new_object.get('vlan_tagging') is not None: + new_object_params['vlanTagging'] = self.new_object.get('vlanTagging') or \ + self.new_object.get('vlan_tagging') + if self.new_object.get('bonjourForwarding') is not None or self.new_object.get('bonjour_forwarding') is not None: + new_object_params['bonjourForwarding'] = self.new_object.get('bonjourForwarding') or \ + self.new_object.get('bonjour_forwarding') + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + if self.new_object.get('groupPolicyId') is not None or self.new_object.get('group_policy_id') is not None: + new_object_params['groupPolicyId'] = self.new_object.get('groupPolicyId') or \ + self.new_object.get('group_policy_id') + return new_object_params + + def get_object_by_name(self, name): + result = None + # NOTE: Does not have a get by name method or it is in another action + try: + items = self.meraki.exec_meraki( + family="networks", + function="getNetworkGroupPolicies", + params=self.get_all_params(name=name), + ) + if isinstance(items, dict): + if 'response' in items: + items = items.get('response') + result = get_dict_result(items, 'name', name) + if result is None: + result = items + except Exception as e: + print("Error: ", e) + result = None + return result + + def get_object_by_id(self, id): + result = None + try: + items = self.meraki.exec_meraki( + family="networks", + function="getNetworkGroupPolicy", + params=self.get_params_by_id() + ) + if isinstance(items, dict): + if 'response' in items: + items = items.get('response') + result = get_dict_result(items, 'groupPolicyId', id) + except Exception as e: + print("Error: ", e) + result = None + return result + + def exists(self): + id_exists = False + name_exists = False + prev_obj = None + o_id = self.new_object.get("id") + o_id = o_id or self.new_object.get( + "group_policy_id") or self.new_object.get("groupPolicyId") + name = self.new_object.get("name") + if o_id: + prev_obj = self.get_object_by_id(o_id) + id_exists = prev_obj is not None and isinstance(prev_obj, dict) + if not id_exists and name: + prev_obj = self.get_object_by_name(name) + name_exists = prev_obj is not None and isinstance(prev_obj, dict) + if name_exists: + _id = prev_obj.get("id") + _id = _id or prev_obj.get("groupPolicyId") + if id_exists and name_exists and o_id != _id: + raise InconsistentParameters( + "The 'id' and 'name' params don't refer to the same object") + if _id: + self.new_object.update(dict(id=_id)) + self.new_object.update(dict(groupPolicyId=_id)) + if _id: + prev_obj = self.get_object_by_id(_id) + it_exists = prev_obj is not None and isinstance(prev_obj, dict) + return (it_exists, prev_obj) + + def requires_update(self, current_obj): + requested_obj = self.new_object + + obj_params = [ + ("name", "name"), + ("scheduling", "scheduling"), + ("bandwidth", "bandwidth"), + ("firewallAndTrafficShaping", "firewallAndTrafficShaping"), + ("contentFiltering", "contentFiltering"), + ("splashAuthSettings", "splashAuthSettings"), + ("vlanTagging", "vlanTagging"), + ("bonjourForwarding", "bonjourForwarding"), + ("networkId", "networkId"), + ("groupPolicyId", "groupPolicyId"), + ] + # Method 1. Params present in request (Ansible) obj are the same as the current (DNAC) params + # If any does not have eq params, it requires update + return any(not meraki_compare_equality(current_obj.get(meraki_param), + requested_obj.get(ansible_param)) + for (meraki_param, ansible_param) in obj_params) + + def create(self): + result = self.meraki.exec_meraki( + family="networks", + function="createNetworkGroupPolicy", + params=self.create_params(), + op_modifies=True, + ) + return result + + def update(self): + id = self.new_object.get("id") + id = id or self.new_object.get("groupPolicyId") + name = self.new_object.get("name") + result = None + if not id: + prev_obj_name = self.get_object_by_name(name) + id_ = None + if prev_obj_name: + id_ = prev_obj_name.get("id") + id_ = id_ or prev_obj_name.get("groupPolicyId") + if id_: + self.new_object.update(dict(groupPolicyId=id_)) + result = self.meraki.exec_meraki( + family="networks", + function="updateNetworkGroupPolicy", + params=self.update_by_id_params(), + op_modifies=True, + ) + return result + + def delete(self): + id = self.new_object.get("id") + id = id or self.new_object.get("groupPolicyId") + name = self.new_object.get("name") + result = None + if not id: + prev_obj_name = self.get_object_by_name(name) + id_ = None + if prev_obj_name: + id_ = prev_obj_name.get("id") + id_ = id_ or prev_obj_name.get("groupPolicyId") + if id_: + self.new_object.update(dict(groupPolicyId=id_)) + result = self.meraki.exec_meraki( + family="networks", + function="deleteNetworkGroupPolicy", + params=self.delete_by_id_params(), + ) + return result + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = False + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + meraki = MERAKI(self._task.args) + obj = NetworksGroupPolicies(self._task.args, meraki) + + state = self._task.args.get("state") + + response = None + + if state == "present": + (obj_exists, prev_obj) = obj.exists() + if obj_exists: + if obj.requires_update(prev_obj): + response = obj.update() + meraki.object_updated() + else: + response = prev_obj + meraki.object_already_present() + else: + response = obj.create() + meraki.object_created() + + elif state == "absent": + (obj_exists, prev_obj) = obj.exists() + if obj_exists: + response = obj.delete() + meraki.object_deleted() + else: + meraki.object_already_absent() + + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_group_policies_info.py b/ansible_collections/cisco/meraki/plugins/action/networks_group_policies_info.py new file mode 100644 index 000000000..0d2117107 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_group_policies_info.py @@ -0,0 +1,112 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + networkId=dict(type="str"), + groupPolicyId=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_object(self, params): + new_object = {} + if params.get("networkId") is not None: + new_object["networkId"] = params.get( + "networkId") + if params.get("groupPolicyId") is not None: + new_object["groupPolicyId"] = params.get( + "groupPolicyId") + return new_object + + def get_all(self, params): + new_object = {} + if params.get("networkId") is not None: + new_object["networkId"] = params.get( + "networkId") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + id = self._task.args.get("groupPolicyId") + if id: + response = meraki.exec_meraki( + family="networks", + function='getNetworkGroupPolicy', + params=self.get_object(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result + if not id: + response = meraki.exec_meraki( + family="networks", + function='getNetworkGroupPolicies', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_health_alerts_info.py b/ansible_collections/cisco/meraki/plugins/action/networks_health_alerts_info.py new file mode 100644 index 000000000..9137b2612 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_health_alerts_info.py @@ -0,0 +1,90 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + networkId=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_all(self, params): + new_object = {} + if params.get("networkId") is not None: + new_object["networkId"] = params.get( + "networkId") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="networks", + function='getNetworkHealthAlerts', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_info.py b/ansible_collections/cisco/meraki/plugins/action/networks_info.py new file mode 100644 index 000000000..091ed9e65 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_info.py @@ -0,0 +1,143 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + networkId=dict(type="str"), + organizationId=dict(type="str"), + configTemplateId=dict(type="str"), + isBoundToConfigTemplate=dict(type="bool"), + tags=dict(type="list"), + tagsFilterType=dict(type="str"), + perPage=dict(type="int"), + total_pages=dict(type="int"), + direction=dict(type="str"), + startingAfter=dict(type="str"), + endingBefore=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_object(self, params): + new_object = {} + if params.get("networkId") is not None: + new_object["networkId"] = params.get( + "networkId") + return new_object + + def get_all(self, params): + new_object = {} + if params.get("organizationId") is not None: + new_object["organizationId"] = params.get( + "organizationId") + if params.get("configTemplateId") is not None: + new_object["configTemplateId"] = params.get( + "configTemplateId") + if params.get("isBoundToConfigTemplate") is not None: + new_object["isBoundToConfigTemplate"] = params.get( + "isBoundToConfigTemplate") + if params.get("tags") is not None: + new_object["tags"] = params.get( + "tags") + if params.get("tagsFilterType") is not None: + new_object["tagsFilterType"] = params.get( + "tagsFilterType") + if params.get("perPage") is not None: + new_object["perPage"] = params.get( + "perPage") + new_object['total_pages'] = params.get( + "total_pages") or 1 + new_object['direction'] = params.get( + "direction") or "next" + if params.get("startingAfter") is not None: + new_object["startingAfter"] = params.get( + "startingAfter") + if params.get("endingBefore") is not None: + new_object["endingBefore"] = params.get( + "endingBefore") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + id = self._task.args.get("networkId") + if id: + response = meraki.exec_meraki( + family="networks", + function='getNetwork', + params=self.get_object(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result + if not id: + response = meraki.exec_meraki( + family="organizations", + function='getOrganizationNetworks', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_insight_applications_health_by_time_info.py b/ansible_collections/cisco/meraki/plugins/action/networks_insight_applications_health_by_time_info.py new file mode 100644 index 000000000..e9f9e3e61 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_insight_applications_health_by_time_info.py @@ -0,0 +1,110 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + networkId=dict(type="str"), + applicationId=dict(type="str"), + t0=dict(type="str"), + t1=dict(type="str"), + timespan=dict(type="float"), + resolution=dict(type="int"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_all(self, params): + new_object = {} + if params.get("networkId") is not None: + new_object["networkId"] = params.get( + "networkId") + if params.get("applicationId") is not None: + new_object["applicationId"] = params.get( + "applicationId") + if params.get("t0") is not None: + new_object["t0"] = params.get( + "t0") + if params.get("t1") is not None: + new_object["t1"] = params.get( + "t1") + if params.get("timespan") is not None: + new_object["timespan"] = params.get( + "timespan") + if params.get("resolution") is not None: + new_object["resolution"] = params.get( + "resolution") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="insight", + function='getNetworkInsightApplicationHealthByTime', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_meraki_auth_users.py b/ansible_collections/cisco/meraki/plugins/action/networks_meraki_auth_users.py new file mode 100644 index 000000000..56787c4fd --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_meraki_auth_users.py @@ -0,0 +1,343 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or +# https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, + meraki_compare_equality, + get_dict_result, +) +from ansible_collections.cisco.meraki.plugins.plugin_utils.exceptions import ( + InconsistentParameters, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + state=dict(type="str", default="present", choices=["present", "absent"]), + email=dict(type="str"), + name=dict(type="str"), + password=dict(type="str"), + accountType=dict(type="str"), + emailPasswordToUser=dict(type="bool"), + isAdmin=dict(type="bool"), + authorizations=dict(type="list"), + networkId=dict(type="str"), + merakiAuthUserId=dict(type="str"), +)) + +required_if = [ + ("state", "present", ["merakiAuthUserId", "name", "networkId"], True), + ("state", "absent", ["merakiAuthUserId", "name", "networkId"], True), +] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class NetworksMerakiAuthUsers(object): + def __init__(self, params, meraki): + self.meraki = meraki + self.new_object = dict( + email=params.get("email"), + name=params.get("name"), + password=params.get("password"), + accountType=params.get("accountType"), + emailPasswordToUser=params.get("emailPasswordToUser"), + isAdmin=params.get("isAdmin"), + authorizations=params.get("authorizations"), + networkId=params.get("networkId"), + merakiAuthUserId=params.get("merakiAuthUserId"), + ) + + def get_all_params(self, name=None, id=None): + new_object_params = {} + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + return new_object_params + + def get_params_by_id(self, name=None, id=None): + new_object_params = {} + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + if self.new_object.get('merakiAuthUserId') is not None or self.new_object.get('meraki_auth_user_id') is not None: + new_object_params['merakiAuthUserId'] = self.new_object.get('merakiAuthUserId') or \ + self.new_object.get('meraki_auth_user_id') + return new_object_params + + def create_params(self): + new_object_params = {} + if self.new_object.get('email') is not None or self.new_object.get('email') is not None: + new_object_params['email'] = self.new_object.get('email') or \ + self.new_object.get('email') + if self.new_object.get('name') is not None or self.new_object.get('name') is not None: + new_object_params['name'] = self.new_object.get('name') or \ + self.new_object.get('name') + if self.new_object.get('password') is not None or self.new_object.get('password') is not None: + new_object_params['password'] = self.new_object.get('password') or \ + self.new_object.get('password') + if self.new_object.get('accountType') is not None or self.new_object.get('account_type') is not None: + new_object_params['accountType'] = self.new_object.get('accountType') or \ + self.new_object.get('account_type') + if self.new_object.get('emailPasswordToUser') is not None or self.new_object.get('email_password_to_user') is not None: + new_object_params['emailPasswordToUser'] = self.new_object.get('emailPasswordToUser') + if self.new_object.get('isAdmin') is not None or self.new_object.get('is_admin') is not None: + new_object_params['isAdmin'] = self.new_object.get('isAdmin') + if self.new_object.get('authorizations') is not None or self.new_object.get('authorizations') is not None: + new_object_params['authorizations'] = self.new_object.get('authorizations') or \ + self.new_object.get('authorizations') + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + return new_object_params + + def delete_by_id_params(self): + new_object_params = {} + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + if self.new_object.get('merakiAuthUserId') is not None or self.new_object.get('meraki_auth_user_id') is not None: + new_object_params['merakiAuthUserId'] = self.new_object.get('merakiAuthUserId') or \ + self.new_object.get('meraki_auth_user_id') + return new_object_params + + def update_by_id_params(self): + new_object_params = {} + if self.new_object.get('name') is not None or self.new_object.get('name') is not None: + new_object_params['name'] = self.new_object.get('name') or \ + self.new_object.get('name') + if self.new_object.get('password') is not None or self.new_object.get('password') is not None: + new_object_params['password'] = self.new_object.get('password') or \ + self.new_object.get('password') + if self.new_object.get('emailPasswordToUser') is not None or self.new_object.get('email_password_to_user') is not None: + new_object_params['emailPasswordToUser'] = self.new_object.get('emailPasswordToUser') + if self.new_object.get('authorizations') is not None or self.new_object.get('authorizations') is not None: + new_object_params['authorizations'] = self.new_object.get('authorizations') or \ + self.new_object.get('authorizations') + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + if self.new_object.get('merakiAuthUserId') is not None or self.new_object.get('meraki_auth_user_id') is not None: + new_object_params['merakiAuthUserId'] = self.new_object.get('merakiAuthUserId') or \ + self.new_object.get('meraki_auth_user_id') + return new_object_params + + def get_object_by_name(self, name): + result = None + # NOTE: Does not have a get by name method or it is in another action + try: + items = self.meraki.exec_meraki( + family="networks", + function="getNetworkMerakiAuthUsers", + params=self.get_all_params(name=name), + ) + if isinstance(items, dict): + if 'response' in items: + items = items.get('response') + result = get_dict_result(items, 'name', name) + if result is None: + result = items + except Exception as e: + print("Error: ", e) + result = None + return result + + def get_object_by_id(self, id): + result = None + try: + items = self.meraki.exec_meraki( + family="networks", + function="getNetworkMerakiAuthUser", + params=self.get_params_by_id() + ) + if isinstance(items, dict): + if 'response' in items: + items = items.get('response') + result = get_dict_result(items, 'merakiAuthUserId', id) + except Exception as e: + print("Error: ", e) + result = None + return result + + def exists(self): + id_exists = False + name_exists = False + prev_obj = None + o_id = self.new_object.get("id") + o_id = o_id or self.new_object.get( + "meraki_auth_user_id") or self.new_object.get("merakiAuthUserId") + name = self.new_object.get("name") + if o_id: + prev_obj = self.get_object_by_id(o_id) + id_exists = prev_obj is not None and isinstance(prev_obj, dict) + if not id_exists and name: + prev_obj = self.get_object_by_name(name) + name_exists = prev_obj is not None and isinstance(prev_obj, dict) + if name_exists: + _id = prev_obj.get("id") + _id = _id or prev_obj.get("merakiAuthUserId") + if id_exists and name_exists and o_id != _id: + raise InconsistentParameters( + "The 'id' and 'name' params don't refer to the same object") + if _id: + self.new_object.update(dict(id=_id)) + self.new_object.update(dict(merakiAuthUserId=_id)) + if _id: + prev_obj = self.get_object_by_id(_id) + it_exists = prev_obj is not None and isinstance(prev_obj, dict) + return (it_exists, prev_obj) + + def requires_update(self, current_obj): + requested_obj = self.new_object + + obj_params = [ + ("email", "email"), + ("name", "name"), + ("accountType", "accountType"), + ("emailPasswordToUser", "emailPasswordToUser"), + ("isAdmin", "isAdmin"), + ("authorizations", "authorizations"), + ("networkId", "networkId"), + ("merakiAuthUserId", "merakiAuthUserId"), + ] + # Method 1. Params present in request (Ansible) obj are the same as the current (DNAC) params + # If any does not have eq params, it requires update + return any(not meraki_compare_equality(current_obj.get(meraki_param), + requested_obj.get(ansible_param)) + for (meraki_param, ansible_param) in obj_params) + + def create(self): + result = self.meraki.exec_meraki( + family="networks", + function="createNetworkMerakiAuthUser", + params=self.create_params(), + op_modifies=True, + ) + return result + + def update(self): + id = self.new_object.get("id") + id = id or self.new_object.get("merakiAuthUserId") + name = self.new_object.get("name") + result = None + if not id: + prev_obj_name = self.get_object_by_name(name) + id_ = None + if prev_obj_name: + id_ = prev_obj_name.get("id") + id_ = id_ or prev_obj_name.get("merakiAuthUserId") + if id_: + self.new_object.update(dict(merakiAuthUserId=id_)) + result = self.meraki.exec_meraki( + family="networks", + function="updateNetworkMerakiAuthUser", + params=self.update_by_id_params(), + op_modifies=True, + ) + return result + + def delete(self): + id = self.new_object.get("id") + id = id or self.new_object.get("merakiAuthUserId") + name = self.new_object.get("name") + result = None + if not id: + prev_obj_name = self.get_object_by_name(name) + id_ = None + if prev_obj_name: + id_ = prev_obj_name.get("id") + id_ = id_ or prev_obj_name.get("merakiAuthUserId") + if id_: + self.new_object.update(dict(merakiAuthUserId=id_)) + result = self.meraki.exec_meraki( + family="networks", + function="deleteNetworkMerakiAuthUser", + params=self.delete_by_id_params(), + ) + return result + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = False + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + meraki = MERAKI(self._task.args) + obj = NetworksMerakiAuthUsers(self._task.args, meraki) + + state = self._task.args.get("state") + + response = None + + if state == "present": + (obj_exists, prev_obj) = obj.exists() + if obj_exists: + if obj.requires_update(prev_obj): + response = obj.update() + meraki.object_updated() + else: + response = prev_obj + meraki.object_already_present() + else: + response = obj.create() + meraki.object_created() + + elif state == "absent": + (obj_exists, prev_obj) = obj.exists() + if obj_exists: + response = obj.delete() + meraki.object_deleted() + else: + meraki.object_already_absent() + + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_meraki_auth_users_info.py b/ansible_collections/cisco/meraki/plugins/action/networks_meraki_auth_users_info.py new file mode 100644 index 000000000..bc8281258 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_meraki_auth_users_info.py @@ -0,0 +1,112 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + networkId=dict(type="str"), + merakiAuthUserId=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_object(self, params): + new_object = {} + if params.get("networkId") is not None: + new_object["networkId"] = params.get( + "networkId") + if params.get("merakiAuthUserId") is not None: + new_object["merakiAuthUserId"] = params.get( + "merakiAuthUserId") + return new_object + + def get_all(self, params): + new_object = {} + if params.get("networkId") is not None: + new_object["networkId"] = params.get( + "networkId") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + id = self._task.args.get("merakiAuthUserId") + if id: + response = meraki.exec_meraki( + family="networks", + function='getNetworkMerakiAuthUser', + params=self.get_object(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result + if not id: + response = meraki.exec_meraki( + family="networks", + function='getNetworkMerakiAuthUsers', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_mqtt_brokers.py b/ansible_collections/cisco/meraki/plugins/action/networks_mqtt_brokers.py new file mode 100644 index 000000000..4313ec519 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_mqtt_brokers.py @@ -0,0 +1,97 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguements specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + name=dict(type="str"), + host=dict(type="str"), + port=dict(type="int"), + security=dict(type="dict"), + authentication=dict(type="dict"), + networkId=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = False + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_object(self, params): + new_object = dict( + name=params.get("name"), + host=params.get("host"), + port=params.get("port"), + security=params.get("security"), + authentication=params.get("authentication"), + networkId=params.get("networkId"), + ) + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="networks", + function='createNetworkMqttBroker', + op_modifies=True, + params=self.get_object(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_netflow.py b/ansible_collections/cisco/meraki/plugins/action/networks_netflow.py new file mode 100644 index 000000000..0360b2792 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_netflow.py @@ -0,0 +1,222 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or +# https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, + meraki_compare_equality, + get_dict_result, +) +from ansible_collections.cisco.meraki.plugins.plugin_utils.exceptions import ( + InconsistentParameters, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + state=dict(type="str", default="present", choices=["present"]), + reportingEnabled=dict(type="bool"), + collectorIp=dict(type="str"), + collectorPort=dict(type="int"), + etaEnabled=dict(type="bool"), + etaDstPort=dict(type="int"), + networkId=dict(type="str"), +)) + +required_if = [ + ("state", "present", ["networkId"], True), +] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class NetworksNetflow(object): + def __init__(self, params, meraki): + self.meraki = meraki + self.new_object = dict( + reportingEnabled=params.get("reportingEnabled"), + collectorIp=params.get("collectorIp"), + collectorPort=params.get("collectorPort"), + etaEnabled=params.get("etaEnabled"), + etaDstPort=params.get("etaDstPort"), + network_id=params.get("networkId"), + ) + + def get_all_params(self, name=None, id=None): + new_object_params = {} + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + return new_object_params + + def update_all_params(self): + new_object_params = {} + if self.new_object.get('reportingEnabled') is not None or self.new_object.get('reporting_enabled') is not None: + new_object_params['reportingEnabled'] = self.new_object.get('reportingEnabled') + if self.new_object.get('collectorIp') is not None or self.new_object.get('collector_ip') is not None: + new_object_params['collectorIp'] = self.new_object.get('collectorIp') or \ + self.new_object.get('collector_ip') + if self.new_object.get('collectorPort') is not None or self.new_object.get('collector_port') is not None: + new_object_params['collectorPort'] = self.new_object.get('collectorPort') or \ + self.new_object.get('collector_port') + if self.new_object.get('etaEnabled') is not None or self.new_object.get('eta_enabled') is not None: + new_object_params['etaEnabled'] = self.new_object.get('etaEnabled') + if self.new_object.get('etaDstPort') is not None or self.new_object.get('eta_dst_port') is not None: + new_object_params['etaDstPort'] = self.new_object.get('etaDstPort') or \ + self.new_object.get('eta_dst_port') + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + return new_object_params + + def get_object_by_name(self, name): + result = None + # NOTE: Does not have a get by name method, using get all + try: + items = self.meraki.exec_meraki( + family="networks", + function="getNetworkNetflow", + params=self.get_all_params(name=name), + ) + if isinstance(items, dict): + if 'response' in items: + items = items.get('response') + result = get_dict_result(items, 'name', name) + if result is None: + result = items + except Exception as e: + print("Error: ", e) + result = None + return result + + def get_object_by_id(self, id): + result = None + # NOTE: Does not have a get by id method or it is in another action + return result + + def exists(self): + prev_obj = None + id_exists = False + name_exists = False + o_id = self.new_object.get("networkId") or self.new_object.get("network_id") + name = self.new_object.get("name") + if o_id: + prev_obj = self.get_object_by_name(o_id) + id_exists = prev_obj is not None and isinstance(prev_obj, dict) + if not id_exists and name: + prev_obj = self.get_object_by_name(name) + name_exists = prev_obj is not None and isinstance(prev_obj, dict) + if name_exists: + _id = prev_obj.get("id") + if id_exists and name_exists and o_id != _id: + raise InconsistentParameters( + "The 'id' and 'name' params don't refer to the same object") + if _id: + self.new_object.update(dict(id=_id)) + it_exists = prev_obj is not None and isinstance(prev_obj, dict) + return (it_exists, prev_obj) + + def requires_update(self, current_obj): + requested_obj = self.new_object + + obj_params = [ + ("reportingEnabled", "reportingEnabled"), + ("collectorIp", "collectorIp"), + ("collectorPort", "collectorPort"), + ("etaEnabled", "etaEnabled"), + ("etaDstPort", "etaDstPort"), + ("networkId", "networkId"), + ] + # Method 1. Params present in request (Ansible) obj are the same as the current (ISE) params + # If any does not have eq params, it requires update + return any(not meraki_compare_equality(current_obj.get(meraki_param), + requested_obj.get(ansible_param)) + for (meraki_param, ansible_param) in obj_params) + + def update(self): + id = self.new_object.get("id") + name = self.new_object.get("name") + result = None + result = self.meraki.exec_meraki( + family="networks", + function="updateNetworkNetflow", + params=self.update_all_params(), + op_modifies=True, + ) + return result + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = False + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + meraki = MERAKI(self._task.args) + obj = NetworksNetflow(self._task.args, meraki) + + state = self._task.args.get("state") + + response = None + if state == "present": + (obj_exists, prev_obj) = obj.exists() + if obj_exists: + if obj.requires_update(prev_obj): + response = obj.update() + meraki.object_updated() + else: + response = prev_obj + meraki.object_already_present() + else: + meraki.fail_json( + "Object does not exists, plugin only has update") + + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_netflow_info.py b/ansible_collections/cisco/meraki/plugins/action/networks_netflow_info.py new file mode 100644 index 000000000..b0636d4ba --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_netflow_info.py @@ -0,0 +1,90 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + networkId=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_all(self, params): + new_object = {} + if params.get("networkId") is not None: + new_object["networkId"] = params.get( + "networkId") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="networks", + function='getNetworkNetflow', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_pii_pii_keys_info.py b/ansible_collections/cisco/meraki/plugins/action/networks_pii_pii_keys_info.py new file mode 100644 index 000000000..a263f2d3e --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_pii_pii_keys_info.py @@ -0,0 +1,114 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + networkId=dict(type="str"), + username=dict(type="str"), + email=dict(type="str"), + mac=dict(type="str"), + serial=dict(type="str"), + imei=dict(type="str"), + bluetoothMac=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_all(self, params): + new_object = {} + if params.get("networkId") is not None: + new_object["networkId"] = params.get( + "networkId") + if params.get("username") is not None: + new_object["username"] = params.get( + "username") + if params.get("email") is not None: + new_object["email"] = params.get( + "email") + if params.get("mac") is not None: + new_object["mac"] = params.get( + "mac") + if params.get("serial") is not None: + new_object["serial"] = params.get( + "serial") + if params.get("imei") is not None: + new_object["imei"] = params.get( + "imei") + if params.get("bluetoothMac") is not None: + new_object["bluetoothMac"] = params.get( + "bluetoothMac") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="networks", + function='getNetworkPiiPiiKeys', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_pii_requests_delete.py b/ansible_collections/cisco/meraki/plugins/action/networks_pii_requests_delete.py new file mode 100644 index 000000000..da74a8f19 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_pii_requests_delete.py @@ -0,0 +1,88 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguements specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + networkId=dict(type="str"), + requestId=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = False + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_object(self, params): + new_object = dict( + networkId=params.get("networkId"), + requestId=params.get("requestId"), + ) + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="networks", + function="deleteNetworkPiiRequest", + params=self.get_object(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_pii_requests_info.py b/ansible_collections/cisco/meraki/plugins/action/networks_pii_requests_info.py new file mode 100644 index 000000000..ec0658730 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_pii_requests_info.py @@ -0,0 +1,112 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + networkId=dict(type="str"), + requestId=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_object(self, params): + new_object = {} + if params.get("networkId") is not None: + new_object["networkId"] = params.get( + "networkId") + if params.get("requestId") is not None: + new_object["requestId"] = params.get( + "requestId") + return new_object + + def get_all(self, params): + new_object = {} + if params.get("networkId") is not None: + new_object["networkId"] = params.get( + "networkId") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + id = self._task.args.get("requestId") + if id: + response = meraki.exec_meraki( + family="networks", + function='getNetworkPiiRequest', + params=self.get_object(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result + if not id: + response = meraki.exec_meraki( + family="networks", + function='getNetworkPiiRequests', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_pii_sm_devices_for_key_info.py b/ansible_collections/cisco/meraki/plugins/action/networks_pii_sm_devices_for_key_info.py new file mode 100644 index 000000000..db8644449 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_pii_sm_devices_for_key_info.py @@ -0,0 +1,114 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + networkId=dict(type="str"), + username=dict(type="str"), + email=dict(type="str"), + mac=dict(type="str"), + serial=dict(type="str"), + imei=dict(type="str"), + bluetoothMac=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_all(self, params): + new_object = {} + if params.get("networkId") is not None: + new_object["networkId"] = params.get( + "networkId") + if params.get("username") is not None: + new_object["username"] = params.get( + "username") + if params.get("email") is not None: + new_object["email"] = params.get( + "email") + if params.get("mac") is not None: + new_object["mac"] = params.get( + "mac") + if params.get("serial") is not None: + new_object["serial"] = params.get( + "serial") + if params.get("imei") is not None: + new_object["imei"] = params.get( + "imei") + if params.get("bluetoothMac") is not None: + new_object["bluetoothMac"] = params.get( + "bluetoothMac") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="networks", + function='getNetworkPiiSmDevicesForKey', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_pii_sm_owners_for_key_info.py b/ansible_collections/cisco/meraki/plugins/action/networks_pii_sm_owners_for_key_info.py new file mode 100644 index 000000000..8468c643f --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_pii_sm_owners_for_key_info.py @@ -0,0 +1,114 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + networkId=dict(type="str"), + username=dict(type="str"), + email=dict(type="str"), + mac=dict(type="str"), + serial=dict(type="str"), + imei=dict(type="str"), + bluetoothMac=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_all(self, params): + new_object = {} + if params.get("networkId") is not None: + new_object["networkId"] = params.get( + "networkId") + if params.get("username") is not None: + new_object["username"] = params.get( + "username") + if params.get("email") is not None: + new_object["email"] = params.get( + "email") + if params.get("mac") is not None: + new_object["mac"] = params.get( + "mac") + if params.get("serial") is not None: + new_object["serial"] = params.get( + "serial") + if params.get("imei") is not None: + new_object["imei"] = params.get( + "imei") + if params.get("bluetoothMac") is not None: + new_object["bluetoothMac"] = params.get( + "bluetoothMac") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="networks", + function='getNetworkPiiSmOwnersForKey', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_policies_by_client_info.py b/ansible_collections/cisco/meraki/plugins/action/networks_policies_by_client_info.py new file mode 100644 index 000000000..4471bd461 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_policies_by_client_info.py @@ -0,0 +1,116 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + networkId=dict(type="str"), + perPage=dict(type="int"), + total_pages=dict(type="int"), + direction=dict(type="str"), + startingAfter=dict(type="str"), + endingBefore=dict(type="str"), + t0=dict(type="str"), + timespan=dict(type="float"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_all(self, params): + new_object = {} + if params.get("networkId") is not None: + new_object["networkId"] = params.get( + "networkId") + if params.get("perPage") is not None: + new_object["perPage"] = params.get( + "perPage") + new_object['total_pages'] = params.get( + "total_pages") or 1 + new_object['direction'] = params.get( + "direction") or "next" + if params.get("startingAfter") is not None: + new_object["startingAfter"] = params.get( + "startingAfter") + if params.get("endingBefore") is not None: + new_object["endingBefore"] = params.get( + "endingBefore") + if params.get("t0") is not None: + new_object["t0"] = params.get( + "t0") + if params.get("timespan") is not None: + new_object["timespan"] = params.get( + "timespan") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="networks", + function='getNetworkPoliciesByClient', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_sensor_alerts_current_overview_by_metric_info.py b/ansible_collections/cisco/meraki/plugins/action/networks_sensor_alerts_current_overview_by_metric_info.py new file mode 100644 index 000000000..49da874ad --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_sensor_alerts_current_overview_by_metric_info.py @@ -0,0 +1,90 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + networkId=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_all(self, params): + new_object = {} + if params.get("networkId") is not None: + new_object["networkId"] = params.get( + "networkId") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="sensor", + function='getNetworkSensorAlertsCurrentOverviewByMetric', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_sensor_alerts_overview_by_metric_info.py b/ansible_collections/cisco/meraki/plugins/action/networks_sensor_alerts_overview_by_metric_info.py new file mode 100644 index 000000000..6c9e730ce --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_sensor_alerts_overview_by_metric_info.py @@ -0,0 +1,106 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + networkId=dict(type="str"), + t0=dict(type="str"), + t1=dict(type="str"), + timespan=dict(type="float"), + interval=dict(type="int"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_all(self, params): + new_object = {} + if params.get("networkId") is not None: + new_object["networkId"] = params.get( + "networkId") + if params.get("t0") is not None: + new_object["t0"] = params.get( + "t0") + if params.get("t1") is not None: + new_object["t1"] = params.get( + "t1") + if params.get("timespan") is not None: + new_object["timespan"] = params.get( + "timespan") + if params.get("interval") is not None: + new_object["interval"] = params.get( + "interval") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="sensor", + function='getNetworkSensorAlertsOverviewByMetric', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_sensor_alerts_profiles.py b/ansible_collections/cisco/meraki/plugins/action/networks_sensor_alerts_profiles.py new file mode 100644 index 000000000..13be65175 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_sensor_alerts_profiles.py @@ -0,0 +1,329 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or +# https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, + meraki_compare_equality, + get_dict_result, +) +from ansible_collections.cisco.meraki.plugins.plugin_utils.exceptions import ( + InconsistentParameters, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + state=dict(type="str", default="present", choices=["present", "absent"]), + name=dict(type="str"), + schedule=dict(type="dict"), + conditions=dict(type="list"), + recipients=dict(type="dict"), + serials=dict(type="list"), + networkId=dict(type="str"), + id=dict(type="str"), +)) + +required_if = [ + ("state", "present", ["id", "name", "networkId"], True), + ("state", "absent", ["id", "name", "networkId"], True), +] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class NetworksSensorAlertsProfiles(object): + def __init__(self, params, meraki): + self.meraki = meraki + self.new_object = dict( + name=params.get("name"), + schedule=params.get("schedule"), + conditions=params.get("conditions"), + recipients=params.get("recipients"), + serials=params.get("serials"), + networkId=params.get("networkId"), + id=params.get("id"), + ) + + def get_all_params(self, name=None, id=None): + new_object_params = {} + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + return new_object_params + + def get_params_by_id(self, name=None, id=None): + new_object_params = {} + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + if self.new_object.get('id') is not None or self.new_object.get('id') is not None: + new_object_params['id'] = self.new_object.get('id') + return new_object_params + + def create_params(self): + new_object_params = {} + if self.new_object.get('name') is not None or self.new_object.get('name') is not None: + new_object_params['name'] = self.new_object.get('name') or \ + self.new_object.get('name') + if self.new_object.get('schedule') is not None or self.new_object.get('schedule') is not None: + new_object_params['schedule'] = self.new_object.get('schedule') or \ + self.new_object.get('schedule') + if self.new_object.get('conditions') is not None or self.new_object.get('conditions') is not None: + new_object_params['conditions'] = self.new_object.get('conditions') or \ + self.new_object.get('conditions') + if self.new_object.get('recipients') is not None or self.new_object.get('recipients') is not None: + new_object_params['recipients'] = self.new_object.get('recipients') or \ + self.new_object.get('recipients') + if self.new_object.get('serials') is not None or self.new_object.get('serials') is not None: + new_object_params['serials'] = self.new_object.get('serials') or \ + self.new_object.get('serials') + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + return new_object_params + + def delete_by_id_params(self): + new_object_params = {} + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + if self.new_object.get('id') is not None or self.new_object.get('id') is not None: + new_object_params['id'] = self.new_object.get('id') or \ + self.new_object.get('id') + return new_object_params + + def update_by_id_params(self): + new_object_params = {} + if self.new_object.get('name') is not None or self.new_object.get('name') is not None: + new_object_params['name'] = self.new_object.get('name') or \ + self.new_object.get('name') + if self.new_object.get('schedule') is not None or self.new_object.get('schedule') is not None: + new_object_params['schedule'] = self.new_object.get('schedule') or \ + self.new_object.get('schedule') + if self.new_object.get('conditions') is not None or self.new_object.get('conditions') is not None: + new_object_params['conditions'] = self.new_object.get('conditions') or \ + self.new_object.get('conditions') + if self.new_object.get('recipients') is not None or self.new_object.get('recipients') is not None: + new_object_params['recipients'] = self.new_object.get('recipients') or \ + self.new_object.get('recipients') + if self.new_object.get('serials') is not None or self.new_object.get('serials') is not None: + new_object_params['serials'] = self.new_object.get('serials') or \ + self.new_object.get('serials') + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + if self.new_object.get('id') is not None or self.new_object.get('id') is not None: + new_object_params['id'] = self.new_object.get('id') or \ + self.new_object.get('id') + return new_object_params + + def get_object_by_name(self, name): + result = None + # NOTE: Does not have a get by name method or it is in another action + try: + items = self.meraki.exec_meraki( + family="sensor", + function="getNetworkSensorAlertsProfiles", + params=self.get_all_params(name=name), + ) + if isinstance(items, dict): + if 'response' in items: + items = items.get('response') + result = get_dict_result(items, 'name', name) + if result is None: + result = items + except Exception as e: + print("Error: ", e) + result = None + return result + + def get_object_by_id(self, id): + result = None + try: + items = self.meraki.exec_meraki( + family="sensor", + function="getNetworkSensorAlertsProfile", + params={"id": id} + ) + if isinstance(items, dict): + if 'response' in items: + items = items.get('response') + result = get_dict_result(items, 'id', id) + except Exception as e: + print("Error: ", e) + result = None + return result + + def exists(self): + id_exists = False + name_exists = False + prev_obj = None + o_id = self.new_object.get("id") + name = self.new_object.get("name") + if o_id: + prev_obj = self.get_object_by_id(o_id) + id_exists = prev_obj is not None and isinstance(prev_obj, dict) + if not id_exists and name: + prev_obj = self.get_object_by_name(name) + name_exists = prev_obj is not None and isinstance(prev_obj, dict) + if name_exists: + _id = prev_obj.get("id") + if id_exists and name_exists and o_id != _id: + raise InconsistentParameters( + "The 'id' and 'name' params don't refer to the same object") + if _id: + self.new_object.update(dict(id=_id)) + if _id: + prev_obj = self.get_object_by_id(_id) + it_exists = prev_obj is not None and isinstance(prev_obj, dict) + return (it_exists, prev_obj) + + def requires_update(self, current_obj): + requested_obj = self.new_object + + obj_params = [ + ("name", "name"), + ("schedule", "schedule"), + ("conditions", "conditions"), + ("recipients", "recipients"), + ("serials", "serials"), + ("networkId", "networkId"), + ("id", "id"), + ] + # Method 1. Params present in request (Ansible) obj are the same as the current (DNAC) params + # If any does not have eq params, it requires update + return any(not meraki_compare_equality(current_obj.get(meraki_param), + requested_obj.get(ansible_param)) + for (meraki_param, ansible_param) in obj_params) + + def create(self): + result = self.meraki.exec_meraki( + family="sensor", + function="createNetworkSensorAlertsProfile", + params=self.create_params(), + op_modifies=True, + ) + return result + + def update(self): + id = self.new_object.get("id") + name = self.new_object.get("name") + result = None + if not id: + prev_obj_name = self.get_object_by_name(name) + id_ = None + if prev_obj_name: + id_ = prev_obj_name.get("id") + if id_: + self.new_object.update(dict(id=id_)) + result = self.meraki.exec_meraki( + family="sensor", + function="updateNetworkSensorAlertsProfile", + params=self.update_by_id_params(), + op_modifies=True, + ) + return result + + def delete(self): + id = self.new_object.get("id") + name = self.new_object.get("name") + result = None + if not id: + prev_obj_name = self.get_object_by_name(name) + id_ = None + if prev_obj_name: + id_ = prev_obj_name.get("id") + if id_: + self.new_object.update(dict(id=id_)) + result = self.meraki.exec_meraki( + family="sensor", + function="deleteNetworkSensorAlertsProfile", + params=self.delete_by_id_params(), + ) + return result + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = False + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + meraki = MERAKI(self._task.args) + obj = NetworksSensorAlertsProfiles(self._task.args, meraki) + + state = self._task.args.get("state") + + response = None + + if state == "present": + (obj_exists, prev_obj) = obj.exists() + if obj_exists: + if obj.requires_update(prev_obj): + response = obj.update() + meraki.object_updated() + else: + response = prev_obj + meraki.object_already_present() + else: + response = obj.create() + meraki.object_created() + + elif state == "absent": + (obj_exists, prev_obj) = obj.exists() + if obj_exists: + response = obj.delete() + meraki.object_deleted() + else: + meraki.object_already_absent() + + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_sensor_alerts_profiles_info.py b/ansible_collections/cisco/meraki/plugins/action/networks_sensor_alerts_profiles_info.py new file mode 100644 index 000000000..02015c786 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_sensor_alerts_profiles_info.py @@ -0,0 +1,112 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + networkId=dict(type="str"), + id=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_object(self, params): + new_object = {} + if params.get("networkId") is not None: + new_object["networkId"] = params.get( + "networkId") + if params.get("id") is not None: + new_object["id"] = params.get( + "id") + return new_object + + def get_all(self, params): + new_object = {} + if params.get("networkId") is not None: + new_object["networkId"] = params.get( + "networkId") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + id = self._task.args.get("id") + if id: + response = meraki.exec_meraki( + family="sensor", + function='getNetworkSensorAlertsProfile', + params=self.get_object(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result + if not id: + response = meraki.exec_meraki( + family="sensor", + function='getNetworkSensorAlertsProfiles', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_sensor_mqtt_brokers.py b/ansible_collections/cisco/meraki/plugins/action/networks_sensor_mqtt_brokers.py new file mode 100644 index 000000000..cb3ad8b3d --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_sensor_mqtt_brokers.py @@ -0,0 +1,242 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or +# https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, + meraki_compare_equality, + get_dict_result, +) +from ansible_collections.cisco.meraki.plugins.plugin_utils.exceptions import ( + InconsistentParameters, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + state=dict(type="str", default="present", choices=["present"]), + enabled=dict(type="bool"), + networkId=dict(type="str"), + mqttBrokerId=dict(type="str"), +)) + +required_if = [ + ("state", "present", ["mqttBrokerId", "networkId"], True), +] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class NetworksSensorMqttBrokers(object): + def __init__(self, params, meraki): + self.meraki = meraki + self.new_object = dict( + enabled=params.get("enabled"), + network_id=params.get("networkId"), + mqtt_broker_id=params.get("mqttBrokerId"), + ) + + def get_all_params(self, name=None, id=None): + new_object_params = {} + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + return new_object_params + + def get_params_by_id(self, name=None, id=None): + new_object_params = {} + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + if self.new_object.get('mqttBrokerId') is not None or self.new_object.get('mqtt_broker_id') is not None: + new_object_params['mqttBrokerId'] = self.new_object.get('mqttBrokerId') or \ + self.new_object.get('mqtt_broker_id') + return new_object_params + + def update_by_id_params(self): + new_object_params = {} + if self.new_object.get('enabled') is not None or self.new_object.get('enabled') is not None: + new_object_params['enabled'] = self.new_object.get('enabled') + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + if self.new_object.get('mqttBrokerId') is not None or self.new_object.get('mqtt_broker_id') is not None: + new_object_params['mqttBrokerId'] = self.new_object.get('mqttBrokerId') or \ + self.new_object.get('mqtt_broker_id') + return new_object_params + + def get_object_by_name(self, name): + result = None + # NOTE: Does not have a get by name method, using get all + try: + items = self.meraki.exec_meraki( + family="sensor", + function="getNetworkSensorMqttBrokers", + params=self.get_all_params(name=name), + ) + if isinstance(items, dict): + if 'response' in items: + items = items.get('response') + result = get_dict_result(items, 'name', name) + if result is None: + result = items + except Exception as e: + print("Error: ", e) + result = None + return result + + def get_object_by_id(self, id): + result = None + try: + items = self.meraki.exec_meraki( + family="sensor", + function="getNetworkSensorMqttBroker", + params=self.get_params_by_id() + ) + if isinstance(items, dict): + if 'response' in items: + items = items.get('response') + result = items + except Exception as e: + print("Error: ", e) + result = None + return result + + def exists(self): + prev_obj = None + id_exists = False + name_exists = False + o_id = self.new_object.get("networkId") or self.new_object.get("network_id") + o_id = o_id or self.new_object.get( + "mqtt_broker_id") or self.new_object.get("mqttBrokerId") + name = self.new_object.get("name") + if o_id: + prev_obj = self.get_object_by_id(o_id) + id_exists = prev_obj is not None and isinstance(prev_obj, dict) + if not id_exists and name: + prev_obj = self.get_object_by_name(name) + name_exists = prev_obj is not None and isinstance(prev_obj, dict) + if name_exists: + _id = prev_obj.get("id") + _id = _id or prev_obj.get("mqttBrokerId") + if id_exists and name_exists and o_id != _id: + raise InconsistentParameters( + "The 'id' and 'name' params don't refer to the same object") + if _id: + self.new_object.update(dict(id=_id)) + self.new_object.update(dict(mqttBrokerId=_id)) + if _id: + prev_obj = self.get_object_by_id(_id) + it_exists = prev_obj is not None and isinstance(prev_obj, dict) + return (it_exists, prev_obj) + + def requires_update(self, current_obj): + requested_obj = self.new_object + + obj_params = [ + ("enabled", "enabled"), + ("networkId", "networkId"), + ("mqttBrokerId", "mqttBrokerId"), + ] + # Method 1. Params present in request (Ansible) obj are the same as the current (ISE) params + # If any does not have eq params, it requires update + return any(not meraki_compare_equality(current_obj.get(meraki_param), + requested_obj.get(ansible_param)) + for (meraki_param, ansible_param) in obj_params) + + def update(self): + id = self.new_object.get("id") + id = id or self.new_object.get("mqttBrokerId") + name = self.new_object.get("name") + result = None + if not id: + prev_obj_name = self.get_object_by_name(name) + id_ = None + if prev_obj_name: + id_ = prev_obj_name.get("id") + id_ = id_ or prev_obj_name.get("mqttBrokerId") + if id_: + self.new_object.update(dict(mqttbrokerid=id_)) + result = self.meraki.exec_meraki( + family="sensor", + function="updateNetworkSensorMqttBroker", + params=self.update_by_id_params(), + op_modifies=True, + ) + return result + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = False + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + meraki = MERAKI(self._task.args) + obj = NetworksSensorMqttBrokers(self._task.args, meraki) + + state = self._task.args.get("state") + + response = None + if state == "present": + (obj_exists, prev_obj) = obj.exists() + if obj_exists: + if obj.requires_update(prev_obj): + response = obj.update() + meraki.object_updated() + else: + response = prev_obj + meraki.object_already_present() + else: + meraki.fail_json( + "Object does not exists, plugin only has update") + + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_sensor_mqtt_brokers_info.py b/ansible_collections/cisco/meraki/plugins/action/networks_sensor_mqtt_brokers_info.py new file mode 100644 index 000000000..dd0f6dabf --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_sensor_mqtt_brokers_info.py @@ -0,0 +1,112 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + networkId=dict(type="str"), + mqttBrokerId=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_object(self, params): + new_object = {} + if params.get("networkId") is not None: + new_object["networkId"] = params.get( + "networkId") + if params.get("mqttBrokerId") is not None: + new_object["mqttBrokerId"] = params.get( + "mqttBrokerId") + return new_object + + def get_all(self, params): + new_object = {} + if params.get("networkId") is not None: + new_object["networkId"] = params.get( + "networkId") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + id = self._task.args.get("mqttBrokerId") + if id: + response = meraki.exec_meraki( + family="sensor", + function='getNetworkSensorMqttBroker', + params=self.get_object(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result + if not id: + response = meraki.exec_meraki( + family="sensor", + function='getNetworkSensorMqttBrokers', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_sensor_relationships_info.py b/ansible_collections/cisco/meraki/plugins/action/networks_sensor_relationships_info.py new file mode 100644 index 000000000..c875c5301 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_sensor_relationships_info.py @@ -0,0 +1,90 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + networkId=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_all(self, params): + new_object = {} + if params.get("networkId") is not None: + new_object["networkId"] = params.get( + "networkId") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="sensor", + function='getNetworkSensorRelationships', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_settings.py b/ansible_collections/cisco/meraki/plugins/action/networks_settings.py new file mode 100644 index 000000000..3827be9c0 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_settings.py @@ -0,0 +1,216 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or +# https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, + meraki_compare_equality, + get_dict_result, +) +from ansible_collections.cisco.meraki.plugins.plugin_utils.exceptions import ( + InconsistentParameters, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + state=dict(type="str", default="present", choices=["present"]), + localStatusPageEnabled=dict(type="bool"), + remoteStatusPageEnabled=dict(type="bool"), + localStatusPage=dict(type="dict"), + securePort=dict(type="dict"), + networkId=dict(type="str"), +)) + +required_if = [ + ("state", "present", ["networkId"], True), +] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class NetworksSettings(object): + def __init__(self, params, meraki): + self.meraki = meraki + self.new_object = dict( + localStatusPageEnabled=params.get("localStatusPageEnabled"), + remoteStatusPageEnabled=params.get("remoteStatusPageEnabled"), + localStatusPage=params.get("localStatusPage"), + securePort=params.get("securePort"), + network_id=params.get("networkId"), + ) + + def get_all_params(self, name=None, id=None): + new_object_params = {} + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + return new_object_params + + def update_all_params(self): + new_object_params = {} + if self.new_object.get('localStatusPageEnabled') is not None or self.new_object.get('local_status_page_enabled') is not None: + new_object_params['localStatusPageEnabled'] = self.new_object.get('localStatusPageEnabled') + if self.new_object.get('remoteStatusPageEnabled') is not None or self.new_object.get('remote_status_page_enabled') is not None: + new_object_params['remoteStatusPageEnabled'] = self.new_object.get('remoteStatusPageEnabled') + if self.new_object.get('localStatusPage') is not None or self.new_object.get('local_status_page') is not None: + new_object_params['localStatusPage'] = self.new_object.get('localStatusPage') or \ + self.new_object.get('local_status_page') + if self.new_object.get('securePort') is not None or self.new_object.get('secure_port') is not None: + new_object_params['securePort'] = self.new_object.get('securePort') or \ + self.new_object.get('secure_port') + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + return new_object_params + + def get_object_by_name(self, name): + result = None + # NOTE: Does not have a get by name method, using get all + try: + items = self.meraki.exec_meraki( + family="networks", + function="getNetworkSettings", + params=self.get_all_params(name=name), + ) + if isinstance(items, dict): + if 'response' in items: + items = items.get('response') + result = get_dict_result(items, 'name', name) + if result is None: + result = items + except Exception as e: + print("Error: ", e) + result = None + return result + + def get_object_by_id(self, id): + result = None + # NOTE: Does not have a get by id method or it is in another action + return result + + def exists(self): + prev_obj = None + id_exists = False + name_exists = False + o_id = self.new_object.get("networkId") or self.new_object.get("network_id") + name = self.new_object.get("name") + if o_id: + prev_obj = self.get_object_by_name(o_id) + id_exists = prev_obj is not None and isinstance(prev_obj, dict) + if not id_exists and name: + prev_obj = self.get_object_by_name(name) + name_exists = prev_obj is not None and isinstance(prev_obj, dict) + if name_exists: + _id = prev_obj.get("id") + if id_exists and name_exists and o_id != _id: + raise InconsistentParameters( + "The 'id' and 'name' params don't refer to the same object") + if _id: + self.new_object.update(dict(id=_id)) + it_exists = prev_obj is not None and isinstance(prev_obj, dict) + return (it_exists, prev_obj) + + def requires_update(self, current_obj): + requested_obj = self.new_object + + obj_params = [ + ("localStatusPageEnabled", "localStatusPageEnabled"), + ("remoteStatusPageEnabled", "remoteStatusPageEnabled"), + ("localStatusPage", "localStatusPage"), + ("securePort", "securePort"), + ("networkId", "networkId"), + ] + # Method 1. Params present in request (Ansible) obj are the same as the current (ISE) params + # If any does not have eq params, it requires update + return any(not meraki_compare_equality(current_obj.get(meraki_param), + requested_obj.get(ansible_param)) + for (meraki_param, ansible_param) in obj_params) + + def update(self): + id = self.new_object.get("id") + name = self.new_object.get("name") + result = None + result = self.meraki.exec_meraki( + family="networks", + function="updateNetworkSettings", + params=self.update_all_params(), + op_modifies=True, + ) + return result + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = False + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + meraki = MERAKI(self._task.args) + obj = NetworksSettings(self._task.args, meraki) + + state = self._task.args.get("state") + + response = None + if state == "present": + (obj_exists, prev_obj) = obj.exists() + if obj_exists: + if obj.requires_update(prev_obj): + response = obj.update() + meraki.object_updated() + else: + response = prev_obj + meraki.object_already_present() + else: + meraki.fail_json( + "Object does not exists, plugin only has update") + + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_settings_info.py b/ansible_collections/cisco/meraki/plugins/action/networks_settings_info.py new file mode 100644 index 000000000..f4ab2bafb --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_settings_info.py @@ -0,0 +1,90 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + networkId=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_all(self, params): + new_object = {} + if params.get("networkId") is not None: + new_object["networkId"] = params.get( + "networkId") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="networks", + function='getNetworkSettings', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_sm_bypass_activation_lock_attempts.py b/ansible_collections/cisco/meraki/plugins/action/networks_sm_bypass_activation_lock_attempts.py new file mode 100644 index 000000000..017f2e314 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_sm_bypass_activation_lock_attempts.py @@ -0,0 +1,205 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or +# https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, + meraki_compare_equality, +) +from ansible_collections.cisco.meraki.plugins.plugin_utils.exceptions import ( + InconsistentParameters, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + state=dict(type="str", default="present", choices=["present"]), + ids=dict(type="list"), + networkId=dict(type="str"), + attemptId=dict(type="str"), +)) + +required_if = [ + ("state", "present", ["attemptId", "networkId"], True), +] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class NetworksSmBypassActivationLockAttempts(object): + def __init__(self, params, meraki): + self.meraki = meraki + self.new_object = dict( + ids=params.get("ids"), + network_id=params.get("networkId"), + attempt_id=params.get("attemptId"), + ) + + def get_params_by_id(self, name=None, id=None): + new_object_params = {} + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + if self.new_object.get('attemptId') is not None or self.new_object.get('attempt_id') is not None: + new_object_params['attemptId'] = self.new_object.get('attemptId') or \ + self.new_object.get('attempt_id') + return new_object_params + + def create_params(self): + new_object_params = {} + if self.new_object.get('ids') is not None or self.new_object.get('ids') is not None: + new_object_params['ids'] = self.new_object.get('ids') or \ + self.new_object.get('ids') + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + return new_object_params + + def get_object_by_name(self, name): + result = None + # NOTE: Does not have a get by name and get all + return result + + def get_object_by_id(self, id): + result = None + try: + items = self.meraki.exec_meraki( + family="sm", + function="getNetworkSmBypassActivationLockAttempt", + params=self.get_params_by_id() + ) + if isinstance(items, dict): + if 'response' in items: + items = items.get('response') + result = items + except Exception as e: + print("Error: ", e) + result = None + return result + + def exists(self): + prev_obj = None + id_exists = False + name_exists = False + o_id = self.new_object.get("networkId") or self.new_object.get("network_id") + o_id = o_id or self.new_object.get( + "attempt_id") or self.new_object.get("attemptId") + name = self.new_object.get("name") + if o_id: + prev_obj = self.get_object_by_id(o_id) + id_exists = prev_obj is not None and isinstance(prev_obj, dict) + if not id_exists and name: + prev_obj = self.get_object_by_name(name) + name_exists = prev_obj is not None and isinstance(prev_obj, dict) + if name_exists: + _id = prev_obj.get("id") + _id = _id or prev_obj.get("attemptId") + if id_exists and name_exists and o_id != _id: + raise InconsistentParameters( + "The 'id' and 'name' params don't refer to the same object") + if _id: + self.new_object.update(dict(id=_id)) + self.new_object.update(dict(attemptId=_id)) + if _id: + prev_obj = self.get_object_by_id(_id) + it_exists = prev_obj is not None and isinstance(prev_obj, dict) + return (it_exists, prev_obj) + + def requires_update(self, current_obj): + requested_obj = self.new_object + + obj_params = [ + ("ids", "ids"), + ("networkId", "networkId"), + ("attemptId", "attemptId"), + ] + # Method 1. Params present in request (Ansible) obj are the same as the current (ISE) params + # If any does not have eq params, it requires update + return any(not meraki_compare_equality(current_obj.get(meraki_param), + requested_obj.get(ansible_param)) + for (meraki_param, ansible_param) in obj_params) + + def create(self): + result = self.meraki.exec_meraki( + family="sm", + function="createNetworkSmBypassActivationLockAttempt", + params=self.create_params(), + op_modifies=True, + ) + return result + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = False + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + meraki = MERAKI(self._task.args) + obj = NetworksSmBypassActivationLockAttempts(self._task.args, meraki) + + state = self._task.args.get("state") + + response = None + if state == "present": + (obj_exists, prev_obj) = obj.exists() + if obj_exists: + if obj.requires_update(prev_obj): + response = prev_obj + meraki.object_present_and_different() + else: + response = prev_obj + meraki.object_already_present() + else: + response = obj.create() + meraki.object_created() + + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_sm_bypass_activation_lock_attempts_info.py b/ansible_collections/cisco/meraki/plugins/action/networks_sm_bypass_activation_lock_attempts_info.py new file mode 100644 index 000000000..8b1a96ad0 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_sm_bypass_activation_lock_attempts_info.py @@ -0,0 +1,102 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + networkId=dict(type="str"), + attemptId=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_object(self, params): + new_object = {} + if params.get("networkId") is not None: + new_object["networkId"] = params.get( + "networkId") + if params.get("attemptId") is not None: + new_object["attemptId"] = params.get( + "attemptId") + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + id = self._task.args.get("attemptId") + if id: + response = meraki.exec_meraki( + family="sm", + function='getNetworkSmBypassActivationLockAttempt', + params=self.get_object(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result + if not id: + # NOTE: Does not have a get all method or it is in another action + response = None + meraki.object_modify_result(changed=False, result="Module does not have get all, check arguments of module") + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_sm_devices_cellular_usage_history_info.py b/ansible_collections/cisco/meraki/plugins/action/networks_sm_devices_cellular_usage_history_info.py new file mode 100644 index 000000000..8b5977fe7 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_sm_devices_cellular_usage_history_info.py @@ -0,0 +1,94 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + networkId=dict(type="str"), + deviceId=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_all(self, params): + new_object = {} + if params.get("networkId") is not None: + new_object["networkId"] = params.get( + "networkId") + if params.get("deviceId") is not None: + new_object["deviceId"] = params.get( + "deviceId") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="sm", + function='getNetworkSmDeviceCellularUsageHistory', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_sm_devices_certs_info.py b/ansible_collections/cisco/meraki/plugins/action/networks_sm_devices_certs_info.py new file mode 100644 index 000000000..2698b6b41 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_sm_devices_certs_info.py @@ -0,0 +1,94 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + networkId=dict(type="str"), + deviceId=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_all(self, params): + new_object = {} + if params.get("networkId") is not None: + new_object["networkId"] = params.get( + "networkId") + if params.get("deviceId") is not None: + new_object["deviceId"] = params.get( + "deviceId") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="sm", + function='getNetworkSmDeviceCerts', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_sm_devices_checkin.py b/ansible_collections/cisco/meraki/plugins/action/networks_sm_devices_checkin.py new file mode 100644 index 000000000..8695838b5 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_sm_devices_checkin.py @@ -0,0 +1,95 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguements specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + wifiMacs=dict(type="list"), + ids=dict(type="list"), + serials=dict(type="list"), + scope=dict(type="list"), + networkId=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = False + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_object(self, params): + new_object = dict( + wifiMacs=params.get("wifiMacs"), + ids=params.get("ids"), + serials=params.get("serials"), + scope=params.get("scope"), + networkId=params.get("networkId"), + ) + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="sm", + function='checkinNetworkSmDevices', + op_modifies=True, + params=self.get_object(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_sm_devices_connectivity_info.py b/ansible_collections/cisco/meraki/plugins/action/networks_sm_devices_connectivity_info.py new file mode 100644 index 000000000..28cb9a0fd --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_sm_devices_connectivity_info.py @@ -0,0 +1,112 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + networkId=dict(type="str"), + deviceId=dict(type="str"), + perPage=dict(type="int"), + total_pages=dict(type="int"), + direction=dict(type="str"), + startingAfter=dict(type="str"), + endingBefore=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_all(self, params): + new_object = {} + if params.get("networkId") is not None: + new_object["networkId"] = params.get( + "networkId") + if params.get("deviceId") is not None: + new_object["deviceId"] = params.get( + "deviceId") + if params.get("perPage") is not None: + new_object["perPage"] = params.get( + "perPage") + new_object['total_pages'] = params.get( + "total_pages") or 1 + new_object['direction'] = params.get( + "direction") or "next" + if params.get("startingAfter") is not None: + new_object["startingAfter"] = params.get( + "startingAfter") + if params.get("endingBefore") is not None: + new_object["endingBefore"] = params.get( + "endingBefore") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="sm", + function='getNetworkSmDeviceConnectivity', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_sm_devices_desktop_logs_info.py b/ansible_collections/cisco/meraki/plugins/action/networks_sm_devices_desktop_logs_info.py new file mode 100644 index 000000000..413efab99 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_sm_devices_desktop_logs_info.py @@ -0,0 +1,112 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + networkId=dict(type="str"), + deviceId=dict(type="str"), + perPage=dict(type="int"), + total_pages=dict(type="int"), + direction=dict(type="str"), + startingAfter=dict(type="str"), + endingBefore=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_all(self, params): + new_object = {} + if params.get("networkId") is not None: + new_object["networkId"] = params.get( + "networkId") + if params.get("deviceId") is not None: + new_object["deviceId"] = params.get( + "deviceId") + if params.get("perPage") is not None: + new_object["perPage"] = params.get( + "perPage") + new_object['total_pages'] = params.get( + "total_pages") or 1 + new_object['direction'] = params.get( + "direction") or "next" + if params.get("startingAfter") is not None: + new_object["startingAfter"] = params.get( + "startingAfter") + if params.get("endingBefore") is not None: + new_object["endingBefore"] = params.get( + "endingBefore") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="sm", + function='getNetworkSmDeviceDesktopLogs', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_sm_devices_device_command_logs_info.py b/ansible_collections/cisco/meraki/plugins/action/networks_sm_devices_device_command_logs_info.py new file mode 100644 index 000000000..4a4388128 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_sm_devices_device_command_logs_info.py @@ -0,0 +1,112 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + networkId=dict(type="str"), + deviceId=dict(type="str"), + perPage=dict(type="int"), + total_pages=dict(type="int"), + direction=dict(type="str"), + startingAfter=dict(type="str"), + endingBefore=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_all(self, params): + new_object = {} + if params.get("networkId") is not None: + new_object["networkId"] = params.get( + "networkId") + if params.get("deviceId") is not None: + new_object["deviceId"] = params.get( + "deviceId") + if params.get("perPage") is not None: + new_object["perPage"] = params.get( + "perPage") + new_object['total_pages'] = params.get( + "total_pages") or 1 + new_object['direction'] = params.get( + "direction") or "next" + if params.get("startingAfter") is not None: + new_object["startingAfter"] = params.get( + "startingAfter") + if params.get("endingBefore") is not None: + new_object["endingBefore"] = params.get( + "endingBefore") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="sm", + function='getNetworkSmDeviceDeviceCommandLogs', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_sm_devices_device_profiles_info.py b/ansible_collections/cisco/meraki/plugins/action/networks_sm_devices_device_profiles_info.py new file mode 100644 index 000000000..8f5ac7c62 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_sm_devices_device_profiles_info.py @@ -0,0 +1,94 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + networkId=dict(type="str"), + deviceId=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_all(self, params): + new_object = {} + if params.get("networkId") is not None: + new_object["networkId"] = params.get( + "networkId") + if params.get("deviceId") is not None: + new_object["deviceId"] = params.get( + "deviceId") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="sm", + function='getNetworkSmDeviceDeviceProfiles', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_sm_devices_fields.py b/ansible_collections/cisco/meraki/plugins/action/networks_sm_devices_fields.py new file mode 100644 index 000000000..6d9bda4c7 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_sm_devices_fields.py @@ -0,0 +1,95 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguements specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + wifiMac=dict(type="str"), + id=dict(type="str"), + serial=dict(type="str"), + deviceFields=dict(type="dict"), + networkId=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = False + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_object(self, params): + new_object = dict( + wifiMac=params.get("wifiMac"), + id=params.get("id"), + serial=params.get("serial"), + deviceFields=params.get("deviceFields"), + networkId=params.get("networkId"), + ) + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="sm", + function='updateNetworkSmDevicesFields', + op_modifies=True, + params=self.get_object(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_sm_devices_info.py b/ansible_collections/cisco/meraki/plugins/action/networks_sm_devices_info.py new file mode 100644 index 000000000..c37f3cc07 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_sm_devices_info.py @@ -0,0 +1,128 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + networkId=dict(type="str"), + fields=dict(type="list"), + wifiMacs=dict(type="list"), + serials=dict(type="list"), + ids=dict(type="list"), + scope=dict(type="list"), + perPage=dict(type="int"), + total_pages=dict(type="int"), + direction=dict(type="str"), + startingAfter=dict(type="str"), + endingBefore=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_all(self, params): + new_object = {} + if params.get("networkId") is not None: + new_object["networkId"] = params.get( + "networkId") + if params.get("fields") is not None: + new_object["fields"] = params.get( + "fields") + if params.get("wifiMacs") is not None: + new_object["wifiMacs"] = params.get( + "wifiMacs") + if params.get("serials") is not None: + new_object["serials"] = params.get( + "serials") + if params.get("ids") is not None: + new_object["ids"] = params.get( + "ids") + if params.get("scope") is not None: + new_object["scope"] = params.get( + "scope") + if params.get("perPage") is not None: + new_object["perPage"] = params.get( + "perPage") + new_object['total_pages'] = params.get( + "total_pages") or 1 + new_object['direction'] = params.get( + "direction") or "next" + if params.get("startingAfter") is not None: + new_object["startingAfter"] = params.get( + "startingAfter") + if params.get("endingBefore") is not None: + new_object["endingBefore"] = params.get( + "endingBefore") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="sm", + function='getNetworkSmDevices', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_sm_devices_lock.py b/ansible_collections/cisco/meraki/plugins/action/networks_sm_devices_lock.py new file mode 100644 index 000000000..c846a4dde --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_sm_devices_lock.py @@ -0,0 +1,97 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguements specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + wifiMacs=dict(type="list"), + ids=dict(type="list"), + serials=dict(type="list"), + scope=dict(type="list"), + pin=dict(type="int"), + networkId=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = False + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_object(self, params): + new_object = dict( + wifiMacs=params.get("wifiMacs"), + ids=params.get("ids"), + serials=params.get("serials"), + scope=params.get("scope"), + pin=params.get("pin"), + networkId=params.get("networkId"), + ) + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="sm", + function='lockNetworkSmDevices', + op_modifies=True, + params=self.get_object(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_sm_devices_modify_tags.py b/ansible_collections/cisco/meraki/plugins/action/networks_sm_devices_modify_tags.py new file mode 100644 index 000000000..ea771b977 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_sm_devices_modify_tags.py @@ -0,0 +1,99 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguements specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + wifiMacs=dict(type="list"), + ids=dict(type="list"), + serials=dict(type="list"), + scope=dict(type="list"), + tags=dict(type="list"), + updateAction=dict(type="str"), + networkId=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = False + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_object(self, params): + new_object = dict( + wifiMacs=params.get("wifiMacs"), + ids=params.get("ids"), + serials=params.get("serials"), + scope=params.get("scope"), + tags=params.get("tags"), + updateAction=params.get("updateAction"), + networkId=params.get("networkId"), + ) + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="sm", + function='modifyNetworkSmDevicesTags', + op_modifies=True, + params=self.get_object(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_sm_devices_move.py b/ansible_collections/cisco/meraki/plugins/action/networks_sm_devices_move.py new file mode 100644 index 000000000..5ed4b5d65 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_sm_devices_move.py @@ -0,0 +1,97 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguements specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + wifiMacs=dict(type="list"), + ids=dict(type="list"), + serials=dict(type="list"), + scope=dict(type="list"), + newNetwork=dict(type="str"), + networkId=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = False + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_object(self, params): + new_object = dict( + wifiMacs=params.get("wifiMacs"), + ids=params.get("ids"), + serials=params.get("serials"), + scope=params.get("scope"), + newNetwork=params.get("newNetwork"), + networkId=params.get("networkId"), + ) + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="sm", + function='moveNetworkSmDevices', + op_modifies=True, + params=self.get_object(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_sm_devices_network_adapters_info.py b/ansible_collections/cisco/meraki/plugins/action/networks_sm_devices_network_adapters_info.py new file mode 100644 index 000000000..78c0d0619 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_sm_devices_network_adapters_info.py @@ -0,0 +1,94 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + networkId=dict(type="str"), + deviceId=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_all(self, params): + new_object = {} + if params.get("networkId") is not None: + new_object["networkId"] = params.get( + "networkId") + if params.get("deviceId") is not None: + new_object["deviceId"] = params.get( + "deviceId") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="sm", + function='getNetworkSmDeviceNetworkAdapters', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_sm_devices_performance_history_info.py b/ansible_collections/cisco/meraki/plugins/action/networks_sm_devices_performance_history_info.py new file mode 100644 index 000000000..d955bf63d --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_sm_devices_performance_history_info.py @@ -0,0 +1,112 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + networkId=dict(type="str"), + deviceId=dict(type="str"), + perPage=dict(type="int"), + total_pages=dict(type="int"), + direction=dict(type="str"), + startingAfter=dict(type="str"), + endingBefore=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_all(self, params): + new_object = {} + if params.get("networkId") is not None: + new_object["networkId"] = params.get( + "networkId") + if params.get("deviceId") is not None: + new_object["deviceId"] = params.get( + "deviceId") + if params.get("perPage") is not None: + new_object["perPage"] = params.get( + "perPage") + new_object['total_pages'] = params.get( + "total_pages") or 1 + new_object['direction'] = params.get( + "direction") or "next" + if params.get("startingAfter") is not None: + new_object["startingAfter"] = params.get( + "startingAfter") + if params.get("endingBefore") is not None: + new_object["endingBefore"] = params.get( + "endingBefore") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="sm", + function='getNetworkSmDevicePerformanceHistory', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_sm_devices_refresh_details.py b/ansible_collections/cisco/meraki/plugins/action/networks_sm_devices_refresh_details.py new file mode 100644 index 000000000..dfa0283c6 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_sm_devices_refresh_details.py @@ -0,0 +1,89 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguements specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + networkId=dict(type="str"), + deviceId=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = False + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_object(self, params): + new_object = dict( + networkId=params.get("networkId"), + deviceId=params.get("deviceId"), + ) + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="sm", + function='refreshNetworkSmDeviceDetails', + op_modifies=True, + params=self.get_object(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_sm_devices_security_centers_info.py b/ansible_collections/cisco/meraki/plugins/action/networks_sm_devices_security_centers_info.py new file mode 100644 index 000000000..e3e70c1d7 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_sm_devices_security_centers_info.py @@ -0,0 +1,94 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + networkId=dict(type="str"), + deviceId=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_all(self, params): + new_object = {} + if params.get("networkId") is not None: + new_object["networkId"] = params.get( + "networkId") + if params.get("deviceId") is not None: + new_object["deviceId"] = params.get( + "deviceId") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="sm", + function='getNetworkSmDeviceSoftwares', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_sm_devices_unenroll.py b/ansible_collections/cisco/meraki/plugins/action/networks_sm_devices_unenroll.py new file mode 100644 index 000000000..d9373e6e1 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_sm_devices_unenroll.py @@ -0,0 +1,89 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguements specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + networkId=dict(type="str"), + deviceId=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = False + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_object(self, params): + new_object = dict( + networkId=params.get("networkId"), + deviceId=params.get("deviceId"), + ) + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="sm", + function='unenrollNetworkSmDevice', + op_modifies=True, + params=self.get_object(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_sm_devices_wipe.py b/ansible_collections/cisco/meraki/plugins/action/networks_sm_devices_wipe.py new file mode 100644 index 000000000..1b20cad81 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_sm_devices_wipe.py @@ -0,0 +1,95 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguements specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + wifiMac=dict(type="str"), + id=dict(type="str"), + serial=dict(type="str"), + pin=dict(type="int"), + networkId=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = False + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_object(self, params): + new_object = dict( + wifiMac=params.get("wifiMac"), + id=params.get("id"), + serial=params.get("serial"), + pin=params.get("pin"), + networkId=params.get("networkId"), + ) + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="sm", + function='wipeNetworkSmDevices', + op_modifies=True, + params=self.get_object(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_sm_devices_wlan_lists_info.py b/ansible_collections/cisco/meraki/plugins/action/networks_sm_devices_wlan_lists_info.py new file mode 100644 index 000000000..305bb024e --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_sm_devices_wlan_lists_info.py @@ -0,0 +1,94 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + networkId=dict(type="str"), + deviceId=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_all(self, params): + new_object = {} + if params.get("networkId") is not None: + new_object["networkId"] = params.get( + "networkId") + if params.get("deviceId") is not None: + new_object["deviceId"] = params.get( + "deviceId") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="sm", + function='getNetworkSmDeviceWlanLists', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_sm_profiles_info.py b/ansible_collections/cisco/meraki/plugins/action/networks_sm_profiles_info.py new file mode 100644 index 000000000..44ab17a59 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_sm_profiles_info.py @@ -0,0 +1,90 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + networkId=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_all(self, params): + new_object = {} + if params.get("networkId") is not None: + new_object["networkId"] = params.get( + "networkId") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="sm", + function='getNetworkSmProfiles', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_sm_target_groups.py b/ansible_collections/cisco/meraki/plugins/action/networks_sm_target_groups.py new file mode 100644 index 000000000..3c70b117b --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_sm_target_groups.py @@ -0,0 +1,317 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or +# https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, + meraki_compare_equality, + get_dict_result, +) +from ansible_collections.cisco.meraki.plugins.plugin_utils.exceptions import ( + InconsistentParameters, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + state=dict(type="str", default="present", choices=["present", "absent"]), + name=dict(type="str"), + scope=dict(type="str"), + networkId=dict(type="str"), + targetGroupId=dict(type="str"), +)) + +required_if = [ + ("state", "present", ["name", "networkId", "targetGroupId"], True), + ("state", "absent", ["name", "networkId", "targetGroupId"], True), +] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class NetworksSmTargetGroups(object): + def __init__(self, params, meraki): + self.meraki = meraki + self.new_object = dict( + name=params.get("name"), + scope=params.get("scope"), + networkId=params.get("networkId"), + targetGroupId=params.get("targetGroupId"), + ) + + def get_all_params(self, name=None, id=None): + new_object_params = {} + if self.new_object.get('withDetails') is not None or self.new_object.get('with_details') is not None: + new_object_params['withDetails'] = self.new_object.get('withDetails') or \ + self.new_object.get('with_details') + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + return new_object_params + + def get_params_by_id(self, name=None, id=None): + new_object_params = {} + if self.new_object.get('withDetails') is not None or self.new_object.get('with_details') is not None: + new_object_params['withDetails'] = self.new_object.get('withDetails') or \ + self.new_object.get('with_details') + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + if self.new_object.get('targetGroupId') is not None or self.new_object.get('target_group_id') is not None: + new_object_params['targetGroupId'] = self.new_object.get('targetGroupId') or \ + self.new_object.get('target_group_id') + return new_object_params + + def create_params(self): + new_object_params = {} + if self.new_object.get('name') is not None or self.new_object.get('name') is not None: + new_object_params['name'] = self.new_object.get('name') or \ + self.new_object.get('name') + if self.new_object.get('scope') is not None or self.new_object.get('scope') is not None: + new_object_params['scope'] = self.new_object.get('scope') or \ + self.new_object.get('scope') + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + return new_object_params + + def delete_by_id_params(self): + new_object_params = {} + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + if self.new_object.get('targetGroupId') is not None or self.new_object.get('target_group_id') is not None: + new_object_params['targetGroupId'] = self.new_object.get('targetGroupId') or \ + self.new_object.get('target_group_id') + return new_object_params + + def update_by_id_params(self): + new_object_params = {} + if self.new_object.get('name') is not None or self.new_object.get('name') is not None: + new_object_params['name'] = self.new_object.get('name') or \ + self.new_object.get('name') + if self.new_object.get('scope') is not None or self.new_object.get('scope') is not None: + new_object_params['scope'] = self.new_object.get('scope') or \ + self.new_object.get('scope') + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + if self.new_object.get('targetGroupId') is not None or self.new_object.get('target_group_id') is not None: + new_object_params['targetGroupId'] = self.new_object.get('targetGroupId') or \ + self.new_object.get('target_group_id') + return new_object_params + + def get_object_by_name(self, name): + result = None + # NOTE: Does not have a get by name method or it is in another action + try: + items = self.meraki.exec_meraki( + family="sm", + function="getNetworkSmTargetGroups", + params=self.get_all_params(name=name), + ) + if isinstance(items, dict): + if 'response' in items: + items = items.get('response') + result = get_dict_result(items, 'name', name) + if result is None: + result = items + except Exception as e: + print("Error: ", e) + result = None + return result + + def get_object_by_id(self, id): + result = None + try: + items = self.meraki.exec_meraki( + family="sm", + function="getNetworkSmTargetGroup", + params=self.get_params_by_id() + ) + if isinstance(items, dict): + if 'response' in items: + items = items.get('response') + result = get_dict_result(items, 'targetGroupId', id) + except Exception as e: + print("Error: ", e) + result = None + return result + + def exists(self): + id_exists = False + name_exists = False + prev_obj = None + o_id = self.new_object.get("id") + o_id = o_id or self.new_object.get( + "target_group_id") or self.new_object.get("targetGroupId") + name = self.new_object.get("name") + if o_id: + prev_obj = self.get_object_by_id(o_id) + id_exists = prev_obj is not None and isinstance(prev_obj, dict) + if not id_exists and name: + prev_obj = self.get_object_by_name(name) + name_exists = prev_obj is not None and isinstance(prev_obj, dict) + if name_exists: + _id = prev_obj.get("id") + _id = _id or prev_obj.get("targetGroupId") + if id_exists and name_exists and o_id != _id: + raise InconsistentParameters( + "The 'id' and 'name' params don't refer to the same object") + if _id: + self.new_object.update(dict(id=_id)) + self.new_object.update(dict(targetGroupId=_id)) + if _id: + prev_obj = self.get_object_by_id(_id) + it_exists = prev_obj is not None and isinstance(prev_obj, dict) + return (it_exists, prev_obj) + + def requires_update(self, current_obj): + requested_obj = self.new_object + + obj_params = [ + ("name", "name"), + ("scope", "scope"), + ("networkId", "networkId"), + ("targetGroupId", "targetGroupId"), + ] + # Method 1. Params present in request (Ansible) obj are the same as the current (DNAC) params + # If any does not have eq params, it requires update + return any(not meraki_compare_equality(current_obj.get(meraki_param), + requested_obj.get(ansible_param)) + for (meraki_param, ansible_param) in obj_params) + + def create(self): + result = self.meraki.exec_meraki( + family="sm", + function="createNetworkSmTargetGroup", + params=self.create_params(), + op_modifies=True, + ) + return result + + def update(self): + id = self.new_object.get("id") + id = id or self.new_object.get("targetGroupId") + name = self.new_object.get("name") + result = None + if not id: + prev_obj_name = self.get_object_by_name(name) + id_ = None + if prev_obj_name: + id_ = prev_obj_name.get("id") + id_ = id_ or prev_obj_name.get("targetGroupId") + if id_: + self.new_object.update(dict(targetGroupId=id_)) + result = self.meraki.exec_meraki( + family="sm", + function="updateNetworkSmTargetGroup", + params=self.update_by_id_params(), + op_modifies=True, + ) + return result + + def delete(self): + id = self.new_object.get("id") + id = id or self.new_object.get("targetGroupId") + name = self.new_object.get("name") + result = None + if not id: + prev_obj_name = self.get_object_by_name(name) + id_ = None + if prev_obj_name: + id_ = prev_obj_name.get("id") + id_ = id_ or prev_obj_name.get("targetGroupId") + if id_: + self.new_object.update(dict(targetGroupId=id_)) + result = self.meraki.exec_meraki( + family="sm", + function="deleteNetworkSmTargetGroup", + params=self.delete_by_id_params(), + ) + return result + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = False + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + meraki = MERAKI(self._task.args) + obj = NetworksSmTargetGroups(self._task.args, meraki) + + state = self._task.args.get("state") + + response = None + + if state == "present": + (obj_exists, prev_obj) = obj.exists() + if obj_exists: + if obj.requires_update(prev_obj): + response = obj.update() + meraki.object_updated() + else: + response = prev_obj + meraki.object_already_present() + else: + response = obj.create() + meraki.object_created() + + elif state == "absent": + (obj_exists, prev_obj) = obj.exists() + if obj_exists: + response = obj.delete() + meraki.object_deleted() + else: + meraki.object_already_absent() + + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_sm_target_groups_info.py b/ansible_collections/cisco/meraki/plugins/action/networks_sm_target_groups_info.py new file mode 100644 index 000000000..ca5858ccc --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_sm_target_groups_info.py @@ -0,0 +1,119 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + networkId=dict(type="str"), + withDetails=dict(type="bool"), + targetGroupId=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_object(self, params): + new_object = {} + if params.get("networkId") is not None: + new_object["networkId"] = params.get( + "networkId") + if params.get("targetGroupId") is not None: + new_object["targetGroupId"] = params.get( + "targetGroupId") + if params.get("withDetails") is not None: + new_object["withDetails"] = params.get( + "withDetails") + return new_object + + def get_all(self, params): + new_object = {} + if params.get("networkId") is not None: + new_object["networkId"] = params.get( + "networkId") + if params.get("withDetails") is not None: + new_object["withDetails"] = params.get( + "withDetails") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + id = self._task.args.get("targetGroupId") + if id: + response = meraki.exec_meraki( + family="sm", + function='getNetworkSmTargetGroup', + params=self.get_object(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result + if not id: + response = meraki.exec_meraki( + family="sm", + function='getNetworkSmTargetGroups', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_sm_trusted_access_configs_info.py b/ansible_collections/cisco/meraki/plugins/action/networks_sm_trusted_access_configs_info.py new file mode 100644 index 000000000..d0ee8c52b --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_sm_trusted_access_configs_info.py @@ -0,0 +1,108 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + networkId=dict(type="str"), + perPage=dict(type="int"), + total_pages=dict(type="int"), + direction=dict(type="str"), + startingAfter=dict(type="str"), + endingBefore=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_all(self, params): + new_object = {} + if params.get("networkId") is not None: + new_object["networkId"] = params.get( + "networkId") + if params.get("perPage") is not None: + new_object["perPage"] = params.get( + "perPage") + new_object['total_pages'] = params.get( + "total_pages") or 1 + new_object['direction'] = params.get( + "direction") or "next" + if params.get("startingAfter") is not None: + new_object["startingAfter"] = params.get( + "startingAfter") + if params.get("endingBefore") is not None: + new_object["endingBefore"] = params.get( + "endingBefore") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="sm", + function='getNetworkSmTrustedAccessConfigs', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_sm_user_access_devices_delete.py b/ansible_collections/cisco/meraki/plugins/action/networks_sm_user_access_devices_delete.py new file mode 100644 index 000000000..c4d46e299 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_sm_user_access_devices_delete.py @@ -0,0 +1,88 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguements specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + networkId=dict(type="str"), + userAccessDeviceId=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = False + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_object(self, params): + new_object = dict( + networkId=params.get("networkId"), + userAccessDeviceId=params.get("userAccessDeviceId"), + ) + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="sm", + function="deleteNetworkSmUserAccessDevice", + params=self.get_object(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_sm_user_access_devices_info.py b/ansible_collections/cisco/meraki/plugins/action/networks_sm_user_access_devices_info.py new file mode 100644 index 000000000..55a0a99bf --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_sm_user_access_devices_info.py @@ -0,0 +1,108 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + networkId=dict(type="str"), + perPage=dict(type="int"), + total_pages=dict(type="int"), + direction=dict(type="str"), + startingAfter=dict(type="str"), + endingBefore=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_all(self, params): + new_object = {} + if params.get("networkId") is not None: + new_object["networkId"] = params.get( + "networkId") + if params.get("perPage") is not None: + new_object["perPage"] = params.get( + "perPage") + new_object['total_pages'] = params.get( + "total_pages") or 1 + new_object['direction'] = params.get( + "direction") or "next" + if params.get("startingAfter") is not None: + new_object["startingAfter"] = params.get( + "startingAfter") + if params.get("endingBefore") is not None: + new_object["endingBefore"] = params.get( + "endingBefore") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="sm", + function='getNetworkSmUserAccessDevices', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_sm_users_device_profiles_info.py b/ansible_collections/cisco/meraki/plugins/action/networks_sm_users_device_profiles_info.py new file mode 100644 index 000000000..a3244c1b6 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_sm_users_device_profiles_info.py @@ -0,0 +1,94 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + networkId=dict(type="str"), + userId=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_all(self, params): + new_object = {} + if params.get("networkId") is not None: + new_object["networkId"] = params.get( + "networkId") + if params.get("userId") is not None: + new_object["userId"] = params.get( + "userId") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="sm", + function='getNetworkSmUserDeviceProfiles', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_sm_users_info.py b/ansible_collections/cisco/meraki/plugins/action/networks_sm_users_info.py new file mode 100644 index 000000000..7a7e7668c --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_sm_users_info.py @@ -0,0 +1,106 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + networkId=dict(type="str"), + ids=dict(type="list"), + usernames=dict(type="list"), + emails=dict(type="list"), + scope=dict(type="list"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_all(self, params): + new_object = {} + if params.get("networkId") is not None: + new_object["networkId"] = params.get( + "networkId") + if params.get("ids") is not None: + new_object["ids"] = params.get( + "ids") + if params.get("usernames") is not None: + new_object["usernames"] = params.get( + "usernames") + if params.get("emails") is not None: + new_object["emails"] = params.get( + "emails") + if params.get("scope") is not None: + new_object["scope"] = params.get( + "scope") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="sm", + function='getNetworkSmUsers', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_sm_users_softwares_info.py b/ansible_collections/cisco/meraki/plugins/action/networks_sm_users_softwares_info.py new file mode 100644 index 000000000..5ff7efea7 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_sm_users_softwares_info.py @@ -0,0 +1,94 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + networkId=dict(type="str"), + userId=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_all(self, params): + new_object = {} + if params.get("networkId") is not None: + new_object["networkId"] = params.get( + "networkId") + if params.get("userId") is not None: + new_object["userId"] = params.get( + "userId") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="sm", + function='getNetworkSmUserSoftwares', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_snmp.py b/ansible_collections/cisco/meraki/plugins/action/networks_snmp.py new file mode 100644 index 000000000..cb8ce38c7 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_snmp.py @@ -0,0 +1,212 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or +# https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, + meraki_compare_equality, + get_dict_result, +) +from ansible_collections.cisco.meraki.plugins.plugin_utils.exceptions import ( + InconsistentParameters, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + state=dict(type="str", default="present", choices=["present"]), + access=dict(type="str"), + communityString=dict(type="str"), + users=dict(type="list"), + networkId=dict(type="str"), +)) + +required_if = [ + ("state", "present", ["networkId"], True), +] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class NetworksSnmp(object): + def __init__(self, params, meraki): + self.meraki = meraki + self.new_object = dict( + access=params.get("access"), + communityString=params.get("communityString"), + users=params.get("users"), + network_id=params.get("networkId"), + ) + + def get_all_params(self, name=None, id=None): + new_object_params = {} + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + return new_object_params + + def update_all_params(self): + new_object_params = {} + if self.new_object.get('access') is not None or self.new_object.get('access') is not None: + new_object_params['access'] = self.new_object.get('access') or \ + self.new_object.get('access') + if self.new_object.get('communityString') is not None or self.new_object.get('community_string') is not None: + new_object_params['communityString'] = self.new_object.get('communityString') or \ + self.new_object.get('community_string') + if self.new_object.get('users') is not None or self.new_object.get('users') is not None: + new_object_params['users'] = self.new_object.get('users') or \ + self.new_object.get('users') + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + return new_object_params + + def get_object_by_name(self, name): + result = None + # NOTE: Does not have a get by name method, using get all + try: + items = self.meraki.exec_meraki( + family="networks", + function="getNetworkSnmp", + params=self.get_all_params(name=name), + ) + if isinstance(items, dict): + if 'response' in items: + items = items.get('response') + result = get_dict_result(items, 'name', name) + if result is None: + result = items + except Exception as e: + print("Error: ", e) + result = None + return result + + def get_object_by_id(self, id): + result = None + # NOTE: Does not have a get by id method or it is in another action + return result + + def exists(self): + prev_obj = None + id_exists = False + name_exists = False + o_id = self.new_object.get("networkId") or self.new_object.get("network_id") + name = self.new_object.get("name") + if o_id: + prev_obj = self.get_object_by_name(o_id) + id_exists = prev_obj is not None and isinstance(prev_obj, dict) + if not id_exists and name: + prev_obj = self.get_object_by_name(name) + name_exists = prev_obj is not None and isinstance(prev_obj, dict) + if name_exists: + _id = prev_obj.get("id") + if id_exists and name_exists and o_id != _id: + raise InconsistentParameters( + "The 'id' and 'name' params don't refer to the same object") + if _id: + self.new_object.update(dict(id=_id)) + it_exists = prev_obj is not None and isinstance(prev_obj, dict) + return (it_exists, prev_obj) + + def requires_update(self, current_obj): + requested_obj = self.new_object + + obj_params = [ + ("access", "access"), + ("communityString", "communityString"), + ("users", "users"), + ("networkId", "networkId"), + ] + # Method 1. Params present in request (Ansible) obj are the same as the current (ISE) params + # If any does not have eq params, it requires update + return any(not meraki_compare_equality(current_obj.get(meraki_param), + requested_obj.get(ansible_param)) + for (meraki_param, ansible_param) in obj_params) + + def update(self): + id = self.new_object.get("id") + name = self.new_object.get("name") + result = None + result = self.meraki.exec_meraki( + family="networks", + function="updateNetworkSnmp", + params=self.update_all_params(), + op_modifies=True, + ) + return result + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = False + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + meraki = MERAKI(self._task.args) + obj = NetworksSnmp(self._task.args, meraki) + + state = self._task.args.get("state") + + response = None + if state == "present": + (obj_exists, prev_obj) = obj.exists() + if obj_exists: + if obj.requires_update(prev_obj): + response = obj.update() + meraki.object_updated() + else: + response = prev_obj + meraki.object_already_present() + else: + meraki.fail_json( + "Object does not exists, plugin only has update") + + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_snmp_info.py b/ansible_collections/cisco/meraki/plugins/action/networks_snmp_info.py new file mode 100644 index 000000000..3111a5551 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_snmp_info.py @@ -0,0 +1,90 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + networkId=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_all(self, params): + new_object = {} + if params.get("networkId") is not None: + new_object["networkId"] = params.get( + "networkId") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="networks", + function='getNetworkSnmp', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_split.py b/ansible_collections/cisco/meraki/plugins/action/networks_split.py new file mode 100644 index 000000000..458e5e27a --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_split.py @@ -0,0 +1,87 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguements specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + networkId=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = False + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_object(self, params): + new_object = dict( + networkId=params.get("networkId"), + ) + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="networks", + function='splitNetwork', + op_modifies=True, + params=self.get_object(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_switch_access_control_lists.py b/ansible_collections/cisco/meraki/plugins/action/networks_switch_access_control_lists.py new file mode 100644 index 000000000..9819c8394 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_switch_access_control_lists.py @@ -0,0 +1,200 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or +# https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, + meraki_compare_equality, + get_dict_result, +) +from ansible_collections.cisco.meraki.plugins.plugin_utils.exceptions import ( + InconsistentParameters, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + state=dict(type="str", default="present", choices=["present"]), + rules=dict(type="list"), + networkId=dict(type="str"), +)) + +required_if = [ + ("state", "present", ["networkId"], True), +] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class NetworksSwitchAccessControlLists(object): + def __init__(self, params, meraki): + self.meraki = meraki + self.new_object = dict( + rules=params.get("rules"), + network_id=params.get("networkId"), + ) + + def get_all_params(self, name=None, id=None): + new_object_params = {} + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + return new_object_params + + def update_all_params(self): + new_object_params = {} + if self.new_object.get('rules') is not None or self.new_object.get('rules') is not None: + new_object_params['rules'] = self.new_object.get('rules') or \ + self.new_object.get('rules') + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + return new_object_params + + def get_object_by_name(self, name): + result = None + # NOTE: Does not have a get by name method, using get all + try: + items = self.meraki.exec_meraki( + family="switch", + function="getNetworkSwitchAccessControlLists", + params=self.get_all_params(name=name), + ) + if isinstance(items, dict): + if 'rules' in items: + items = items.get('rules') + result = get_dict_result(items, 'name', name) + if result is None: + result = items + except Exception as e: + print("Error: ", e) + result = None + return result + + def get_object_by_id(self, id): + result = None + # NOTE: Does not have a get by id method or it is in another action + return result + + def exists(self): + prev_obj = None + id_exists = False + name_exists = False + o_id = self.new_object.get("networkId") or self.new_object.get("network_id") + name = self.new_object.get("name") + if o_id: + prev_obj = self.get_object_by_name(o_id) + id_exists = prev_obj is not None and isinstance(prev_obj, dict) + if not id_exists and name: + prev_obj = self.get_object_by_name(name) + name_exists = prev_obj is not None and isinstance(prev_obj, dict) + if name_exists: + _id = prev_obj.get("id") + if id_exists and name_exists and o_id != _id: + raise InconsistentParameters( + "The 'id' and 'name' params don't refer to the same object") + if _id: + self.new_object.update(dict(id=_id)) + it_exists = prev_obj is not None and isinstance(prev_obj, dict) + return (it_exists, prev_obj) + + def requires_update(self, current_obj): + requested_obj = self.new_object + + obj_params = [ + ("rules", "rules"), + ("networkId", "networkId"), + ] + # Method 1. Params present in request (Ansible) obj are the same as the current (ISE) params + # If any does not have eq params, it requires update + return any(not meraki_compare_equality(current_obj.get(meraki_param), + requested_obj.get(ansible_param)) + for (meraki_param, ansible_param) in obj_params) + + def update(self): + id = self.new_object.get("id") + name = self.new_object.get("name") + result = None + result = self.meraki.exec_meraki( + family="switch", + function="updateNetworkSwitchAccessControlLists", + params=self.update_all_params(), + op_modifies=True, + ) + return result + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = False + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + meraki = MERAKI(self._task.args) + obj = NetworksSwitchAccessControlLists(self._task.args, meraki) + + state = self._task.args.get("state") + + response = None + if state == "present": + (obj_exists, prev_obj) = obj.exists() + if obj_exists: + if obj.requires_update(prev_obj): + response = obj.update() + meraki.object_updated() + else: + response = prev_obj + meraki.object_already_present() + else: + meraki.fail_json( + "Object does not exists, plugin only has update") + + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_switch_access_control_lists_info.py b/ansible_collections/cisco/meraki/plugins/action/networks_switch_access_control_lists_info.py new file mode 100644 index 000000000..12189e536 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_switch_access_control_lists_info.py @@ -0,0 +1,90 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + networkId=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_all(self, params): + new_object = {} + if params.get("networkId") is not None: + new_object["networkId"] = params.get( + "networkId") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="switch", + function='getNetworkSwitchAccessControlLists', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_switch_access_policies.py b/ansible_collections/cisco/meraki/plugins/action/networks_switch_access_policies.py new file mode 100644 index 000000000..a56a7f0dd --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_switch_access_policies.py @@ -0,0 +1,448 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or +# https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, + meraki_compare_equality, + get_dict_result, +) +from ansible_collections.cisco.meraki.plugins.plugin_utils.exceptions import ( + InconsistentParameters, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + state=dict(type="str", default="present", choices=["present", "absent"]), + name=dict(type="str"), + radiusServers=dict(type="list"), + radius=dict(type="dict"), + guestPortBouncing=dict(type="bool"), + radiusTestingEnabled=dict(type="bool"), + radiusCoaSupportEnabled=dict(type="bool"), + radiusAccountingEnabled=dict(type="bool"), + radiusAccountingServers=dict(type="list"), + radiusGroupAttribute=dict(type="str"), + hostMode=dict(type="str"), + accessPolicyType=dict(type="str"), + increaseAccessSpeed=dict(type="bool"), + guestVlanId=dict(type="int"), + dot1x=dict(type="dict"), + voiceVlanClients=dict(type="bool"), + urlRedirectWalledGardenEnabled=dict(type="bool"), + urlRedirectWalledGardenRanges=dict(type="list"), + networkId=dict(type="str"), + accessPolicyNumber=dict(type="str"), +)) + +required_if = [ + ("state", "present", ["accessPolicyNumber", "name", "networkId"], True), + ("state", "absent", ["accessPolicyNumber", "name", "networkId"], True), +] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class NetworksSwitchAccessPolicies(object): + def __init__(self, params, meraki): + self.meraki = meraki + self.new_object = dict( + name=params.get("name"), + radiusServers=params.get("radiusServers"), + radius=params.get("radius"), + guestPortBouncing=params.get("guestPortBouncing"), + radiusTestingEnabled=params.get("radiusTestingEnabled"), + radiusCoaSupportEnabled=params.get("radiusCoaSupportEnabled"), + radiusAccountingEnabled=params.get("radiusAccountingEnabled"), + radiusAccountingServers=params.get("radiusAccountingServers"), + radiusGroupAttribute=params.get("radiusGroupAttribute"), + hostMode=params.get("hostMode"), + accessPolicyType=params.get("accessPolicyType"), + increaseAccessSpeed=params.get("increaseAccessSpeed"), + guestVlanId=params.get("guestVlanId"), + dot1x=params.get("dot1x"), + voiceVlanClients=params.get("voiceVlanClients"), + urlRedirectWalledGardenEnabled=params.get( + "urlRedirectWalledGardenEnabled"), + urlRedirectWalledGardenRanges=params.get( + "urlRedirectWalledGardenRanges"), + networkId=params.get("networkId"), + accessPolicyNumber=params.get("accessPolicyNumber"), + ) + + def get_all_params(self, name=None, id=None): + new_object_params = {} + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + return new_object_params + + def get_params_by_id(self, name=None, id=None): + new_object_params = {} + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + if self.new_object.get('accessPolicyNumber') is not None or self.new_object.get('access_policy_number') is not None: + new_object_params['accessPolicyNumber'] = self.new_object.get('accessPolicyNumber') or \ + self.new_object.get('access_policy_number') + return new_object_params + + def create_params(self): + new_object_params = {} + if self.new_object.get('name') is not None or self.new_object.get('name') is not None: + new_object_params['name'] = self.new_object.get('name') or \ + self.new_object.get('name') + if self.new_object.get('radiusServers') is not None or self.new_object.get('radius_servers') is not None: + new_object_params['radiusServers'] = self.new_object.get('radiusServers') or \ + self.new_object.get('radius_servers') + if self.new_object.get('radius') is not None or self.new_object.get('radius') is not None: + new_object_params['radius'] = self.new_object.get('radius') or \ + self.new_object.get('radius') + if self.new_object.get('guestPortBouncing') is not None or self.new_object.get('guest_port_bouncing') is not None: + new_object_params['guestPortBouncing'] = self.new_object.get( + 'guestPortBouncing') + if self.new_object.get('radiusTestingEnabled') is not None or self.new_object.get('radius_testing_enabled') is not None: + new_object_params['radiusTestingEnabled'] = self.new_object.get( + 'radiusTestingEnabled') + if self.new_object.get('radiusCoaSupportEnabled') is not None or self.new_object.get('radius_coa_support_enabled') is not None: + new_object_params['radiusCoaSupportEnabled'] = self.new_object.get( + 'radiusCoaSupportEnabled') + if self.new_object.get('radiusAccountingEnabled') is not None or self.new_object.get('radius_accounting_enabled') is not None: + new_object_params['radiusAccountingEnabled'] = self.new_object.get( + 'radiusAccountingEnabled') + if self.new_object.get('radiusAccountingServers') is not None or self.new_object.get('radius_accounting_servers') is not None: + new_object_params['radiusAccountingServers'] = self.new_object.get('radiusAccountingServers') or \ + self.new_object.get('radius_accounting_servers') + if self.new_object.get('radiusGroupAttribute') is not None or self.new_object.get('radius_group_attribute') is not None: + new_object_params['radiusGroupAttribute'] = self.new_object.get('radiusGroupAttribute') or \ + self.new_object.get('radius_group_attribute') + if self.new_object.get('hostMode') is not None or self.new_object.get('host_mode') is not None: + new_object_params['hostMode'] = self.new_object.get('hostMode') or \ + self.new_object.get('host_mode') + if self.new_object.get('accessPolicyType') is not None or self.new_object.get('access_policy_type') is not None: + new_object_params['accessPolicyType'] = self.new_object.get('accessPolicyType') or \ + self.new_object.get('access_policy_type') + if self.new_object.get('increaseAccessSpeed') is not None or self.new_object.get('increase_access_speed') is not None: + new_object_params['increaseAccessSpeed'] = self.new_object.get( + 'increaseAccessSpeed') + if self.new_object.get('guestVlanId') is not None or self.new_object.get('guest_vlan_id') is not None: + new_object_params['guestVlanId'] = self.new_object.get('guestVlanId') or \ + self.new_object.get('guest_vlan_id') + if self.new_object.get('dot1x') is not None or self.new_object.get('dot1x') is not None: + new_object_params['dot1x'] = self.new_object.get('dot1x') or \ + self.new_object.get('dot1x') + if self.new_object.get('voiceVlanClients') is not None or self.new_object.get('voice_vlan_clients') is not None: + new_object_params['voiceVlanClients'] = self.new_object.get( + 'voiceVlanClients') + if self.new_object.get('urlRedirectWalledGardenEnabled') is not None or self.new_object.get('url_redirect_walled_garden_enabled') is not None: + new_object_params['urlRedirectWalledGardenEnabled'] = self.new_object.get( + 'urlRedirectWalledGardenEnabled') + if self.new_object.get('urlRedirectWalledGardenRanges') is not None or self.new_object.get('url_redirect_walled_garden_ranges') is not None: + new_object_params['urlRedirectWalledGardenRanges'] = self.new_object.get('urlRedirectWalledGardenRanges') or \ + self.new_object.get('url_redirect_walled_garden_ranges') + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + return new_object_params + + def delete_by_id_params(self): + new_object_params = {} + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + if self.new_object.get('accessPolicyNumber') is not None or self.new_object.get('access_policy_number') is not None: + new_object_params['accessPolicyNumber'] = self.new_object.get('accessPolicyNumber') or \ + self.new_object.get('access_policy_number') + return new_object_params + + def update_by_id_params(self): + new_object_params = {} + if self.new_object.get('name') is not None or self.new_object.get('name') is not None: + new_object_params['name'] = self.new_object.get('name') or \ + self.new_object.get('name') + if self.new_object.get('radiusServers') is not None or self.new_object.get('radius_servers') is not None: + new_object_params['radiusServers'] = self.new_object.get('radiusServers') or \ + self.new_object.get('radius_servers') + if self.new_object.get('radius') is not None or self.new_object.get('radius') is not None: + new_object_params['radius'] = self.new_object.get('radius') or \ + self.new_object.get('radius') + if self.new_object.get('guestPortBouncing') is not None or self.new_object.get('guest_port_bouncing') is not None: + new_object_params['guestPortBouncing'] = self.new_object.get( + 'guestPortBouncing') + if self.new_object.get('radiusTestingEnabled') is not None or self.new_object.get('radius_testing_enabled') is not None: + new_object_params['radiusTestingEnabled'] = self.new_object.get( + 'radiusTestingEnabled') + if self.new_object.get('radiusCoaSupportEnabled') is not None or self.new_object.get('radius_coa_support_enabled') is not None: + new_object_params['radiusCoaSupportEnabled'] = self.new_object.get( + 'radiusCoaSupportEnabled') + if self.new_object.get('radiusAccountingEnabled') is not None or self.new_object.get('radius_accounting_enabled') is not None: + new_object_params['radiusAccountingEnabled'] = self.new_object.get( + 'radiusAccountingEnabled') + if self.new_object.get('radiusAccountingServers') is not None or self.new_object.get('radius_accounting_servers') is not None: + new_object_params['radiusAccountingServers'] = self.new_object.get('radiusAccountingServers') or \ + self.new_object.get('radius_accounting_servers') + if self.new_object.get('radiusGroupAttribute') is not None or self.new_object.get('radius_group_attribute') is not None: + new_object_params['radiusGroupAttribute'] = self.new_object.get('radiusGroupAttribute') or \ + self.new_object.get('radius_group_attribute') + if self.new_object.get('hostMode') is not None or self.new_object.get('host_mode') is not None: + new_object_params['hostMode'] = self.new_object.get('hostMode') or \ + self.new_object.get('host_mode') + if self.new_object.get('accessPolicyType') is not None or self.new_object.get('access_policy_type') is not None: + new_object_params['accessPolicyType'] = self.new_object.get('accessPolicyType') or \ + self.new_object.get('access_policy_type') + if self.new_object.get('increaseAccessSpeed') is not None or self.new_object.get('increase_access_speed') is not None: + new_object_params['increaseAccessSpeed'] = self.new_object.get( + 'increaseAccessSpeed') + if self.new_object.get('guestVlanId') is not None or self.new_object.get('guest_vlan_id') is not None: + new_object_params['guestVlanId'] = self.new_object.get('guestVlanId') or \ + self.new_object.get('guest_vlan_id') + if self.new_object.get('dot1x') is not None or self.new_object.get('dot1x') is not None: + new_object_params['dot1x'] = self.new_object.get('dot1x') or \ + self.new_object.get('dot1x') + if self.new_object.get('voiceVlanClients') is not None or self.new_object.get('voice_vlan_clients') is not None: + new_object_params['voiceVlanClients'] = self.new_object.get( + 'voiceVlanClients') + if self.new_object.get('urlRedirectWalledGardenEnabled') is not None or self.new_object.get('url_redirect_walled_garden_enabled') is not None: + new_object_params['urlRedirectWalledGardenEnabled'] = self.new_object.get( + 'urlRedirectWalledGardenEnabled') + if self.new_object.get('urlRedirectWalledGardenRanges') is not None or self.new_object.get('url_redirect_walled_garden_ranges') is not None: + new_object_params['urlRedirectWalledGardenRanges'] = self.new_object.get('urlRedirectWalledGardenRanges') or \ + self.new_object.get('url_redirect_walled_garden_ranges') + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + if self.new_object.get('accessPolicyNumber') is not None or self.new_object.get('access_policy_number') is not None: + new_object_params['accessPolicyNumber'] = self.new_object.get('accessPolicyNumber') or \ + self.new_object.get('access_policy_number') + return new_object_params + + def get_object_by_name(self, name): + result = None + # NOTE: Does not have a get by name method or it is in another action + try: + items = self.meraki.exec_meraki( + family="switch", + function="getNetworkSwitchAccessPolicies", + params=self.get_all_params(name=name), + ) + if isinstance(items, dict): + if 'response' in items: + items = items.get('response') + result = get_dict_result(items, 'name', name) + if result is None: + result = items + except Exception as e: + print("Error: ", e) + result = None + return result + + def get_object_by_id(self, id): + result = None + try: + items = self.meraki.exec_meraki( + family="switch", + function="getNetworkSwitchAccessPolicy", + params=self.get_params_by_id() + ) + if isinstance(items, dict): + if 'response' in items: + items = items.get('response') + result = get_dict_result(items, 'accessPolicyNumber', id) + except Exception as e: + print("Error: ", e) + result = None + return result + + def exists(self): + id_exists = False + name_exists = False + prev_obj = None + o_id = self.new_object.get("id") + o_id = o_id or self.new_object.get( + "access_policy_number") or self.new_object.get("accessPolicyNumber") + name = self.new_object.get("name") + if o_id: + prev_obj = self.get_object_by_id(o_id) + id_exists = prev_obj is not None and isinstance(prev_obj, dict) + if not id_exists and name: + prev_obj = self.get_object_by_name(name) + name_exists = prev_obj is not None and isinstance(prev_obj, dict) + if name_exists: + _id = prev_obj.get("id") + _id = _id or prev_obj.get("accessPolicyNumber") + if id_exists and name_exists and o_id != _id: + raise InconsistentParameters( + "The 'id' and 'name' params don't refer to the same object") + if _id: + self.new_object.update(dict(id=_id)) + self.new_object.update(dict(accessPolicyNumber=_id)) + if _id: + prev_obj = self.get_object_by_id(_id) + it_exists = prev_obj is not None and isinstance(prev_obj, dict) + return (it_exists, prev_obj) + + def requires_update(self, current_obj): + requested_obj = self.new_object + + obj_params = [ + ("name", "name"), + ("radiusServers", "radiusServers"), + ("radius", "radius"), + ("guestPortBouncing", "guestPortBouncing"), + ("radiusTestingEnabled", "radiusTestingEnabled"), + ("radiusCoaSupportEnabled", "radiusCoaSupportEnabled"), + ("radiusAccountingEnabled", "radiusAccountingEnabled"), + ("radiusAccountingServers", "radiusAccountingServers"), + ("radiusGroupAttribute", "radiusGroupAttribute"), + ("hostMode", "hostMode"), + ("accessPolicyType", "accessPolicyType"), + ("increaseAccessSpeed", "increaseAccessSpeed"), + ("guestVlanId", "guestVlanId"), + ("dot1x", "dot1x"), + ("voiceVlanClients", "voiceVlanClients"), + ("urlRedirectWalledGardenEnabled", "urlRedirectWalledGardenEnabled"), + ("urlRedirectWalledGardenRanges", "urlRedirectWalledGardenRanges"), + ("networkId", "networkId"), + ("accessPolicyNumber", "accessPolicyNumber"), + ] + # Method 1. Params present in request (Ansible) obj are the same as the current (DNAC) params + # If any does not have eq params, it requires update + return any(not meraki_compare_equality(current_obj.get(meraki_param), + requested_obj.get(ansible_param)) + for (meraki_param, ansible_param) in obj_params) + + def create(self): + result = self.meraki.exec_meraki( + family="switch", + function="createNetworkSwitchAccessPolicy", + params=self.create_params(), + op_modifies=True, + ) + return result + + def update(self): + id = self.new_object.get("id") + id = id or self.new_object.get("accessPolicyNumber") + name = self.new_object.get("name") + result = None + if not id: + prev_obj_name = self.get_object_by_name(name) + id_ = None + if prev_obj_name: + id_ = prev_obj_name.get("id") + id_ = id_ or prev_obj_name.get("accessPolicyNumber") + if id_: + self.new_object.update(dict(accessPolicyNumber=id_)) + result = self.meraki.exec_meraki( + family="switch", + function="updateNetworkSwitchAccessPolicy", + params=self.update_by_id_params(), + op_modifies=True, + ) + return result + + def delete(self): + id = self.new_object.get("id") + id = id or self.new_object.get("accessPolicyNumber") + name = self.new_object.get("name") + result = None + if not id: + prev_obj_name = self.get_object_by_name(name) + id_ = None + if prev_obj_name: + id_ = prev_obj_name.get("id") + id_ = id_ or prev_obj_name.get("accessPolicyNumber") + if id_: + self.new_object.update(dict(accessPolicyNumber=id_)) + result = self.meraki.exec_meraki( + family="switch", + function="deleteNetworkSwitchAccessPolicy", + params=self.delete_by_id_params(), + ) + return result + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = False + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + meraki = MERAKI(self._task.args) + obj = NetworksSwitchAccessPolicies(self._task.args, meraki) + + state = self._task.args.get("state") + + response = None + + if state == "present": + (obj_exists, prev_obj) = obj.exists() + if obj_exists: + if obj.requires_update(prev_obj): + response = obj.update() + meraki.object_updated() + else: + response = prev_obj + meraki.object_already_present() + else: + response = obj.create() + meraki.object_created() + + elif state == "absent": + (obj_exists, prev_obj) = obj.exists() + if obj_exists: + response = obj.delete() + meraki.object_deleted() + else: + meraki.object_already_absent() + + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_switch_access_policies_info.py b/ansible_collections/cisco/meraki/plugins/action/networks_switch_access_policies_info.py new file mode 100644 index 000000000..af5cc28fa --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_switch_access_policies_info.py @@ -0,0 +1,112 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + networkId=dict(type="str"), + accessPolicyNumber=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_object(self, params): + new_object = {} + if params.get("networkId") is not None: + new_object["networkId"] = params.get( + "networkId") + if params.get("accessPolicyNumber") is not None: + new_object["accessPolicyNumber"] = params.get( + "accessPolicyNumber") + return new_object + + def get_all(self, params): + new_object = {} + if params.get("networkId") is not None: + new_object["networkId"] = params.get( + "networkId") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + id = self._task.args.get("accessPolicyNumber") + if id: + response = meraki.exec_meraki( + family="switch", + function='getNetworkSwitchAccessPolicy', + params=self.get_object(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result + if not id: + response = meraki.exec_meraki( + family="switch", + function='getNetworkSwitchAccessPolicies', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_switch_alternate_management_interface.py b/ansible_collections/cisco/meraki/plugins/action/networks_switch_alternate_management_interface.py new file mode 100644 index 000000000..7fd38d4f3 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_switch_alternate_management_interface.py @@ -0,0 +1,217 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or +# https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, + meraki_compare_equality, + get_dict_result, +) +from ansible_collections.cisco.meraki.plugins.plugin_utils.exceptions import ( + InconsistentParameters, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + state=dict(type="str", default="present", choices=["present"]), + enabled=dict(type="bool"), + vlanId=dict(type="int"), + protocols=dict(type="list"), + switches=dict(type="list"), + networkId=dict(type="str"), +)) + +required_if = [ + ("state", "present", ["networkId"], True), +] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class NetworksSwitchAlternateManagementInterface(object): + def __init__(self, params, meraki): + self.meraki = meraki + self.new_object = dict( + enabled=params.get("enabled"), + vlanId=params.get("vlanId"), + protocols=params.get("protocols"), + switches=params.get("switches"), + network_id=params.get("networkId"), + ) + + def get_all_params(self, name=None, id=None): + new_object_params = {} + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + return new_object_params + + def update_all_params(self): + new_object_params = {} + if self.new_object.get('enabled') is not None or self.new_object.get('enabled') is not None: + new_object_params['enabled'] = self.new_object.get('enabled') + if self.new_object.get('vlanId') is not None or self.new_object.get('vlan_id') is not None: + new_object_params['vlanId'] = self.new_object.get('vlanId') or \ + self.new_object.get('vlan_id') + if self.new_object.get('protocols') is not None or self.new_object.get('protocols') is not None: + new_object_params['protocols'] = self.new_object.get('protocols') or \ + self.new_object.get('protocols') + if self.new_object.get('switches') is not None or self.new_object.get('switches') is not None: + new_object_params['switches'] = self.new_object.get('switches') or \ + self.new_object.get('switches') + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + return new_object_params + + def get_object_by_name(self, name): + result = None + # NOTE: Does not have a get by name method, using get all + try: + items = self.meraki.exec_meraki( + family="switch", + function="getNetworkSwitchAlternateManagementInterface", + params=self.get_all_params(name=name), + ) + if isinstance(items, dict): + if 'response' in items: + items = items.get('response') + result = get_dict_result(items, 'name', name) + if result is None: + result = items + except Exception as e: + print("Error: ", e) + result = None + return result + + def get_object_by_id(self, id): + result = None + # NOTE: Does not have a get by id method or it is in another action + return result + + def exists(self): + prev_obj = None + id_exists = False + name_exists = False + o_id = self.new_object.get("networkId") or self.new_object.get("network_id") + name = self.new_object.get("name") + if o_id: + prev_obj = self.get_object_by_name(o_id) + id_exists = prev_obj is not None and isinstance(prev_obj, dict) + if not id_exists and name: + prev_obj = self.get_object_by_name(name) + name_exists = prev_obj is not None and isinstance(prev_obj, dict) + if name_exists: + _id = prev_obj.get("id") + if id_exists and name_exists and o_id != _id: + raise InconsistentParameters( + "The 'id' and 'name' params don't refer to the same object") + if _id: + self.new_object.update(dict(id=_id)) + it_exists = prev_obj is not None and isinstance(prev_obj, dict) + return (it_exists, prev_obj) + + def requires_update(self, current_obj): + requested_obj = self.new_object + + obj_params = [ + ("enabled", "enabled"), + ("vlanId", "vlanId"), + ("protocols", "protocols"), + ("switches", "switches"), + ("networkId", "networkId"), + ] + # Method 1. Params present in request (Ansible) obj are the same as the current (ISE) params + # If any does not have eq params, it requires update + return any(not meraki_compare_equality(current_obj.get(meraki_param), + requested_obj.get(ansible_param)) + for (meraki_param, ansible_param) in obj_params) + + def update(self): + id = self.new_object.get("id") + name = self.new_object.get("name") + result = None + result = self.meraki.exec_meraki( + family="switch", + function="updateNetworkSwitchAlternateManagementInterface", + params=self.update_all_params(), + op_modifies=True, + ) + return result + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = False + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + meraki = MERAKI(self._task.args) + obj = NetworksSwitchAlternateManagementInterface(self._task.args, meraki) + + state = self._task.args.get("state") + + response = None + if state == "present": + (obj_exists, prev_obj) = obj.exists() + if obj_exists: + if obj.requires_update(prev_obj): + response = obj.update() + meraki.object_updated() + else: + response = prev_obj + meraki.object_already_present() + else: + meraki.fail_json( + "Object does not exists, plugin only has update") + + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_switch_alternate_management_interface_info.py b/ansible_collections/cisco/meraki/plugins/action/networks_switch_alternate_management_interface_info.py new file mode 100644 index 000000000..967563901 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_switch_alternate_management_interface_info.py @@ -0,0 +1,90 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + networkId=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_all(self, params): + new_object = {} + if params.get("networkId") is not None: + new_object["networkId"] = params.get( + "networkId") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="switch", + function='getNetworkSwitchAlternateManagementInterface', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_switch_dhcp_server_policy.py b/ansible_collections/cisco/meraki/plugins/action/networks_switch_dhcp_server_policy.py new file mode 100644 index 000000000..70dae83da --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_switch_dhcp_server_policy.py @@ -0,0 +1,224 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or +# https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, + meraki_compare_equality, + get_dict_result, +) +from ansible_collections.cisco.meraki.plugins.plugin_utils.exceptions import ( + InconsistentParameters, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + state=dict(type="str", default="present", choices=["present"]), + alerts=dict(type="dict"), + defaultPolicy=dict(type="str"), + allowedServers=dict(type="list"), + blockedServers=dict(type="list"), + arpInspection=dict(type="dict"), + networkId=dict(type="str"), +)) + +required_if = [ + ("state", "present", ["networkId"], True), +] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class NetworksSwitchDhcpServerPolicy(object): + def __init__(self, params, meraki): + self.meraki = meraki + self.new_object = dict( + alerts=params.get("alerts"), + defaultPolicy=params.get("defaultPolicy"), + allowedServers=params.get("allowedServers"), + blockedServers=params.get("blockedServers"), + arpInspection=params.get("arpInspection"), + network_id=params.get("networkId"), + ) + + def get_all_params(self, name=None, id=None): + new_object_params = {} + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + return new_object_params + + def update_all_params(self): + new_object_params = {} + if self.new_object.get('alerts') is not None or self.new_object.get('alerts') is not None: + new_object_params['alerts'] = self.new_object.get('alerts') or \ + self.new_object.get('alerts') + if self.new_object.get('defaultPolicy') is not None or self.new_object.get('default_policy') is not None: + new_object_params['defaultPolicy'] = self.new_object.get('defaultPolicy') or \ + self.new_object.get('default_policy') + if self.new_object.get('allowedServers') is not None or self.new_object.get('allowed_servers') is not None: + new_object_params['allowedServers'] = self.new_object.get('allowedServers') or \ + self.new_object.get('allowed_servers') + if self.new_object.get('blockedServers') is not None or self.new_object.get('blocked_servers') is not None: + new_object_params['blockedServers'] = self.new_object.get('blockedServers') or \ + self.new_object.get('blocked_servers') + if self.new_object.get('arpInspection') is not None or self.new_object.get('arp_inspection') is not None: + new_object_params['arpInspection'] = self.new_object.get('arpInspection') or \ + self.new_object.get('arp_inspection') + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + return new_object_params + + def get_object_by_name(self, name): + result = None + # NOTE: Does not have a get by name method, using get all + try: + items = self.meraki.exec_meraki( + family="switch", + function="getNetworkSwitchDhcpServerPolicy", + params=self.get_all_params(name=name), + ) + if isinstance(items, dict): + if 'response' in items: + items = items.get('response') + result = get_dict_result(items, 'name', name) + if result is None: + result = items + except Exception as e: + print("Error: ", e) + result = None + return result + + def get_object_by_id(self, id): + result = None + # NOTE: Does not have a get by id method or it is in another action + return result + + def exists(self): + prev_obj = None + id_exists = False + name_exists = False + o_id = self.new_object.get("networkId") or self.new_object.get("network_id") + name = self.new_object.get("name") + if o_id: + prev_obj = self.get_object_by_name(o_id) + id_exists = prev_obj is not None and isinstance(prev_obj, dict) + if not id_exists and name: + prev_obj = self.get_object_by_name(name) + name_exists = prev_obj is not None and isinstance(prev_obj, dict) + if name_exists: + _id = prev_obj.get("id") + if id_exists and name_exists and o_id != _id: + raise InconsistentParameters( + "The 'id' and 'name' params don't refer to the same object") + if _id: + self.new_object.update(dict(id=_id)) + it_exists = prev_obj is not None and isinstance(prev_obj, dict) + return (it_exists, prev_obj) + + def requires_update(self, current_obj): + requested_obj = self.new_object + + obj_params = [ + ("alerts", "alerts"), + ("defaultPolicy", "defaultPolicy"), + ("allowedServers", "allowedServers"), + ("blockedServers", "blockedServers"), + ("arpInspection", "arpInspection"), + ("networkId", "networkId"), + ] + # Method 1. Params present in request (Ansible) obj are the same as the current (ISE) params + # If any does not have eq params, it requires update + return any(not meraki_compare_equality(current_obj.get(meraki_param), + requested_obj.get(ansible_param)) + for (meraki_param, ansible_param) in obj_params) + + def update(self): + id = self.new_object.get("id") + name = self.new_object.get("name") + result = None + result = self.meraki.exec_meraki( + family="switch", + function="updateNetworkSwitchDhcpServerPolicy", + params=self.update_all_params(), + op_modifies=True, + ) + return result + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = False + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + meraki = MERAKI(self._task.args) + obj = NetworksSwitchDhcpServerPolicy(self._task.args, meraki) + + state = self._task.args.get("state") + + response = None + if state == "present": + (obj_exists, prev_obj) = obj.exists() + if obj_exists: + if obj.requires_update(prev_obj): + response = obj.update() + meraki.object_updated() + else: + response = prev_obj + meraki.object_already_present() + else: + meraki.fail_json( + "Object does not exists, plugin only has update") + + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_switch_dhcp_server_policy_arp_inspection_trusted_servers.py b/ansible_collections/cisco/meraki/plugins/action/networks_switch_dhcp_server_policy_arp_inspection_trusted_servers.py new file mode 100644 index 000000000..d0bd4b120 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_switch_dhcp_server_policy_arp_inspection_trusted_servers.py @@ -0,0 +1,319 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or +# https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, + meraki_compare_equality, + get_dict_result, +) +from ansible_collections.cisco.meraki.plugins.plugin_utils.exceptions import ( + InconsistentParameters, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + state=dict(type="str", default="present", choices=["present", "absent"]), + mac=dict(type="str"), + vlan=dict(type="int"), + ipv4=dict(type="dict"), + networkId=dict(type="str"), + trustedServerId=dict(type="str"), +)) + +required_if = [ + ("state", "present", ["networkId", "trustedServerId"], True), + ("state", "absent", ["networkId", "trustedServerId"], True), +] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class NetworksSwitchDhcpServerPolicyArpInspectionTrustedServers(object): + def __init__(self, params, meraki): + self.meraki = meraki + self.new_object = dict( + mac=params.get("mac"), + vlan=params.get("vlan"), + ipv4=params.get("ipv4"), + networkId=params.get("networkId"), + trustedServerId=params.get("trustedServerId"), + ) + + def get_all_params(self, name=None, id=None): + new_object_params = {} + if self.new_object.get('perPage') is not None or self.new_object.get('per_page') is not None: + new_object_params['perPage'] = self.new_object.get('perPage') or \ + self.new_object.get('per_page') + new_object_params['total_pages'] = -1 + if self.new_object.get('startingAfter') is not None or self.new_object.get('starting_after') is not None: + new_object_params['startingAfter'] = self.new_object.get('startingAfter') or \ + self.new_object.get('starting_after') + if self.new_object.get('endingBefore') is not None or self.new_object.get('ending_before') is not None: + new_object_params['endingBefore'] = self.new_object.get('endingBefore') or \ + self.new_object.get('ending_before') + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + return new_object_params + + def create_params(self): + new_object_params = {} + if self.new_object.get('mac') is not None or self.new_object.get('mac') is not None: + new_object_params['mac'] = self.new_object.get('mac') or \ + self.new_object.get('mac') + if self.new_object.get('vlan') is not None or self.new_object.get('vlan') is not None: + new_object_params['vlan'] = self.new_object.get('vlan') or \ + self.new_object.get('vlan') + if self.new_object.get('ipv4') is not None or self.new_object.get('ipv4') is not None: + new_object_params['ipv4'] = self.new_object.get('ipv4') or \ + self.new_object.get('ipv4') + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + return new_object_params + + def delete_by_id_params(self): + new_object_params = {} + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + if self.new_object.get('trustedServerId') is not None or self.new_object.get('trusted_server_id') is not None: + new_object_params['trustedServerId'] = self.new_object.get('trustedServerId') or \ + self.new_object.get('trusted_server_id') + return new_object_params + + def update_by_id_params(self): + new_object_params = {} + if self.new_object.get('mac') is not None or self.new_object.get('mac') is not None: + new_object_params['mac'] = self.new_object.get('mac') or \ + self.new_object.get('mac') + if self.new_object.get('vlan') is not None or self.new_object.get('vlan') is not None: + new_object_params['vlan'] = self.new_object.get('vlan') or \ + self.new_object.get('vlan') + if self.new_object.get('ipv4') is not None or self.new_object.get('ipv4') is not None: + new_object_params['ipv4'] = self.new_object.get('ipv4') or \ + self.new_object.get('ipv4') + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + if self.new_object.get('trustedServerId') is not None or self.new_object.get('trusted_server_id') is not None: + new_object_params['trustedServerId'] = self.new_object.get('trustedServerId') or \ + self.new_object.get('trusted_server_id') + return new_object_params + + def get_object_by_name(self, name): + result = None + # NOTE: Does not have a get by name method or it is in another action + try: + items = self.meraki.exec_meraki( + family="switch", + function="getNetworkSwitchDhcpServerPolicyArpInspectionTrustedServers", + params=self.get_all_params(name=name), + ) + if isinstance(items, dict): + if 'response' in items: + items = items.get('response') + result = get_dict_result(items, 'name', name) + if result is None: + result = items + except Exception as e: + print("Error: ", e) + result = None + return result + + def get_object_by_id(self, id): + result = None + # NOTE: Does not have a get by id method or it is in another action + try: + items = self.meraki.exec_meraki( + family="switch", + function="getNetworkSwitchDhcpServerPolicyArpInspectionTrustedServers", + params=self.get_all_params(id=id), + ) + if isinstance(items, dict): + if 'response' in items: + items = items.get('response') + result = get_dict_result(items, 'id', id) + except Exception as e: + print("Error: ", e) + result = None + return result + + def exists(self): + id_exists = False + name_exists = False + prev_obj = None + o_id = self.new_object.get("id") + o_id = o_id or self.new_object.get( + "trusted_server_id") or self.new_object.get("trustedServerId") + name = self.new_object.get("name") + if o_id: + prev_obj = self.get_object_by_id(o_id) + id_exists = prev_obj is not None and isinstance(prev_obj, dict) + if not id_exists and name: + prev_obj = self.get_object_by_name(name) + name_exists = prev_obj is not None and isinstance(prev_obj, dict) + if name_exists: + _id = prev_obj.get("id") + _id = _id or prev_obj.get("trustedServerId") + if id_exists and name_exists and o_id != _id: + raise InconsistentParameters( + "The 'id' and 'name' params don't refer to the same object") + if _id: + self.new_object.update(dict(id=_id)) + self.new_object.update(dict(trustedServerId=_id)) + it_exists = prev_obj is not None and isinstance(prev_obj, dict) + return (it_exists, prev_obj) + + def requires_update(self, current_obj): + requested_obj = self.new_object + + obj_params = [ + ("mac", "mac"), + ("vlan", "vlan"), + ("ipv4", "ipv4"), + ("networkId", "networkId"), + ("trustedServerId", "trustedServerId"), + ] + # Method 1. Params present in request (Ansible) obj are the same as the current (DNAC) params + # If any does not have eq params, it requires update + return any(not meraki_compare_equality(current_obj.get(meraki_param), + requested_obj.get(ansible_param)) + for (meraki_param, ansible_param) in obj_params) + + def create(self): + result = self.meraki.exec_meraki( + family="switch", + function="createNetworkSwitchDhcpServerPolicyArpInspectionTrustedServer", + params=self.create_params(), + op_modifies=True, + ) + return result + + def update(self): + id = self.new_object.get("id") + id = id or self.new_object.get("trustedServerId") + name = self.new_object.get("name") + result = None + if not id: + prev_obj_name = self.get_object_by_name(name) + id_ = None + if prev_obj_name: + id_ = prev_obj_name.get("id") + id_ = id_ or prev_obj_name.get("trustedServerId") + if id_: + self.new_object.update(dict(trustedServerId=id_)) + result = self.meraki.exec_meraki( + family="switch", + function="updateNetworkSwitchDhcpServerPolicyArpInspectionTrustedServer", + params=self.update_by_id_params(), + op_modifies=True, + ) + return result + + def delete(self): + id = self.new_object.get("id") + id = id or self.new_object.get("trustedServerId") + name = self.new_object.get("name") + result = None + if not id: + prev_obj_name = self.get_object_by_name(name) + id_ = None + if prev_obj_name: + id_ = prev_obj_name.get("id") + id_ = id_ or prev_obj_name.get("trustedServerId") + if id_: + self.new_object.update(dict(trustedServerId=id_)) + result = self.meraki.exec_meraki( + family="switch", + function="deleteNetworkSwitchDhcpServerPolicyArpInspectionTrustedServer", + params=self.delete_by_id_params(), + ) + return result + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = False + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + meraki = MERAKI(self._task.args) + obj = NetworksSwitchDhcpServerPolicyArpInspectionTrustedServers(self._task.args, meraki) + + state = self._task.args.get("state") + + response = None + + if state == "present": + (obj_exists, prev_obj) = obj.exists() + if obj_exists: + if obj.requires_update(prev_obj): + response = obj.update() + meraki.object_updated() + else: + response = prev_obj + meraki.object_already_present() + else: + response = obj.create() + meraki.object_created() + + elif state == "absent": + (obj_exists, prev_obj) = obj.exists() + if obj_exists: + response = obj.delete() + meraki.object_deleted() + else: + meraki.object_already_absent() + + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_switch_dhcp_server_policy_arp_inspection_trusted_servers_info.py b/ansible_collections/cisco/meraki/plugins/action/networks_switch_dhcp_server_policy_arp_inspection_trusted_servers_info.py new file mode 100644 index 000000000..f1486824c --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_switch_dhcp_server_policy_arp_inspection_trusted_servers_info.py @@ -0,0 +1,108 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + networkId=dict(type="str"), + perPage=dict(type="int"), + total_pages=dict(type="int"), + direction=dict(type="str"), + startingAfter=dict(type="str"), + endingBefore=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_all(self, params): + new_object = {} + if params.get("networkId") is not None: + new_object["networkId"] = params.get( + "networkId") + if params.get("perPage") is not None: + new_object["perPage"] = params.get( + "perPage") + new_object['total_pages'] = params.get( + "total_pages") or 1 + new_object['direction'] = params.get( + "direction") or "next" + if params.get("startingAfter") is not None: + new_object["startingAfter"] = params.get( + "startingAfter") + if params.get("endingBefore") is not None: + new_object["endingBefore"] = params.get( + "endingBefore") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="switch", + function='getNetworkSwitchDhcpServerPolicyArpInspectionTrustedServers', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_switch_dhcp_server_policy_arp_inspection_warnings_by_device_info.py b/ansible_collections/cisco/meraki/plugins/action/networks_switch_dhcp_server_policy_arp_inspection_warnings_by_device_info.py new file mode 100644 index 000000000..935f201da --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_switch_dhcp_server_policy_arp_inspection_warnings_by_device_info.py @@ -0,0 +1,108 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + networkId=dict(type="str"), + perPage=dict(type="int"), + total_pages=dict(type="int"), + direction=dict(type="str"), + startingAfter=dict(type="str"), + endingBefore=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_all(self, params): + new_object = {} + if params.get("networkId") is not None: + new_object["networkId"] = params.get( + "networkId") + if params.get("perPage") is not None: + new_object["perPage"] = params.get( + "perPage") + new_object['total_pages'] = params.get( + "total_pages") or 1 + new_object['direction'] = params.get( + "direction") or "next" + if params.get("startingAfter") is not None: + new_object["startingAfter"] = params.get( + "startingAfter") + if params.get("endingBefore") is not None: + new_object["endingBefore"] = params.get( + "endingBefore") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="switch", + function='getNetworkSwitchDhcpServerPolicyArpInspectionWarningsByDevice', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_switch_dhcp_server_policy_info.py b/ansible_collections/cisco/meraki/plugins/action/networks_switch_dhcp_server_policy_info.py new file mode 100644 index 000000000..674e2853c --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_switch_dhcp_server_policy_info.py @@ -0,0 +1,90 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + networkId=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_all(self, params): + new_object = {} + if params.get("networkId") is not None: + new_object["networkId"] = params.get( + "networkId") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="switch", + function='getNetworkSwitchDhcpServerPolicy', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_switch_dhcp_v4_servers_seen_info.py b/ansible_collections/cisco/meraki/plugins/action/networks_switch_dhcp_v4_servers_seen_info.py new file mode 100644 index 000000000..7d2e39676 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_switch_dhcp_v4_servers_seen_info.py @@ -0,0 +1,116 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + networkId=dict(type="str"), + t0=dict(type="str"), + timespan=dict(type="float"), + perPage=dict(type="int"), + total_pages=dict(type="int"), + direction=dict(type="str"), + startingAfter=dict(type="str"), + endingBefore=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_all(self, params): + new_object = {} + if params.get("networkId") is not None: + new_object["networkId"] = params.get( + "networkId") + if params.get("t0") is not None: + new_object["t0"] = params.get( + "t0") + if params.get("timespan") is not None: + new_object["timespan"] = params.get( + "timespan") + if params.get("perPage") is not None: + new_object["perPage"] = params.get( + "perPage") + new_object['total_pages'] = params.get( + "total_pages") or 1 + new_object['direction'] = params.get( + "direction") or "next" + if params.get("startingAfter") is not None: + new_object["startingAfter"] = params.get( + "startingAfter") + if params.get("endingBefore") is not None: + new_object["endingBefore"] = params.get( + "endingBefore") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="switch", + function='getNetworkSwitchDhcpV4ServersSeen', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_switch_dscp_to_cos_mappings.py b/ansible_collections/cisco/meraki/plugins/action/networks_switch_dscp_to_cos_mappings.py new file mode 100644 index 000000000..65fbdbdd6 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_switch_dscp_to_cos_mappings.py @@ -0,0 +1,200 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or +# https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, + meraki_compare_equality, + get_dict_result, +) +from ansible_collections.cisco.meraki.plugins.plugin_utils.exceptions import ( + InconsistentParameters, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + state=dict(type="str", default="present", choices=["present"]), + mappings=dict(type="list"), + networkId=dict(type="str"), +)) + +required_if = [ + ("state", "present", ["networkId"], True), +] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class NetworksSwitchDscpToCosMappings(object): + def __init__(self, params, meraki): + self.meraki = meraki + self.new_object = dict( + mappings=params.get("mappings"), + network_id=params.get("networkId"), + ) + + def get_all_params(self, name=None, id=None): + new_object_params = {} + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + return new_object_params + + def update_all_params(self): + new_object_params = {} + if self.new_object.get('mappings') is not None or self.new_object.get('mappings') is not None: + new_object_params['mappings'] = self.new_object.get('mappings') or \ + self.new_object.get('mappings') + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + return new_object_params + + def get_object_by_name(self, name): + result = None + # NOTE: Does not have a get by name method, using get all + try: + items = self.meraki.exec_meraki( + family="switch", + function="getNetworkSwitchDscpToCosMappings", + params=self.get_all_params(name=name), + ) + if isinstance(items, dict): + if 'response' in items: + items = items.get('response') + result = get_dict_result(items, 'name', name) + if result is None: + result = items + except Exception as e: + print("Error: ", e) + result = None + return result + + def get_object_by_id(self, id): + result = None + # NOTE: Does not have a get by id method or it is in another action + return result + + def exists(self): + prev_obj = None + id_exists = False + name_exists = False + o_id = self.new_object.get("networkId") or self.new_object.get("network_id") + name = self.new_object.get("name") + if o_id: + prev_obj = self.get_object_by_name(o_id) + id_exists = prev_obj is not None and isinstance(prev_obj, dict) + if not id_exists and name: + prev_obj = self.get_object_by_name(name) + name_exists = prev_obj is not None and isinstance(prev_obj, dict) + if name_exists: + _id = prev_obj.get("id") + if id_exists and name_exists and o_id != _id: + raise InconsistentParameters( + "The 'id' and 'name' params don't refer to the same object") + if _id: + self.new_object.update(dict(id=_id)) + it_exists = prev_obj is not None and isinstance(prev_obj, dict) + return (it_exists, prev_obj) + + def requires_update(self, current_obj): + requested_obj = self.new_object + + obj_params = [ + ("mappings", "mappings"), + ("networkId", "networkId"), + ] + # Method 1. Params present in request (Ansible) obj are the same as the current (ISE) params + # If any does not have eq params, it requires update + return any(not meraki_compare_equality(current_obj.get(meraki_param), + requested_obj.get(ansible_param)) + for (meraki_param, ansible_param) in obj_params) + + def update(self): + id = self.new_object.get("id") + name = self.new_object.get("name") + result = None + result = self.meraki.exec_meraki( + family="switch", + function="updateNetworkSwitchDscpToCosMappings", + params=self.update_all_params(), + op_modifies=True, + ) + return result + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = False + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + meraki = MERAKI(self._task.args) + obj = NetworksSwitchDscpToCosMappings(self._task.args, meraki) + + state = self._task.args.get("state") + + response = None + if state == "present": + (obj_exists, prev_obj) = obj.exists() + if obj_exists: + if obj.requires_update(prev_obj): + response = obj.update() + meraki.object_updated() + else: + response = prev_obj + meraki.object_already_present() + else: + meraki.fail_json( + "Object does not exists, plugin only has update") + + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_switch_dscp_to_cos_mappings_info.py b/ansible_collections/cisco/meraki/plugins/action/networks_switch_dscp_to_cos_mappings_info.py new file mode 100644 index 000000000..b0c302fde --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_switch_dscp_to_cos_mappings_info.py @@ -0,0 +1,90 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + networkId=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_all(self, params): + new_object = {} + if params.get("networkId") is not None: + new_object["networkId"] = params.get( + "networkId") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="switch", + function='getNetworkSwitchDscpToCosMappings', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_switch_link_aggregations.py b/ansible_collections/cisco/meraki/plugins/action/networks_switch_link_aggregations.py new file mode 100644 index 000000000..096aaa146 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_switch_link_aggregations.py @@ -0,0 +1,300 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or +# https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, + meraki_compare_equality, + get_dict_result, +) +from ansible_collections.cisco.meraki.plugins.plugin_utils.exceptions import ( + InconsistentParameters, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + state=dict(type="str", default="present", choices=["present", "absent"]), + switchPorts=dict(type="list"), + switchProfilePorts=dict(type="list"), + networkId=dict(type="str"), + linkAggregationId=dict(type="str"), +)) + +required_if = [ + ("state", "present", ["linkAggregationId", "networkId"], True), + ("state", "absent", ["linkAggregationId", "networkId"], True), +] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class NetworksSwitchLinkAggregations(object): + def __init__(self, params, meraki): + self.meraki = meraki + self.new_object = dict( + switchPorts=params.get("switchPorts"), + switchProfilePorts=params.get("switchProfilePorts"), + networkId=params.get("networkId"), + linkAggregationId=params.get("linkAggregationId"), + ) + + def get_all_params(self, name=None, id=None): + new_object_params = {} + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + return new_object_params + + def create_params(self): + new_object_params = {} + if self.new_object.get('switchPorts') is not None or self.new_object.get('switch_ports') is not None: + new_object_params['switchPorts'] = self.new_object.get('switchPorts') or \ + self.new_object.get('switch_ports') + if self.new_object.get('switchProfilePorts') is not None or self.new_object.get('switch_profile_ports') is not None: + new_object_params['switchProfilePorts'] = self.new_object.get('switchProfilePorts') or \ + self.new_object.get('switch_profile_ports') + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + return new_object_params + + def delete_by_id_params(self): + new_object_params = {} + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + if self.new_object.get('linkAggregationId') is not None or self.new_object.get('link_aggregation_id') is not None: + new_object_params['linkAggregationId'] = self.new_object.get('linkAggregationId') or \ + self.new_object.get('link_aggregation_id') + return new_object_params + + def update_by_id_params(self): + new_object_params = {} + if self.new_object.get('switchPorts') is not None or self.new_object.get('switch_ports') is not None: + new_object_params['switchPorts'] = self.new_object.get('switchPorts') or \ + self.new_object.get('switch_ports') + if self.new_object.get('switchProfilePorts') is not None or self.new_object.get('switch_profile_ports') is not None: + new_object_params['switchProfilePorts'] = self.new_object.get('switchProfilePorts') or \ + self.new_object.get('switch_profile_ports') + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + if self.new_object.get('linkAggregationId') is not None or self.new_object.get('link_aggregation_id') is not None: + new_object_params['linkAggregationId'] = self.new_object.get('linkAggregationId') or \ + self.new_object.get('link_aggregation_id') + return new_object_params + + def get_object_by_name(self, name): + result = None + # NOTE: Does not have a get by name method or it is in another action + try: + items = self.meraki.exec_meraki( + family="switch", + function="getNetworkSwitchLinkAggregations", + params=self.get_all_params(name=name), + ) + if isinstance(items, dict): + if 'response' in items: + items = items.get('response') + result = get_dict_result(items, 'name', name) + if result is None: + result = items + except Exception as e: + print("Error: ", e) + result = None + return result + + def get_object_by_id(self, id): + result = None + # NOTE: Does not have a get by id method or it is in another action + try: + items = self.meraki.exec_meraki( + family="switch", + function="getNetworkSwitchLinkAggregations", + params=self.get_all_params(id=id), + ) + if isinstance(items, dict): + if 'response' in items: + items = items.get('response') + result = get_dict_result(items, 'id', id) + except Exception as e: + print("Error: ", e) + result = None + return result + + def exists(self): + id_exists = False + name_exists = False + prev_obj = None + o_id = self.new_object.get("id") + o_id = o_id or self.new_object.get( + "link_aggregation_id") or self.new_object.get("linkAggregationId") + name = self.new_object.get("name") + if o_id: + prev_obj = self.get_object_by_id(o_id) + id_exists = prev_obj is not None and isinstance(prev_obj, dict) + if not id_exists and name: + prev_obj = self.get_object_by_name(name) + name_exists = prev_obj is not None and isinstance(prev_obj, dict) + if name_exists: + _id = prev_obj.get("id") + _id = _id or prev_obj.get("linkAggregationId") + if id_exists and name_exists and o_id != _id: + raise InconsistentParameters( + "The 'id' and 'name' params don't refer to the same object") + if _id: + self.new_object.update(dict(id=_id)) + self.new_object.update(dict(linkAggregationId=_id)) + it_exists = prev_obj is not None and isinstance(prev_obj, dict) + return (it_exists, prev_obj) + + def requires_update(self, current_obj): + requested_obj = self.new_object + + obj_params = [ + ("switchPorts", "switchPorts"), + ("switchProfilePorts", "switchProfilePorts"), + ("networkId", "networkId"), + ("linkAggregationId", "linkAggregationId"), + ] + # Method 1. Params present in request (Ansible) obj are the same as the current (DNAC) params + # If any does not have eq params, it requires update + return any(not meraki_compare_equality(current_obj.get(meraki_param), + requested_obj.get(ansible_param)) + for (meraki_param, ansible_param) in obj_params) + + def create(self): + result = self.meraki.exec_meraki( + family="switch", + function="createNetworkSwitchLinkAggregation", + params=self.create_params(), + op_modifies=True, + ) + return result + + def update(self): + id = self.new_object.get("id") + id = id or self.new_object.get("linkAggregationId") + name = self.new_object.get("name") + result = None + if not id: + prev_obj_name = self.get_object_by_name(name) + id_ = None + if prev_obj_name: + id_ = prev_obj_name.get("id") + id_ = id_ or prev_obj_name.get("linkAggregationId") + if id_: + self.new_object.update(dict(linkAggregationId=id_)) + result = self.meraki.exec_meraki( + family="switch", + function="updateNetworkSwitchLinkAggregation", + params=self.update_by_id_params(), + op_modifies=True, + ) + return result + + def delete(self): + id = self.new_object.get("id") + id = id or self.new_object.get("linkAggregationId") + name = self.new_object.get("name") + result = None + if not id: + prev_obj_name = self.get_object_by_name(name) + id_ = None + if prev_obj_name: + id_ = prev_obj_name.get("id") + id_ = id_ or prev_obj_name.get("linkAggregationId") + if id_: + self.new_object.update(dict(linkAggregationId=id_)) + result = self.meraki.exec_meraki( + family="switch", + function="deleteNetworkSwitchLinkAggregation", + params=self.delete_by_id_params(), + ) + return result + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = False + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + meraki = MERAKI(self._task.args) + obj = NetworksSwitchLinkAggregations(self._task.args, meraki) + + state = self._task.args.get("state") + + response = None + + if state == "present": + (obj_exists, prev_obj) = obj.exists() + if obj_exists: + if obj.requires_update(prev_obj): + response = obj.update() + meraki.object_updated() + else: + response = prev_obj + meraki.object_already_present() + else: + response = obj.create() + meraki.object_created() + + elif state == "absent": + (obj_exists, prev_obj) = obj.exists() + if obj_exists: + response = obj.delete() + meraki.object_deleted() + else: + meraki.object_already_absent() + + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_switch_link_aggregations_info.py b/ansible_collections/cisco/meraki/plugins/action/networks_switch_link_aggregations_info.py new file mode 100644 index 000000000..73b10ad09 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_switch_link_aggregations_info.py @@ -0,0 +1,90 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + networkId=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_all(self, params): + new_object = {} + if params.get("networkId") is not None: + new_object["networkId"] = params.get( + "networkId") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="switch", + function='getNetworkSwitchLinkAggregations', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_switch_mtu.py b/ansible_collections/cisco/meraki/plugins/action/networks_switch_mtu.py new file mode 100644 index 000000000..e838cf6d7 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_switch_mtu.py @@ -0,0 +1,206 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or +# https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, + meraki_compare_equality, + get_dict_result, +) +from ansible_collections.cisco.meraki.plugins.plugin_utils.exceptions import ( + InconsistentParameters, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + state=dict(type="str", default="present", choices=["present"]), + defaultMtuSize=dict(type="int"), + overrides=dict(type="list"), + networkId=dict(type="str"), +)) + +required_if = [ + ("state", "present", ["networkId"], True), +] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class NetworksSwitchMtu(object): + def __init__(self, params, meraki): + self.meraki = meraki + self.new_object = dict( + defaultMtuSize=params.get("defaultMtuSize"), + overrides=params.get("overrides"), + network_id=params.get("networkId"), + ) + + def get_all_params(self, name=None, id=None): + new_object_params = {} + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + return new_object_params + + def update_all_params(self): + new_object_params = {} + if self.new_object.get('defaultMtuSize') is not None or self.new_object.get('default_mtu_size') is not None: + new_object_params['defaultMtuSize'] = self.new_object.get('defaultMtuSize') or \ + self.new_object.get('default_mtu_size') + if self.new_object.get('overrides') is not None or self.new_object.get('overrides') is not None: + new_object_params['overrides'] = self.new_object.get('overrides') or \ + self.new_object.get('overrides') + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + return new_object_params + + def get_object_by_name(self, name): + result = None + # NOTE: Does not have a get by name method, using get all + try: + items = self.meraki.exec_meraki( + family="switch", + function="getNetworkSwitchMtu", + params=self.get_all_params(name=name), + ) + if isinstance(items, dict): + if 'response' in items: + items = items.get('response') + result = get_dict_result(items, 'name', name) + if result is None: + result = items + except Exception as e: + print("Error: ", e) + result = None + return result + + def get_object_by_id(self, id): + result = None + # NOTE: Does not have a get by id method or it is in another action + return result + + def exists(self): + prev_obj = None + id_exists = False + name_exists = False + o_id = self.new_object.get("networkId") or self.new_object.get("network_id") + name = self.new_object.get("name") + if o_id: + prev_obj = self.get_object_by_name(o_id) + id_exists = prev_obj is not None and isinstance(prev_obj, dict) + if not id_exists and name: + prev_obj = self.get_object_by_name(name) + name_exists = prev_obj is not None and isinstance(prev_obj, dict) + if name_exists: + _id = prev_obj.get("id") + if id_exists and name_exists and o_id != _id: + raise InconsistentParameters( + "The 'id' and 'name' params don't refer to the same object") + if _id: + self.new_object.update(dict(id=_id)) + it_exists = prev_obj is not None and isinstance(prev_obj, dict) + return (it_exists, prev_obj) + + def requires_update(self, current_obj): + requested_obj = self.new_object + + obj_params = [ + ("defaultMtuSize", "defaultMtuSize"), + ("overrides", "overrides"), + ("networkId", "networkId"), + ] + # Method 1. Params present in request (Ansible) obj are the same as the current (ISE) params + # If any does not have eq params, it requires update + return any(not meraki_compare_equality(current_obj.get(meraki_param), + requested_obj.get(ansible_param)) + for (meraki_param, ansible_param) in obj_params) + + def update(self): + id = self.new_object.get("id") + name = self.new_object.get("name") + result = None + result = self.meraki.exec_meraki( + family="switch", + function="updateNetworkSwitchMtu", + params=self.update_all_params(), + op_modifies=True, + ) + return result + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = False + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + meraki = MERAKI(self._task.args) + obj = NetworksSwitchMtu(self._task.args, meraki) + + state = self._task.args.get("state") + + response = None + if state == "present": + (obj_exists, prev_obj) = obj.exists() + if obj_exists: + if obj.requires_update(prev_obj): + response = obj.update() + meraki.object_updated() + else: + response = prev_obj + meraki.object_already_present() + else: + meraki.fail_json( + "Object does not exists, plugin only has update") + + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_switch_mtu_info.py b/ansible_collections/cisco/meraki/plugins/action/networks_switch_mtu_info.py new file mode 100644 index 000000000..14de16fae --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_switch_mtu_info.py @@ -0,0 +1,90 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + networkId=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_all(self, params): + new_object = {} + if params.get("networkId") is not None: + new_object["networkId"] = params.get( + "networkId") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="switch", + function='getNetworkSwitchMtu', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_switch_port_schedules.py b/ansible_collections/cisco/meraki/plugins/action/networks_switch_port_schedules.py new file mode 100644 index 000000000..f6c45ee4a --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_switch_port_schedules.py @@ -0,0 +1,300 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or +# https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, + meraki_compare_equality, + get_dict_result, +) +from ansible_collections.cisco.meraki.plugins.plugin_utils.exceptions import ( + InconsistentParameters, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + state=dict(type="str", default="present", choices=["present", "absent"]), + name=dict(type="str"), + portSchedule=dict(type="dict"), + networkId=dict(type="str"), + portScheduleId=dict(type="str"), +)) + +required_if = [ + ("state", "present", ["name", "networkId", "portScheduleId"], True), + ("state", "absent", ["name", "networkId", "portScheduleId"], True), +] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class NetworksSwitchPortSchedules(object): + def __init__(self, params, meraki): + self.meraki = meraki + self.new_object = dict( + name=params.get("name"), + portSchedule=params.get("portSchedule"), + networkId=params.get("networkId"), + portScheduleId=params.get("portScheduleId"), + ) + + def get_all_params(self, name=None, id=None): + new_object_params = {} + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + return new_object_params + + def create_params(self): + new_object_params = {} + if self.new_object.get('name') is not None or self.new_object.get('name') is not None: + new_object_params['name'] = self.new_object.get('name') or \ + self.new_object.get('name') + if self.new_object.get('portSchedule') is not None or self.new_object.get('port_schedule') is not None: + new_object_params['portSchedule'] = self.new_object.get('portSchedule') or \ + self.new_object.get('port_schedule') + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + return new_object_params + + def delete_by_id_params(self): + new_object_params = {} + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + if self.new_object.get('portScheduleId') is not None or self.new_object.get('port_schedule_id') is not None: + new_object_params['portScheduleId'] = self.new_object.get('portScheduleId') or \ + self.new_object.get('port_schedule_id') + return new_object_params + + def update_by_id_params(self): + new_object_params = {} + if self.new_object.get('name') is not None or self.new_object.get('name') is not None: + new_object_params['name'] = self.new_object.get('name') or \ + self.new_object.get('name') + if self.new_object.get('portSchedule') is not None or self.new_object.get('port_schedule') is not None: + new_object_params['portSchedule'] = self.new_object.get('portSchedule') or \ + self.new_object.get('port_schedule') + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + if self.new_object.get('portScheduleId') is not None or self.new_object.get('port_schedule_id') is not None: + new_object_params['portScheduleId'] = self.new_object.get('portScheduleId') or \ + self.new_object.get('port_schedule_id') + return new_object_params + + def get_object_by_name(self, name): + result = None + # NOTE: Does not have a get by name method or it is in another action + try: + items = self.meraki.exec_meraki( + family="switch", + function="getNetworkSwitchPortSchedules", + params=self.get_all_params(name=name), + ) + if isinstance(items, dict): + if 'response' in items: + items = items.get('response') + result = get_dict_result(items, 'name', name) + if result is None: + result = items + except Exception as e: + print("Error: ", e) + result = None + return result + + def get_object_by_id(self, id): + result = None + # NOTE: Does not have a get by id method or it is in another action + try: + items = self.meraki.exec_meraki( + family="switch", + function="getNetworkSwitchPortSchedules", + params=self.get_all_params(id=id), + ) + if isinstance(items, dict): + if 'response' in items: + items = items.get('response') + result = get_dict_result(items, 'id', id) + except Exception as e: + print("Error: ", e) + result = None + return result + + def exists(self): + id_exists = False + name_exists = False + prev_obj = None + o_id = self.new_object.get("id") + o_id = o_id or self.new_object.get( + "port_schedule_id") or self.new_object.get("portScheduleId") + name = self.new_object.get("name") + if o_id: + prev_obj = self.get_object_by_id(o_id) + id_exists = prev_obj is not None and isinstance(prev_obj, dict) + if not id_exists and name: + prev_obj = self.get_object_by_name(name) + name_exists = prev_obj is not None and isinstance(prev_obj, dict) + if name_exists: + _id = prev_obj.get("id") + _id = _id or prev_obj.get("portScheduleId") + if id_exists and name_exists and o_id != _id: + raise InconsistentParameters( + "The 'id' and 'name' params don't refer to the same object") + if _id: + self.new_object.update(dict(id=_id)) + self.new_object.update(dict(portScheduleId=_id)) + it_exists = prev_obj is not None and isinstance(prev_obj, dict) + return (it_exists, prev_obj) + + def requires_update(self, current_obj): + requested_obj = self.new_object + + obj_params = [ + ("name", "name"), + ("portSchedule", "portSchedule"), + ("networkId", "networkId"), + ("portScheduleId", "portScheduleId"), + ] + # Method 1. Params present in request (Ansible) obj are the same as the current (DNAC) params + # If any does not have eq params, it requires update + return any(not meraki_compare_equality(current_obj.get(meraki_param), + requested_obj.get(ansible_param)) + for (meraki_param, ansible_param) in obj_params) + + def create(self): + result = self.meraki.exec_meraki( + family="switch", + function="createNetworkSwitchPortSchedule", + params=self.create_params(), + op_modifies=True, + ) + return result + + def update(self): + id = self.new_object.get("id") + id = id or self.new_object.get("portScheduleId") + name = self.new_object.get("name") + result = None + if not id: + prev_obj_name = self.get_object_by_name(name) + id_ = None + if prev_obj_name: + id_ = prev_obj_name.get("id") + id_ = id_ or prev_obj_name.get("portScheduleId") + if id_: + self.new_object.update(dict(portScheduleId=id_)) + result = self.meraki.exec_meraki( + family="switch", + function="updateNetworkSwitchPortSchedule", + params=self.update_by_id_params(), + op_modifies=True, + ) + return result + + def delete(self): + id = self.new_object.get("id") + id = id or self.new_object.get("portScheduleId") + name = self.new_object.get("name") + result = None + if not id: + prev_obj_name = self.get_object_by_name(name) + id_ = None + if prev_obj_name: + id_ = prev_obj_name.get("id") + id_ = id_ or prev_obj_name.get("portScheduleId") + if id_: + self.new_object.update(dict(portScheduleId=id_)) + result = self.meraki.exec_meraki( + family="switch", + function="deleteNetworkSwitchPortSchedule", + params=self.delete_by_id_params(), + ) + return result + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = False + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + meraki = MERAKI(self._task.args) + obj = NetworksSwitchPortSchedules(self._task.args, meraki) + + state = self._task.args.get("state") + + response = None + + if state == "present": + (obj_exists, prev_obj) = obj.exists() + if obj_exists: + if obj.requires_update(prev_obj): + response = obj.update() + meraki.object_updated() + else: + response = prev_obj + meraki.object_already_present() + else: + response = obj.create() + meraki.object_created() + + elif state == "absent": + (obj_exists, prev_obj) = obj.exists() + if obj_exists: + response = obj.delete() + meraki.object_deleted() + else: + meraki.object_already_absent() + + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_switch_port_schedules_info.py b/ansible_collections/cisco/meraki/plugins/action/networks_switch_port_schedules_info.py new file mode 100644 index 000000000..1edac49a2 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_switch_port_schedules_info.py @@ -0,0 +1,90 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + networkId=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_all(self, params): + new_object = {} + if params.get("networkId") is not None: + new_object["networkId"] = params.get( + "networkId") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="switch", + function='getNetworkSwitchPortSchedules', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_switch_qos_rules_order.py b/ansible_collections/cisco/meraki/plugins/action/networks_switch_qos_rules_order.py new file mode 100644 index 000000000..33841d11c --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_switch_qos_rules_order.py @@ -0,0 +1,356 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or +# https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, + meraki_compare_equality, + get_dict_result, +) +from ansible_collections.cisco.meraki.plugins.plugin_utils.exceptions import ( + InconsistentParameters, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + state=dict(type="str", default="present", choices=["present", "absent"]), + vlan=dict(type="int"), + protocol=dict(type="str"), + srcPort=dict(type="int"), + srcPortRange=dict(type="str"), + dstPort=dict(type="int"), + dstPortRange=dict(type="str"), + dscp=dict(type="int"), + networkId=dict(type="str"), + qosRuleId=dict(type="str"), +)) + +required_if = [ + ("state", "present", ["networkId", "qosRuleId"], True), + ("state", "absent", ["networkId", "qosRuleId"], True), +] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class NetworksSwitchQosRulesOrder(object): + def __init__(self, params, meraki): + self.meraki = meraki + self.new_object = dict( + vlan=params.get("vlan"), + protocol=params.get("protocol"), + srcPort=params.get("srcPort"), + srcPortRange=params.get("srcPortRange"), + dstPort=params.get("dstPort"), + dstPortRange=params.get("dstPortRange"), + dscp=params.get("dscp"), + networkId=params.get("networkId"), + qosRuleId=params.get("qosRuleId"), + ) + + def get_all_params(self, name=None, id=None): + new_object_params = {} + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + return new_object_params + + def get_params_by_id(self, name=None, id=None): + new_object_params = {} + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + if self.new_object.get('qosRuleId') is not None or self.new_object.get('qos_rule_id') is not None: + new_object_params['qosRuleId'] = self.new_object.get('qosRuleId') or \ + self.new_object.get('qos_rule_id') + return new_object_params + + def create_params(self): + new_object_params = {} + if self.new_object.get('vlan') is not None or self.new_object.get('vlan') is not None: + new_object_params['vlan'] = self.new_object.get('vlan') or \ + self.new_object.get('vlan') + if self.new_object.get('protocol') is not None or self.new_object.get('protocol') is not None: + new_object_params['protocol'] = self.new_object.get('protocol') or \ + self.new_object.get('protocol') + if self.new_object.get('srcPort') is not None or self.new_object.get('src_port') is not None: + new_object_params['srcPort'] = self.new_object.get('srcPort') or \ + self.new_object.get('src_port') + if self.new_object.get('srcPortRange') is not None or self.new_object.get('src_port_range') is not None: + new_object_params['srcPortRange'] = self.new_object.get('srcPortRange') or \ + self.new_object.get('src_port_range') + if self.new_object.get('dstPort') is not None or self.new_object.get('dst_port') is not None: + new_object_params['dstPort'] = self.new_object.get('dstPort') or \ + self.new_object.get('dst_port') + if self.new_object.get('dstPortRange') is not None or self.new_object.get('dst_port_range') is not None: + new_object_params['dstPortRange'] = self.new_object.get('dstPortRange') or \ + self.new_object.get('dst_port_range') + if self.new_object.get('dscp') is not None or self.new_object.get('dscp') is not None: + new_object_params['dscp'] = self.new_object.get('dscp') or \ + self.new_object.get('dscp') + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + return new_object_params + + def delete_by_id_params(self): + new_object_params = {} + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + if self.new_object.get('qosRuleId') is not None or self.new_object.get('qos_rule_id') is not None: + new_object_params['qosRuleId'] = self.new_object.get('qosRuleId') or \ + self.new_object.get('qos_rule_id') + return new_object_params + + def update_by_id_params(self): + new_object_params = {} + if self.new_object.get('vlan') is not None or self.new_object.get('vlan') is not None: + new_object_params['vlan'] = self.new_object.get('vlan') or \ + self.new_object.get('vlan') + if self.new_object.get('protocol') is not None or self.new_object.get('protocol') is not None: + new_object_params['protocol'] = self.new_object.get('protocol') or \ + self.new_object.get('protocol') + if self.new_object.get('srcPort') is not None or self.new_object.get('src_port') is not None: + new_object_params['srcPort'] = self.new_object.get('srcPort') or \ + self.new_object.get('src_port') + if self.new_object.get('srcPortRange') is not None or self.new_object.get('src_port_range') is not None: + new_object_params['srcPortRange'] = self.new_object.get('srcPortRange') or \ + self.new_object.get('src_port_range') + if self.new_object.get('dstPort') is not None or self.new_object.get('dst_port') is not None: + new_object_params['dstPort'] = self.new_object.get('dstPort') or \ + self.new_object.get('dst_port') + if self.new_object.get('dstPortRange') is not None or self.new_object.get('dst_port_range') is not None: + new_object_params['dstPortRange'] = self.new_object.get('dstPortRange') or \ + self.new_object.get('dst_port_range') + if self.new_object.get('dscp') is not None or self.new_object.get('dscp') is not None: + new_object_params['dscp'] = self.new_object.get('dscp') or \ + self.new_object.get('dscp') + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + if self.new_object.get('qosRuleId') is not None or self.new_object.get('qos_rule_id') is not None: + new_object_params['qosRuleId'] = self.new_object.get('qosRuleId') or \ + self.new_object.get('qos_rule_id') + return new_object_params + + def get_object_by_name(self, name): + result = None + # NOTE: Does not have a get by name method or it is in another action + try: + items = self.meraki.exec_meraki( + family="switch", + function="getNetworkSwitchQosRules", + params=self.get_all_params(name=name), + ) + if isinstance(items, dict): + if 'response' in items: + items = items.get('response') + result = get_dict_result(items, 'name', name) + if result is None: + result = items + except Exception as e: + print("Error: ", e) + result = None + return result + + def get_object_by_id(self, id): + result = None + try: + items = self.meraki.exec_meraki( + family="switch", + function="getNetworkSwitchQosRule", + params=self.get_params_by_id() + ) + if isinstance(items, dict): + if 'response' in items: + items = items.get('response') + result = get_dict_result(items, 'qosRuleId', id) + except Exception as e: + print("Error: ", e) + result = None + return result + + def exists(self): + id_exists = False + name_exists = False + prev_obj = None + o_id = self.new_object.get("id") + o_id = o_id or self.new_object.get( + "qos_rule_id") or self.new_object.get("qosRuleId") + name = self.new_object.get("name") + if o_id: + prev_obj = self.get_object_by_id(o_id) + id_exists = prev_obj is not None and isinstance(prev_obj, dict) + if not id_exists and name: + prev_obj = self.get_object_by_name(name) + name_exists = prev_obj is not None and isinstance(prev_obj, dict) + if name_exists: + _id = prev_obj.get("id") + _id = _id or prev_obj.get("qosRuleId") + if id_exists and name_exists and o_id != _id: + raise InconsistentParameters( + "The 'id' and 'name' params don't refer to the same object") + if _id: + self.new_object.update(dict(id=_id)) + self.new_object.update(dict(qosRuleId=_id)) + if _id: + prev_obj = self.get_object_by_id(_id) + it_exists = prev_obj is not None and isinstance(prev_obj, dict) + return (it_exists, prev_obj) + + def requires_update(self, current_obj): + requested_obj = self.new_object + + obj_params = [ + ("vlan", "vlan"), + ("protocol", "protocol"), + ("srcPort", "srcPort"), + ("srcPortRange", "srcPortRange"), + ("dstPort", "dstPort"), + ("dstPortRange", "dstPortRange"), + ("dscp", "dscp"), + ("networkId", "networkId"), + ("qosRuleId", "qosRuleId"), + ] + # Method 1. Params present in request (Ansible) obj are the same as the current (DNAC) params + # If any does not have eq params, it requires update + return any(not meraki_compare_equality(current_obj.get(meraki_param), + requested_obj.get(ansible_param)) + for (meraki_param, ansible_param) in obj_params) + + def create(self): + result = self.meraki.exec_meraki( + family="switch", + function="createNetworkSwitchQosRule", + params=self.create_params(), + op_modifies=True, + ) + return result + + def update(self): + id = self.new_object.get("id") + id = id or self.new_object.get("qosRuleId") + name = self.new_object.get("name") + result = None + if not id: + prev_obj_name = self.get_object_by_name(name) + id_ = None + if prev_obj_name: + id_ = prev_obj_name.get("id") + id_ = id_ or prev_obj_name.get("qosRuleId") + if id_: + self.new_object.update(dict(qosRuleId=id_)) + result = self.meraki.exec_meraki( + family="switch", + function="updateNetworkSwitchQosRule", + params=self.update_by_id_params(), + op_modifies=True, + ) + return result + + def delete(self): + id = self.new_object.get("id") + id = id or self.new_object.get("qosRuleId") + name = self.new_object.get("name") + result = None + if not id: + prev_obj_name = self.get_object_by_name(name) + id_ = None + if prev_obj_name: + id_ = prev_obj_name.get("id") + id_ = id_ or prev_obj_name.get("qosRuleId") + if id_: + self.new_object.update(dict(qosRuleId=id_)) + result = self.meraki.exec_meraki( + family="switch", + function="deleteNetworkSwitchQosRule", + params=self.delete_by_id_params(), + ) + return result + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = False + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + meraki = MERAKI(self._task.args) + obj = NetworksSwitchQosRulesOrder(self._task.args, meraki) + + state = self._task.args.get("state") + + response = None + + if state == "present": + (obj_exists, prev_obj) = obj.exists() + if obj_exists: + if obj.requires_update(prev_obj): + response = obj.update() + meraki.object_updated() + else: + response = prev_obj + meraki.object_already_present() + else: + response = obj.create() + meraki.object_created() + + elif state == "absent": + (obj_exists, prev_obj) = obj.exists() + if obj_exists: + response = obj.delete() + meraki.object_deleted() + else: + meraki.object_already_absent() + + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_switch_qos_rules_order_info.py b/ansible_collections/cisco/meraki/plugins/action/networks_switch_qos_rules_order_info.py new file mode 100644 index 000000000..8eb3ed0fe --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_switch_qos_rules_order_info.py @@ -0,0 +1,112 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + networkId=dict(type="str"), + qosRuleId=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_object(self, params): + new_object = {} + if params.get("networkId") is not None: + new_object["networkId"] = params.get( + "networkId") + if params.get("qosRuleId") is not None: + new_object["qosRuleId"] = params.get( + "qosRuleId") + return new_object + + def get_all(self, params): + new_object = {} + if params.get("networkId") is not None: + new_object["networkId"] = params.get( + "networkId") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + id = self._task.args.get("qosRuleId") + if id: + response = meraki.exec_meraki( + family="switch", + function='getNetworkSwitchQosRule', + params=self.get_object(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result + if not id: + response = meraki.exec_meraki( + family="switch", + function='getNetworkSwitchQosRules', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_switch_routing_multicast.py b/ansible_collections/cisco/meraki/plugins/action/networks_switch_routing_multicast.py new file mode 100644 index 000000000..ea179dbff --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_switch_routing_multicast.py @@ -0,0 +1,206 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or +# https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, + meraki_compare_equality, + get_dict_result, +) +from ansible_collections.cisco.meraki.plugins.plugin_utils.exceptions import ( + InconsistentParameters, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + state=dict(type="str", default="present", choices=["present"]), + defaultSettings=dict(type="dict"), + overrides=dict(type="list"), + networkId=dict(type="str"), +)) + +required_if = [ + ("state", "present", ["networkId"], True), +] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class NetworksSwitchRoutingMulticast(object): + def __init__(self, params, meraki): + self.meraki = meraki + self.new_object = dict( + defaultSettings=params.get("defaultSettings"), + overrides=params.get("overrides"), + network_id=params.get("networkId"), + ) + + def get_all_params(self, name=None, id=None): + new_object_params = {} + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + return new_object_params + + def update_all_params(self): + new_object_params = {} + if self.new_object.get('defaultSettings') is not None or self.new_object.get('default_settings') is not None: + new_object_params['defaultSettings'] = self.new_object.get('defaultSettings') or \ + self.new_object.get('default_settings') + if self.new_object.get('overrides') is not None or self.new_object.get('overrides') is not None: + new_object_params['overrides'] = self.new_object.get('overrides') or \ + self.new_object.get('overrides') + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + return new_object_params + + def get_object_by_name(self, name): + result = None + # NOTE: Does not have a get by name method, using get all + try: + items = self.meraki.exec_meraki( + family="switch", + function="getNetworkSwitchRoutingMulticast", + params=self.get_all_params(name=name), + ) + if isinstance(items, dict): + if 'response' in items: + items = items.get('response') + result = get_dict_result(items, 'name', name) + if result is None: + result = items + except Exception as e: + print("Error: ", e) + result = None + return result + + def get_object_by_id(self, id): + result = None + # NOTE: Does not have a get by id method or it is in another action + return result + + def exists(self): + prev_obj = None + id_exists = False + name_exists = False + o_id = self.new_object.get("networkId") or self.new_object.get("network_id") + name = self.new_object.get("name") + if o_id: + prev_obj = self.get_object_by_name(o_id) + id_exists = prev_obj is not None and isinstance(prev_obj, dict) + if not id_exists and name: + prev_obj = self.get_object_by_name(name) + name_exists = prev_obj is not None and isinstance(prev_obj, dict) + if name_exists: + _id = prev_obj.get("id") + if id_exists and name_exists and o_id != _id: + raise InconsistentParameters( + "The 'id' and 'name' params don't refer to the same object") + if _id: + self.new_object.update(dict(id=_id)) + it_exists = prev_obj is not None and isinstance(prev_obj, dict) + return (it_exists, prev_obj) + + def requires_update(self, current_obj): + requested_obj = self.new_object + + obj_params = [ + ("defaultSettings", "defaultSettings"), + ("overrides", "overrides"), + ("networkId", "networkId"), + ] + # Method 1. Params present in request (Ansible) obj are the same as the current (ISE) params + # If any does not have eq params, it requires update + return any(not meraki_compare_equality(current_obj.get(meraki_param), + requested_obj.get(ansible_param)) + for (meraki_param, ansible_param) in obj_params) + + def update(self): + id = self.new_object.get("id") + name = self.new_object.get("name") + result = None + result = self.meraki.exec_meraki( + family="switch", + function="updateNetworkSwitchRoutingMulticast", + params=self.update_all_params(), + op_modifies=True, + ) + return result + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = False + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + meraki = MERAKI(self._task.args) + obj = NetworksSwitchRoutingMulticast(self._task.args, meraki) + + state = self._task.args.get("state") + + response = None + if state == "present": + (obj_exists, prev_obj) = obj.exists() + if obj_exists: + if obj.requires_update(prev_obj): + response = obj.update() + meraki.object_updated() + else: + response = prev_obj + meraki.object_already_present() + else: + meraki.fail_json( + "Object does not exists, plugin only has update") + + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_switch_routing_multicast_info.py b/ansible_collections/cisco/meraki/plugins/action/networks_switch_routing_multicast_info.py new file mode 100644 index 000000000..5e6902346 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_switch_routing_multicast_info.py @@ -0,0 +1,90 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + networkId=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_all(self, params): + new_object = {} + if params.get("networkId") is not None: + new_object["networkId"] = params.get( + "networkId") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="switch", + function='getNetworkSwitchRoutingMulticast', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_switch_routing_multicast_rendezvous_points.py b/ansible_collections/cisco/meraki/plugins/action/networks_switch_routing_multicast_rendezvous_points.py new file mode 100644 index 000000000..50015b535 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_switch_routing_multicast_rendezvous_points.py @@ -0,0 +1,311 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or +# https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, + meraki_compare_equality, + get_dict_result, +) +from ansible_collections.cisco.meraki.plugins.plugin_utils.exceptions import ( + InconsistentParameters, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + state=dict(type="str", default="present", choices=["present", "absent"]), + interfaceIp=dict(type="str"), + multicastGroup=dict(type="str"), + networkId=dict(type="str"), + rendezvousPointId=dict(type="str"), +)) + +required_if = [ + ("state", "present", ["networkId", "rendezvousPointId"], True), + ("state", "absent", ["networkId", "rendezvousPointId"], True), +] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class NetworksSwitchRoutingMulticastRendezvousPoints(object): + def __init__(self, params, meraki): + self.meraki = meraki + self.new_object = dict( + interfaceIp=params.get("interfaceIp"), + multicastGroup=params.get("multicastGroup"), + networkId=params.get("networkId"), + rendezvousPointId=params.get("rendezvousPointId"), + ) + + def get_all_params(self, name=None, id=None): + new_object_params = {} + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + return new_object_params + + def get_params_by_id(self, name=None, id=None): + new_object_params = {} + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + if self.new_object.get('rendezvousPointId') is not None or self.new_object.get('rendezvous_point_id') is not None: + new_object_params['rendezvousPointId'] = self.new_object.get('rendezvousPointId') or \ + self.new_object.get('rendezvous_point_id') + return new_object_params + + def create_params(self): + new_object_params = {} + if self.new_object.get('interfaceIp') is not None or self.new_object.get('interface_ip') is not None: + new_object_params['interfaceIp'] = self.new_object.get('interfaceIp') or \ + self.new_object.get('interface_ip') + if self.new_object.get('multicastGroup') is not None or self.new_object.get('multicast_group') is not None: + new_object_params['multicastGroup'] = self.new_object.get('multicastGroup') or \ + self.new_object.get('multicast_group') + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + return new_object_params + + def delete_by_id_params(self): + new_object_params = {} + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + if self.new_object.get('rendezvousPointId') is not None or self.new_object.get('rendezvous_point_id') is not None: + new_object_params['rendezvousPointId'] = self.new_object.get('rendezvousPointId') or \ + self.new_object.get('rendezvous_point_id') + return new_object_params + + def update_by_id_params(self): + new_object_params = {} + if self.new_object.get('interfaceIp') is not None or self.new_object.get('interface_ip') is not None: + new_object_params['interfaceIp'] = self.new_object.get('interfaceIp') or \ + self.new_object.get('interface_ip') + if self.new_object.get('multicastGroup') is not None or self.new_object.get('multicast_group') is not None: + new_object_params['multicastGroup'] = self.new_object.get('multicastGroup') or \ + self.new_object.get('multicast_group') + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + if self.new_object.get('rendezvousPointId') is not None or self.new_object.get('rendezvous_point_id') is not None: + new_object_params['rendezvousPointId'] = self.new_object.get('rendezvousPointId') or \ + self.new_object.get('rendezvous_point_id') + return new_object_params + + def get_object_by_name(self, name): + result = None + # NOTE: Does not have a get by name method or it is in another action + try: + items = self.meraki.exec_meraki( + family="switch", + function="getNetworkSwitchRoutingMulticastRendezvousPoints", + params=self.get_all_params(name=name), + ) + if isinstance(items, dict): + if 'response' in items: + items = items.get('response') + result = get_dict_result(items, 'name', name) + if result is None: + result = items + except Exception as e: + print("Error: ", e) + result = None + return result + + def get_object_by_id(self, id): + result = None + try: + items = self.meraki.exec_meraki( + family="switch", + function="getNetworkSwitchRoutingMulticastRendezvousPoint", + params=self.get_params_by_id() + ) + if isinstance(items, dict): + if 'response' in items: + items = items.get('response') + result = get_dict_result(items, 'rendezvousPointId', id) + except Exception as e: + print("Error: ", e) + result = None + return result + + def exists(self): + id_exists = False + name_exists = False + prev_obj = None + o_id = self.new_object.get("id") + o_id = o_id or self.new_object.get( + "rendezvous_point_id") or self.new_object.get("rendezvousPointId") + name = self.new_object.get("name") + if o_id: + prev_obj = self.get_object_by_id(o_id) + id_exists = prev_obj is not None and isinstance(prev_obj, dict) + if not id_exists and name: + prev_obj = self.get_object_by_name(name) + name_exists = prev_obj is not None and isinstance(prev_obj, dict) + if name_exists: + _id = prev_obj.get("id") + _id = _id or prev_obj.get("rendezvousPointId") + if id_exists and name_exists and o_id != _id: + raise InconsistentParameters( + "The 'id' and 'name' params don't refer to the same object") + if _id: + self.new_object.update(dict(id=_id)) + self.new_object.update(dict(rendezvousPointId=_id)) + if _id: + prev_obj = self.get_object_by_id(_id) + it_exists = prev_obj is not None and isinstance(prev_obj, dict) + return (it_exists, prev_obj) + + def requires_update(self, current_obj): + requested_obj = self.new_object + + obj_params = [ + ("interfaceIp", "interfaceIp"), + ("multicastGroup", "multicastGroup"), + ("networkId", "networkId"), + ("rendezvousPointId", "rendezvousPointId"), + ] + # Method 1. Params present in request (Ansible) obj are the same as the current (DNAC) params + # If any does not have eq params, it requires update + return any(not meraki_compare_equality(current_obj.get(meraki_param), + requested_obj.get(ansible_param)) + for (meraki_param, ansible_param) in obj_params) + + def create(self): + result = self.meraki.exec_meraki( + family="switch", + function="createNetworkSwitchRoutingMulticastRendezvousPoint", + params=self.create_params(), + op_modifies=True, + ) + return result + + def update(self): + id = self.new_object.get("id") + id = id or self.new_object.get("rendezvousPointId") + name = self.new_object.get("name") + result = None + if not id: + prev_obj_name = self.get_object_by_name(name) + id_ = None + if prev_obj_name: + id_ = prev_obj_name.get("id") + id_ = id_ or prev_obj_name.get("rendezvousPointId") + if id_: + self.new_object.update(dict(rendezvousPointId=id_)) + result = self.meraki.exec_meraki( + family="switch", + function="updateNetworkSwitchRoutingMulticastRendezvousPoint", + params=self.update_by_id_params(), + op_modifies=True, + ) + return result + + def delete(self): + id = self.new_object.get("id") + id = id or self.new_object.get("rendezvousPointId") + name = self.new_object.get("name") + result = None + if not id: + prev_obj_name = self.get_object_by_name(name) + id_ = None + if prev_obj_name: + id_ = prev_obj_name.get("id") + id_ = id_ or prev_obj_name.get("rendezvousPointId") + if id_: + self.new_object.update(dict(rendezvousPointId=id_)) + result = self.meraki.exec_meraki( + family="switch", + function="deleteNetworkSwitchRoutingMulticastRendezvousPoint", + params=self.delete_by_id_params(), + ) + return result + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = False + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + meraki = MERAKI(self._task.args) + obj = NetworksSwitchRoutingMulticastRendezvousPoints(self._task.args, meraki) + + state = self._task.args.get("state") + + response = None + + if state == "present": + (obj_exists, prev_obj) = obj.exists() + if obj_exists: + if obj.requires_update(prev_obj): + response = obj.update() + meraki.object_updated() + else: + response = prev_obj + meraki.object_already_present() + else: + response = obj.create() + meraki.object_created() + + elif state == "absent": + (obj_exists, prev_obj) = obj.exists() + if obj_exists: + response = obj.delete() + meraki.object_deleted() + else: + meraki.object_already_absent() + + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_switch_routing_multicast_rendezvous_points_info.py b/ansible_collections/cisco/meraki/plugins/action/networks_switch_routing_multicast_rendezvous_points_info.py new file mode 100644 index 000000000..75ddb7521 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_switch_routing_multicast_rendezvous_points_info.py @@ -0,0 +1,112 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + networkId=dict(type="str"), + rendezvousPointId=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_object(self, params): + new_object = {} + if params.get("networkId") is not None: + new_object["networkId"] = params.get( + "networkId") + if params.get("rendezvousPointId") is not None: + new_object["rendezvousPointId"] = params.get( + "rendezvousPointId") + return new_object + + def get_all(self, params): + new_object = {} + if params.get("networkId") is not None: + new_object["networkId"] = params.get( + "networkId") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + id = self._task.args.get("rendezvousPointId") + if id: + response = meraki.exec_meraki( + family="switch", + function='getNetworkSwitchRoutingMulticastRendezvousPoint', + params=self.get_object(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result + if not id: + response = meraki.exec_meraki( + family="switch", + function='getNetworkSwitchRoutingMulticastRendezvousPoints', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_switch_routing_ospf.py b/ansible_collections/cisco/meraki/plugins/action/networks_switch_routing_ospf.py new file mode 100644 index 000000000..ec0eed0ee --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_switch_routing_ospf.py @@ -0,0 +1,234 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or +# https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, + meraki_compare_equality, + get_dict_result, +) +from ansible_collections.cisco.meraki.plugins.plugin_utils.exceptions import ( + InconsistentParameters, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + state=dict(type="str", default="present", choices=["present"]), + enabled=dict(type="bool"), + helloTimerInSeconds=dict(type="int"), + deadTimerInSeconds=dict(type="int"), + areas=dict(type="list"), + v3=dict(type="dict"), + md5AuthenticationEnabled=dict(type="bool"), + md5AuthenticationKey=dict(type="dict"), + networkId=dict(type="str"), +)) + +required_if = [ + ("state", "present", ["networkId"], True), +] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class NetworksSwitchRoutingOspf(object): + def __init__(self, params, meraki): + self.meraki = meraki + self.new_object = dict( + enabled=params.get("enabled"), + helloTimerInSeconds=params.get("helloTimerInSeconds"), + deadTimerInSeconds=params.get("deadTimerInSeconds"), + areas=params.get("areas"), + v3=params.get("v3"), + md5AuthenticationEnabled=params.get("md5AuthenticationEnabled"), + md5AuthenticationKey=params.get("md5AuthenticationKey"), + network_id=params.get("networkId"), + ) + + def get_all_params(self, name=None, id=None): + new_object_params = {} + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + return new_object_params + + def update_all_params(self): + new_object_params = {} + if self.new_object.get('enabled') is not None or self.new_object.get('enabled') is not None: + new_object_params['enabled'] = self.new_object.get('enabled') + if self.new_object.get('helloTimerInSeconds') is not None or self.new_object.get('hello_timer_in_seconds') is not None: + new_object_params['helloTimerInSeconds'] = self.new_object.get('helloTimerInSeconds') or \ + self.new_object.get('hello_timer_in_seconds') + if self.new_object.get('deadTimerInSeconds') is not None or self.new_object.get('dead_timer_in_seconds') is not None: + new_object_params['deadTimerInSeconds'] = self.new_object.get('deadTimerInSeconds') or \ + self.new_object.get('dead_timer_in_seconds') + if self.new_object.get('areas') is not None or self.new_object.get('areas') is not None: + new_object_params['areas'] = self.new_object.get('areas') or \ + self.new_object.get('areas') + if self.new_object.get('v3') is not None or self.new_object.get('v3') is not None: + new_object_params['v3'] = self.new_object.get('v3') or \ + self.new_object.get('v3') + if self.new_object.get('md5AuthenticationEnabled') is not None or self.new_object.get('md5_authentication_enabled') is not None: + new_object_params['md5AuthenticationEnabled'] = self.new_object.get('md5AuthenticationEnabled') + if self.new_object.get('md5AuthenticationKey') is not None or self.new_object.get('md5_authentication_key') is not None: + new_object_params['md5AuthenticationKey'] = self.new_object.get('md5AuthenticationKey') or \ + self.new_object.get('md5_authentication_key') + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + return new_object_params + + def get_object_by_name(self, name): + result = None + # NOTE: Does not have a get by name method, using get all + try: + items = self.meraki.exec_meraki( + family="switch", + function="getNetworkSwitchRoutingOspf", + params=self.get_all_params(name=name), + ) + if isinstance(items, dict): + if 'response' in items: + items = items.get('response') + result = get_dict_result(items, 'name', name) + if result is None: + result = items + except Exception as e: + print("Error: ", e) + result = None + return result + + def get_object_by_id(self, id): + result = None + # NOTE: Does not have a get by id method or it is in another action + return result + + def exists(self): + prev_obj = None + id_exists = False + name_exists = False + o_id = self.new_object.get("networkId") or self.new_object.get("network_id") + name = self.new_object.get("name") + if o_id: + prev_obj = self.get_object_by_name(o_id) + id_exists = prev_obj is not None and isinstance(prev_obj, dict) + if not id_exists and name: + prev_obj = self.get_object_by_name(name) + name_exists = prev_obj is not None and isinstance(prev_obj, dict) + if name_exists: + _id = prev_obj.get("id") + if id_exists and name_exists and o_id != _id: + raise InconsistentParameters( + "The 'id' and 'name' params don't refer to the same object") + if _id: + self.new_object.update(dict(id=_id)) + it_exists = prev_obj is not None and isinstance(prev_obj, dict) + return (it_exists, prev_obj) + + def requires_update(self, current_obj): + requested_obj = self.new_object + + obj_params = [ + ("enabled", "enabled"), + ("helloTimerInSeconds", "helloTimerInSeconds"), + ("deadTimerInSeconds", "deadTimerInSeconds"), + ("areas", "areas"), + ("v3", "v3"), + ("md5AuthenticationEnabled", "md5AuthenticationEnabled"), + ("md5AuthenticationKey", "md5AuthenticationKey"), + ("networkId", "networkId"), + ] + # Method 1. Params present in request (Ansible) obj are the same as the current (ISE) params + # If any does not have eq params, it requires update + return any(not meraki_compare_equality(current_obj.get(meraki_param), + requested_obj.get(ansible_param)) + for (meraki_param, ansible_param) in obj_params) + + def update(self): + id = self.new_object.get("id") + name = self.new_object.get("name") + result = None + result = self.meraki.exec_meraki( + family="switch", + function="updateNetworkSwitchRoutingOspf", + params=self.update_all_params(), + op_modifies=True, + ) + return result + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = False + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + meraki = MERAKI(self._task.args) + obj = NetworksSwitchRoutingOspf(self._task.args, meraki) + + state = self._task.args.get("state") + + response = None + if state == "present": + (obj_exists, prev_obj) = obj.exists() + if obj_exists: + if obj.requires_update(prev_obj): + response = obj.update() + meraki.object_updated() + else: + response = prev_obj + meraki.object_already_present() + else: + meraki.fail_json( + "Object does not exists, plugin only has update") + + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_switch_routing_ospf_info.py b/ansible_collections/cisco/meraki/plugins/action/networks_switch_routing_ospf_info.py new file mode 100644 index 000000000..559023bf2 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_switch_routing_ospf_info.py @@ -0,0 +1,90 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + networkId=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_all(self, params): + new_object = {} + if params.get("networkId") is not None: + new_object["networkId"] = params.get( + "networkId") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="switch", + function='getNetworkSwitchRoutingOspf', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_switch_settings.py b/ansible_collections/cisco/meraki/plugins/action/networks_switch_settings.py new file mode 100644 index 000000000..65ae85bab --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_switch_settings.py @@ -0,0 +1,211 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or +# https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, + meraki_compare_equality, + get_dict_result, +) +from ansible_collections.cisco.meraki.plugins.plugin_utils.exceptions import ( + InconsistentParameters, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + state=dict(type="str", default="present", choices=["present"]), + vlan=dict(type="int"), + useCombinedPower=dict(type="bool"), + powerExceptions=dict(type="list"), + networkId=dict(type="str"), +)) + +required_if = [ + ("state", "present", ["networkId"], True), +] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class NetworksSwitchSettings(object): + def __init__(self, params, meraki): + self.meraki = meraki + self.new_object = dict( + vlan=params.get("vlan"), + useCombinedPower=params.get("useCombinedPower"), + powerExceptions=params.get("powerExceptions"), + network_id=params.get("networkId"), + ) + + def get_all_params(self, name=None, id=None): + new_object_params = {} + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + return new_object_params + + def update_all_params(self): + new_object_params = {} + if self.new_object.get('vlan') is not None or self.new_object.get('vlan') is not None: + new_object_params['vlan'] = self.new_object.get('vlan') or \ + self.new_object.get('vlan') + if self.new_object.get('useCombinedPower') is not None or self.new_object.get('use_combined_power') is not None: + new_object_params['useCombinedPower'] = self.new_object.get('useCombinedPower') + if self.new_object.get('powerExceptions') is not None or self.new_object.get('power_exceptions') is not None: + new_object_params['powerExceptions'] = self.new_object.get('powerExceptions') or \ + self.new_object.get('power_exceptions') + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + return new_object_params + + def get_object_by_name(self, name): + result = None + # NOTE: Does not have a get by name method, using get all + try: + items = self.meraki.exec_meraki( + family="switch", + function="getNetworkSwitchSettings", + params=self.get_all_params(name=name), + ) + if isinstance(items, dict): + if 'response' in items: + items = items.get('response') + result = get_dict_result(items, 'name', name) + if result is None: + result = items + except Exception as e: + print("Error: ", e) + result = None + return result + + def get_object_by_id(self, id): + result = None + # NOTE: Does not have a get by id method or it is in another action + return result + + def exists(self): + prev_obj = None + id_exists = False + name_exists = False + o_id = self.new_object.get("networkId") or self.new_object.get("network_id") + name = self.new_object.get("name") + if o_id: + prev_obj = self.get_object_by_name(o_id) + id_exists = prev_obj is not None and isinstance(prev_obj, dict) + if not id_exists and name: + prev_obj = self.get_object_by_name(name) + name_exists = prev_obj is not None and isinstance(prev_obj, dict) + if name_exists: + _id = prev_obj.get("id") + if id_exists and name_exists and o_id != _id: + raise InconsistentParameters( + "The 'id' and 'name' params don't refer to the same object") + if _id: + self.new_object.update(dict(id=_id)) + it_exists = prev_obj is not None and isinstance(prev_obj, dict) + return (it_exists, prev_obj) + + def requires_update(self, current_obj): + requested_obj = self.new_object + + obj_params = [ + ("vlan", "vlan"), + ("useCombinedPower", "useCombinedPower"), + ("powerExceptions", "powerExceptions"), + ("networkId", "networkId"), + ] + # Method 1. Params present in request (Ansible) obj are the same as the current (ISE) params + # If any does not have eq params, it requires update + return any(not meraki_compare_equality(current_obj.get(meraki_param), + requested_obj.get(ansible_param)) + for (meraki_param, ansible_param) in obj_params) + + def update(self): + id = self.new_object.get("id") + name = self.new_object.get("name") + result = None + result = self.meraki.exec_meraki( + family="switch", + function="updateNetworkSwitchSettings", + params=self.update_all_params(), + op_modifies=True, + ) + return result + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = False + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + meraki = MERAKI(self._task.args) + obj = NetworksSwitchSettings(self._task.args, meraki) + + state = self._task.args.get("state") + + response = None + if state == "present": + (obj_exists, prev_obj) = obj.exists() + if obj_exists: + if obj.requires_update(prev_obj): + response = obj.update() + meraki.object_updated() + else: + response = prev_obj + meraki.object_already_present() + else: + meraki.fail_json( + "Object does not exists, plugin only has update") + + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_switch_settings_info.py b/ansible_collections/cisco/meraki/plugins/action/networks_switch_settings_info.py new file mode 100644 index 000000000..dbdd01f58 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_switch_settings_info.py @@ -0,0 +1,90 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + networkId=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_all(self, params): + new_object = {} + if params.get("networkId") is not None: + new_object["networkId"] = params.get( + "networkId") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="switch", + function='getNetworkSwitchSettings', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_switch_stacks.py b/ansible_collections/cisco/meraki/plugins/action/networks_switch_stacks.py new file mode 100644 index 000000000..48c70de8f --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_switch_stacks.py @@ -0,0 +1,272 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or +# https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, + meraki_compare_equality, + get_dict_result, +) +from ansible_collections.cisco.meraki.plugins.plugin_utils.exceptions import ( + InconsistentParameters, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + state=dict(type="str", default="present", choices=["present", "absent"]), + name=dict(type="str"), + serials=dict(type="list"), + networkId=dict(type="str"), + switchStackId=dict(type="str"), +)) + +required_if = [ + ("state", "present", ["name", "networkId", "switchStackId"], True), + ("state", "absent", ["name", "networkId", "switchStackId"], True), +] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class NetworksSwitchStacks(object): + def __init__(self, params, meraki): + self.meraki = meraki + self.new_object = dict( + name=params.get("name"), + serials=params.get("serials"), + network_id=params.get("networkId"), + switch_stack_id=params.get("switchStackId"), + ) + + def get_all_params(self, name=None, id=None): + new_object_params = {} + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + return new_object_params + + def get_params_by_id(self, name=None, id=None): + new_object_params = {} + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + if self.new_object.get('switchStackId') is not None or self.new_object.get('switch_stack_id') is not None: + new_object_params['switchStackId'] = self.new_object.get('switchStackId') or \ + self.new_object.get('switch_stack_id') + return new_object_params + + def create_params(self): + new_object_params = {} + if self.new_object.get('name') is not None or self.new_object.get('name') is not None: + new_object_params['name'] = self.new_object.get('name') or \ + self.new_object.get('name') + if self.new_object.get('serials') is not None or self.new_object.get('serials') is not None: + new_object_params['serials'] = self.new_object.get('serials') or \ + self.new_object.get('serials') + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + return new_object_params + + def delete_by_id_params(self): + new_object_params = {} + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + if self.new_object.get('switchStackId') is not None or self.new_object.get('switch_stack_id') is not None: + new_object_params['switchStackId'] = self.new_object.get('switchStackId') or \ + self.new_object.get('switch_stack_id') + return new_object_params + + def get_object_by_name(self, name): + result = None + # NOTE: Does not have a get by name method, using get all + try: + items = self.meraki.exec_meraki( + family="switch", + function="getNetworkSwitchStacks", + params=self.get_all_params(name=name), + ) + if isinstance(items, dict): + if 'response' in items: + items = items.get('response') + result = get_dict_result(items, 'name', name) + if result is None: + result = items + except Exception as e: + print("Error: ", e) + result = None + return result + + def get_object_by_id(self, id): + result = None + try: + items = self.meraki.exec_meraki( + family="switch", + function="getNetworkSwitchStack", + params=self.get_params_by_id() + ) + if isinstance(items, dict): + if 'response' in items: + items = items.get('response') + result = items + except Exception as e: + print("Error: ", e) + result = None + return result + + def exists(self): + prev_obj = None + id_exists = False + name_exists = False + o_id = self.new_object.get("networkId") or self.new_object.get("network_id") + o_id = o_id or self.new_object.get( + "switch_stack_id") or self.new_object.get("switchStackId") + name = self.new_object.get("name") + if o_id: + prev_obj = self.get_object_by_id(o_id) + id_exists = prev_obj is not None and isinstance(prev_obj, dict) + if not id_exists and name: + prev_obj = self.get_object_by_name(name) + name_exists = prev_obj is not None and isinstance(prev_obj, dict) + if name_exists: + _id = prev_obj.get("id") + _id = _id or prev_obj.get("switchStackId") + if id_exists and name_exists and o_id != _id: + raise InconsistentParameters( + "The 'id' and 'name' params don't refer to the same object") + if _id: + self.new_object.update(dict(id=_id)) + self.new_object.update(dict(switchStackId=_id)) + if _id: + prev_obj = self.get_object_by_id(_id) + it_exists = prev_obj is not None and isinstance(prev_obj, dict) + return (it_exists, prev_obj) + + def requires_update(self, current_obj): + requested_obj = self.new_object + + obj_params = [ + ("name", "name"), + ("serials", "serials"), + ("networkId", "networkId"), + ("switchStackId", "switchStackId"), + ] + # Method 1. Params present in request (Ansible) obj are the same as the current (ISE) params + # If any does not have eq params, it requires update + return any(not meraki_compare_equality(current_obj.get(meraki_param), + requested_obj.get(ansible_param)) + for (meraki_param, ansible_param) in obj_params) + + def create(self): + result = self.meraki.exec_meraki( + family="switch", + function="createNetworkSwitchStack", + params=self.create_params(), + op_modifies=True, + ) + return result + + def delete(self): + id = self.new_object.get("id") + id = id or self.new_object.get("switchStackId") + name = self.new_object.get("name") + result = None + if not id: + prev_obj_name = self.get_object_by_name(name) + id_ = None + if prev_obj_name: + id_ = prev_obj_name.get("id") + id_ = id_ or prev_obj_name.get("switchStackId") + if id_: + self.new_object.update(dict(switchstackid=id_)) + result = self.meraki.exec_meraki( + family="switch", + function="deleteNetworkSwitchStack", + params=self.delete_by_id_params(), + ) + return result + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = False + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + meraki = MERAKI(self._task.args) + obj = NetworksSwitchStacks(self._task.args, meraki) + + state = self._task.args.get("state") + + response = None + if state == "present": + (obj_exists, prev_obj) = obj.exists() + if obj_exists: + if obj.requires_update(prev_obj): + response = prev_obj + meraki.object_present_and_different() + else: + response = prev_obj + meraki.object_already_present() + else: + response = obj.create() + meraki.object_created() + elif state == "absent": + (obj_exists, prev_obj) = obj.exists() + if obj_exists: + response = obj.delete() + meraki.object_deleted() + else: + meraki.object_already_absent() + + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_switch_stacks_add.py b/ansible_collections/cisco/meraki/plugins/action/networks_switch_stacks_add.py new file mode 100644 index 000000000..7e1ae177c --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_switch_stacks_add.py @@ -0,0 +1,91 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguements specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + serial=dict(type="str"), + networkId=dict(type="str"), + switchStackId=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = False + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_object(self, params): + new_object = dict( + serial=params.get("serial"), + networkId=params.get("networkId"), + switchStackId=params.get("switchStackId"), + ) + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="switch", + function='addNetworkSwitchStack', + op_modifies=True, + params=self.get_object(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_switch_stacks_info.py b/ansible_collections/cisco/meraki/plugins/action/networks_switch_stacks_info.py new file mode 100644 index 000000000..461e43885 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_switch_stacks_info.py @@ -0,0 +1,112 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + networkId=dict(type="str"), + switchStackId=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_object(self, params): + new_object = {} + if params.get("networkId") is not None: + new_object["networkId"] = params.get( + "networkId") + if params.get("switchStackId") is not None: + new_object["switchStackId"] = params.get( + "switchStackId") + return new_object + + def get_all(self, params): + new_object = {} + if params.get("networkId") is not None: + new_object["networkId"] = params.get( + "networkId") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + id = self._task.args.get("switchStackId") + if id: + response = meraki.exec_meraki( + family="switch", + function='getNetworkSwitchStack', + params=self.get_object(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result + if not id: + response = meraki.exec_meraki( + family="switch", + function='getNetworkSwitchStacks', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_switch_stacks_remove.py b/ansible_collections/cisco/meraki/plugins/action/networks_switch_stacks_remove.py new file mode 100644 index 000000000..6dc97f052 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_switch_stacks_remove.py @@ -0,0 +1,91 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguements specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + serial=dict(type="str"), + networkId=dict(type="str"), + switchStackId=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = False + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_object(self, params): + new_object = dict( + serial=params.get("serial"), + networkId=params.get("networkId"), + switchStackId=params.get("switchStackId"), + ) + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="switch", + function='removeNetworkSwitchStack', + op_modifies=True, + params=self.get_object(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_switch_stacks_routing_interfaces.py b/ansible_collections/cisco/meraki/plugins/action/networks_switch_stacks_routing_interfaces.py new file mode 100644 index 000000000..948b77458 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_switch_stacks_routing_interfaces.py @@ -0,0 +1,383 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or +# https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, + meraki_compare_equality, + get_dict_result, +) +from ansible_collections.cisco.meraki.plugins.plugin_utils.exceptions import ( + InconsistentParameters, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + state=dict(type="str", default="present", choices=["present", "absent"]), + name=dict(type="str"), + subnet=dict(type="str"), + interfaceIp=dict(type="str"), + multicastRouting=dict(type="str"), + vlanId=dict(type="int"), + defaultGateway=dict(type="str"), + ospfSettings=dict(type="dict"), + ipv6=dict(type="dict"), + networkId=dict(type="str"), + switchStackId=dict(type="str"), + interfaceId=dict(type="str"), +)) + +required_if = [ + ("state", "present", ["interfaceId", "name", "networkId", "switchStackId"], True), + ("state", "absent", ["interfaceId", "name", "networkId", "switchStackId"], True), +] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class NetworksSwitchStacksRoutingInterfaces(object): + def __init__(self, params, meraki): + self.meraki = meraki + self.new_object = dict( + name=params.get("name"), + subnet=params.get("subnet"), + interfaceIp=params.get("interfaceIp"), + multicastRouting=params.get("multicastRouting"), + vlanId=params.get("vlanId"), + defaultGateway=params.get("defaultGateway"), + ospfSettings=params.get("ospfSettings"), + ipv6=params.get("ipv6"), + networkId=params.get("networkId"), + switchStackId=params.get("switchStackId"), + interfaceId=params.get("interfaceId"), + ) + + def get_all_params(self, name=None, id=None): + new_object_params = {} + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + if self.new_object.get('switchStackId') is not None or self.new_object.get('switch_stack_id') is not None: + new_object_params['switchStackId'] = self.new_object.get('switchStackId') or \ + self.new_object.get('switch_stack_id') + return new_object_params + + def get_params_by_id(self, name=None, id=None): + new_object_params = {} + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + if self.new_object.get('switchStackId') is not None or self.new_object.get('switch_stack_id') is not None: + new_object_params['switchStackId'] = self.new_object.get('switchStackId') or \ + self.new_object.get('switch_stack_id') + if self.new_object.get('interfaceId') is not None or self.new_object.get('interface_id') is not None: + new_object_params['interfaceId'] = self.new_object.get('interfaceId') or \ + self.new_object.get('interface_id') + return new_object_params + + def create_params(self): + new_object_params = {} + if self.new_object.get('name') is not None or self.new_object.get('name') is not None: + new_object_params['name'] = self.new_object.get('name') or \ + self.new_object.get('name') + if self.new_object.get('subnet') is not None or self.new_object.get('subnet') is not None: + new_object_params['subnet'] = self.new_object.get('subnet') or \ + self.new_object.get('subnet') + if self.new_object.get('interfaceIp') is not None or self.new_object.get('interface_ip') is not None: + new_object_params['interfaceIp'] = self.new_object.get('interfaceIp') or \ + self.new_object.get('interface_ip') + if self.new_object.get('multicastRouting') is not None or self.new_object.get('multicast_routing') is not None: + new_object_params['multicastRouting'] = self.new_object.get('multicastRouting') or \ + self.new_object.get('multicast_routing') + if self.new_object.get('vlanId') is not None or self.new_object.get('vlan_id') is not None: + new_object_params['vlanId'] = self.new_object.get('vlanId') or \ + self.new_object.get('vlan_id') + if self.new_object.get('defaultGateway') is not None or self.new_object.get('default_gateway') is not None: + new_object_params['defaultGateway'] = self.new_object.get('defaultGateway') or \ + self.new_object.get('default_gateway') + if self.new_object.get('ospfSettings') is not None or self.new_object.get('ospf_settings') is not None: + new_object_params['ospfSettings'] = self.new_object.get('ospfSettings') or \ + self.new_object.get('ospf_settings') + if self.new_object.get('ipv6') is not None or self.new_object.get('ipv6') is not None: + new_object_params['ipv6'] = self.new_object.get('ipv6') or \ + self.new_object.get('ipv6') + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + if self.new_object.get('switchStackId') is not None or self.new_object.get('switch_stack_id') is not None: + new_object_params['switchStackId'] = self.new_object.get('switchStackId') or \ + self.new_object.get('switch_stack_id') + return new_object_params + + def delete_by_id_params(self): + new_object_params = {} + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + if self.new_object.get('switchStackId') is not None or self.new_object.get('switch_stack_id') is not None: + new_object_params['switchStackId'] = self.new_object.get('switchStackId') or \ + self.new_object.get('switch_stack_id') + if self.new_object.get('interfaceId') is not None or self.new_object.get('interface_id') is not None: + new_object_params['interfaceId'] = self.new_object.get('interfaceId') or \ + self.new_object.get('interface_id') + return new_object_params + + def update_by_id_params(self): + new_object_params = {} + if self.new_object.get('name') is not None or self.new_object.get('name') is not None: + new_object_params['name'] = self.new_object.get('name') or \ + self.new_object.get('name') + if self.new_object.get('subnet') is not None or self.new_object.get('subnet') is not None: + new_object_params['subnet'] = self.new_object.get('subnet') or \ + self.new_object.get('subnet') + if self.new_object.get('interfaceIp') is not None or self.new_object.get('interface_ip') is not None: + new_object_params['interfaceIp'] = self.new_object.get('interfaceIp') or \ + self.new_object.get('interface_ip') + if self.new_object.get('multicastRouting') is not None or self.new_object.get('multicast_routing') is not None: + new_object_params['multicastRouting'] = self.new_object.get('multicastRouting') or \ + self.new_object.get('multicast_routing') + if self.new_object.get('vlanId') is not None or self.new_object.get('vlan_id') is not None: + new_object_params['vlanId'] = self.new_object.get('vlanId') or \ + self.new_object.get('vlan_id') + if self.new_object.get('defaultGateway') is not None or self.new_object.get('default_gateway') is not None: + new_object_params['defaultGateway'] = self.new_object.get('defaultGateway') or \ + self.new_object.get('default_gateway') + if self.new_object.get('ospfSettings') is not None or self.new_object.get('ospf_settings') is not None: + new_object_params['ospfSettings'] = self.new_object.get('ospfSettings') or \ + self.new_object.get('ospf_settings') + if self.new_object.get('ipv6') is not None or self.new_object.get('ipv6') is not None: + new_object_params['ipv6'] = self.new_object.get('ipv6') or \ + self.new_object.get('ipv6') + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + if self.new_object.get('switchStackId') is not None or self.new_object.get('switch_stack_id') is not None: + new_object_params['switchStackId'] = self.new_object.get('switchStackId') or \ + self.new_object.get('switch_stack_id') + if self.new_object.get('interfaceId') is not None or self.new_object.get('interface_id') is not None: + new_object_params['interfaceId'] = self.new_object.get('interfaceId') or \ + self.new_object.get('interface_id') + return new_object_params + + def get_object_by_name(self, name): + result = None + # NOTE: Does not have a get by name method or it is in another action + try: + items = self.meraki.exec_meraki( + family="switch", + function="getNetworkSwitchStackRoutingInterfaces", + params=self.get_all_params(name=name), + ) + if isinstance(items, dict): + if 'response' in items: + items = items.get('response') + result = get_dict_result(items, 'name', name) + if result is None: + result = items + except Exception as e: + print("Error: ", e) + result = None + return result + + def get_object_by_id(self, id): + result = None + try: + items = self.meraki.exec_meraki( + family="switch", + function="getNetworkSwitchStackRoutingInterface", + params=self.get_params_by_id() + ) + if isinstance(items, dict): + if 'response' in items: + items = items.get('response') + result = get_dict_result(items, 'interfaceId', id) + except Exception as e: + print("Error: ", e) + result = None + return result + + def exists(self): + id_exists = False + name_exists = False + prev_obj = None + o_id = self.new_object.get("id") + o_id = o_id or self.new_object.get( + "interface_id") or self.new_object.get("interfaceId") + name = self.new_object.get("name") + if o_id: + prev_obj = self.get_object_by_id(o_id) + id_exists = prev_obj is not None and isinstance(prev_obj, dict) + if not id_exists and name: + prev_obj = self.get_object_by_name(name) + name_exists = prev_obj is not None and isinstance(prev_obj, dict) + if name_exists: + _id = prev_obj.get("id") + _id = _id or prev_obj.get("interfaceId") + if id_exists and name_exists and o_id != _id: + raise InconsistentParameters( + "The 'id' and 'name' params don't refer to the same object") + if _id: + self.new_object.update(dict(id=_id)) + self.new_object.update(dict(interfaceId=_id)) + if _id: + prev_obj = self.get_object_by_id(_id) + it_exists = prev_obj is not None and isinstance(prev_obj, dict) + return (it_exists, prev_obj) + + def requires_update(self, current_obj): + requested_obj = self.new_object + + obj_params = [ + ("name", "name"), + ("subnet", "subnet"), + ("interfaceIp", "interfaceIp"), + ("multicastRouting", "multicastRouting"), + ("vlanId", "vlanId"), + ("defaultGateway", "defaultGateway"), + ("ospfSettings", "ospfSettings"), + ("ipv6", "ipv6"), + ("networkId", "networkId"), + ("switchStackId", "switchStackId"), + ("interfaceId", "interfaceId"), + ] + # Method 1. Params present in request (Ansible) obj are the same as the current (DNAC) params + # If any does not have eq params, it requires update + return any(not meraki_compare_equality(current_obj.get(meraki_param), + requested_obj.get(ansible_param)) + for (meraki_param, ansible_param) in obj_params) + + def create(self): + result = self.meraki.exec_meraki( + family="switch", + function="createNetworkSwitchStackRoutingInterface", + params=self.create_params(), + op_modifies=True, + ) + return result + + def update(self): + id = self.new_object.get("id") + id = id or self.new_object.get("interfaceId") + name = self.new_object.get("name") + result = None + if not id: + prev_obj_name = self.get_object_by_name(name) + id_ = None + if prev_obj_name: + id_ = prev_obj_name.get("id") + id_ = id_ or prev_obj_name.get("interfaceId") + if id_: + self.new_object.update(dict(interfaceId=id_)) + result = self.meraki.exec_meraki( + family="switch", + function="updateNetworkSwitchStackRoutingInterface", + params=self.update_by_id_params(), + op_modifies=True, + ) + return result + + def delete(self): + id = self.new_object.get("id") + id = id or self.new_object.get("interfaceId") + name = self.new_object.get("name") + result = None + if not id: + prev_obj_name = self.get_object_by_name(name) + id_ = None + if prev_obj_name: + id_ = prev_obj_name.get("id") + id_ = id_ or prev_obj_name.get("interfaceId") + if id_: + self.new_object.update(dict(interfaceId=id_)) + result = self.meraki.exec_meraki( + family="switch", + function="deleteNetworkSwitchStackRoutingInterface", + params=self.delete_by_id_params(), + ) + return result + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = False + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + meraki = MERAKI(self._task.args) + obj = NetworksSwitchStacksRoutingInterfaces(self._task.args, meraki) + + state = self._task.args.get("state") + + response = None + + if state == "present": + (obj_exists, prev_obj) = obj.exists() + if obj_exists: + if obj.requires_update(prev_obj): + response = obj.update() + meraki.object_updated() + else: + response = prev_obj + meraki.object_already_present() + else: + response = obj.create() + meraki.object_created() + + elif state == "absent": + (obj_exists, prev_obj) = obj.exists() + if obj_exists: + response = obj.delete() + meraki.object_deleted() + else: + meraki.object_already_absent() + + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_switch_stacks_routing_interfaces_dhcp.py b/ansible_collections/cisco/meraki/plugins/action/networks_switch_stacks_routing_interfaces_dhcp.py new file mode 100644 index 000000000..0127666a5 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_switch_stacks_routing_interfaces_dhcp.py @@ -0,0 +1,277 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or +# https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, + meraki_compare_equality, + get_dict_result, +) +from ansible_collections.cisco.meraki.plugins.plugin_utils.exceptions import ( + InconsistentParameters, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + state=dict(type="str", default="present", choices=["present"]), + dhcpMode=dict(type="str"), + dhcpRelayServerIps=dict(type="list"), + dhcpLeaseTime=dict(type="str"), + dnsNameserversOption=dict(type="str"), + dnsCustomNameservers=dict(type="list"), + bootOptionsEnabled=dict(type="bool"), + bootNextServer=dict(type="str"), + bootFileName=dict(type="str"), + dhcpOptions=dict(type="list"), + reservedIpRanges=dict(type="list"), + fixedIpAssignments=dict(type="list"), + networkId=dict(type="str"), + switchStackId=dict(type="str"), + interfaceId=dict(type="str"), +)) + +required_if = [ + ("state", "present", ["interfaceId", "networkId", "switchStackId"], True), +] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class NetworksSwitchStacksRoutingInterfacesDhcp(object): + def __init__(self, params, meraki): + self.meraki = meraki + self.new_object = dict( + dhcpMode=params.get("dhcpMode"), + dhcpRelayServerIps=params.get("dhcpRelayServerIps"), + dhcpLeaseTime=params.get("dhcpLeaseTime"), + dnsNameserversOption=params.get("dnsNameserversOption"), + dnsCustomNameservers=params.get("dnsCustomNameservers"), + bootOptionsEnabled=params.get("bootOptionsEnabled"), + bootNextServer=params.get("bootNextServer"), + bootFileName=params.get("bootFileName"), + dhcpOptions=params.get("dhcpOptions"), + reservedIpRanges=params.get("reservedIpRanges"), + fixedIpAssignments=params.get("fixedIpAssignments"), + network_id=params.get("networkId"), + switch_stack_id=params.get("switchStackId"), + interface_id=params.get("interfaceId"), + ) + + def get_all_params(self, name=None, id=None): + new_object_params = {} + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + if self.new_object.get('switchStackId') is not None or self.new_object.get('switch_stack_id') is not None: + new_object_params['switchStackId'] = self.new_object.get('switchStackId') or \ + self.new_object.get('switch_stack_id') + if self.new_object.get('interfaceId') is not None or self.new_object.get('interface_id') is not None: + new_object_params['interfaceId'] = self.new_object.get('interfaceId') or \ + self.new_object.get('interface_id') + return new_object_params + + def update_all_params(self): + new_object_params = {} + if self.new_object.get('dhcpMode') is not None or self.new_object.get('dhcp_mode') is not None: + new_object_params['dhcpMode'] = self.new_object.get('dhcpMode') or \ + self.new_object.get('dhcp_mode') + if self.new_object.get('dhcpRelayServerIps') is not None or self.new_object.get('dhcp_relay_server_ips') is not None: + new_object_params['dhcpRelayServerIps'] = self.new_object.get('dhcpRelayServerIps') or \ + self.new_object.get('dhcp_relay_server_ips') + if self.new_object.get('dhcpLeaseTime') is not None or self.new_object.get('dhcp_lease_time') is not None: + new_object_params['dhcpLeaseTime'] = self.new_object.get('dhcpLeaseTime') or \ + self.new_object.get('dhcp_lease_time') + if self.new_object.get('dnsNameserversOption') is not None or self.new_object.get('dns_nameservers_option') is not None: + new_object_params['dnsNameserversOption'] = self.new_object.get('dnsNameserversOption') or \ + self.new_object.get('dns_nameservers_option') + if self.new_object.get('dnsCustomNameservers') is not None or self.new_object.get('dns_custom_nameservers') is not None: + new_object_params['dnsCustomNameservers'] = self.new_object.get('dnsCustomNameservers') or \ + self.new_object.get('dns_custom_nameservers') + if self.new_object.get('bootOptionsEnabled') is not None or self.new_object.get('boot_options_enabled') is not None: + new_object_params['bootOptionsEnabled'] = self.new_object.get('bootOptionsEnabled') + if self.new_object.get('bootNextServer') is not None or self.new_object.get('boot_next_server') is not None: + new_object_params['bootNextServer'] = self.new_object.get('bootNextServer') or \ + self.new_object.get('boot_next_server') + if self.new_object.get('bootFileName') is not None or self.new_object.get('boot_file_name') is not None: + new_object_params['bootFileName'] = self.new_object.get('bootFileName') or \ + self.new_object.get('boot_file_name') + if self.new_object.get('dhcpOptions') is not None or self.new_object.get('dhcp_options') is not None: + new_object_params['dhcpOptions'] = self.new_object.get('dhcpOptions') or \ + self.new_object.get('dhcp_options') + if self.new_object.get('reservedIpRanges') is not None or self.new_object.get('reserved_ip_ranges') is not None: + new_object_params['reservedIpRanges'] = self.new_object.get('reservedIpRanges') or \ + self.new_object.get('reserved_ip_ranges') + if self.new_object.get('fixedIpAssignments') is not None or self.new_object.get('fixed_ip_assignments') is not None: + new_object_params['fixedIpAssignments'] = self.new_object.get('fixedIpAssignments') or \ + self.new_object.get('fixed_ip_assignments') + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + if self.new_object.get('switchStackId') is not None or self.new_object.get('switch_stack_id') is not None: + new_object_params['switchStackId'] = self.new_object.get('switchStackId') or \ + self.new_object.get('switch_stack_id') + if self.new_object.get('interfaceId') is not None or self.new_object.get('interface_id') is not None: + new_object_params['interfaceId'] = self.new_object.get('interfaceId') or \ + self.new_object.get('interface_id') + return new_object_params + + def get_object_by_name(self, name): + result = None + # NOTE: Does not have a get by name method, using get all + try: + items = self.meraki.exec_meraki( + family="switch", + function="getNetworkSwitchStackRoutingInterfaceDhcp", + params=self.get_all_params(name=name), + ) + if isinstance(items, dict): + if 'response' in items: + items = items.get('response') + result = get_dict_result(items, 'name', name) + if result is None: + result = items + except Exception as e: + print("Error: ", e) + result = None + return result + + def get_object_by_id(self, id): + result = None + # NOTE: Does not have a get by id method or it is in another action + return result + + def exists(self): + prev_obj = None + id_exists = False + name_exists = False + o_id = self.new_object.get("networkId") or self.new_object.get("network_id") + name = self.new_object.get("name") + if o_id: + prev_obj = self.get_object_by_name(o_id) + id_exists = prev_obj is not None and isinstance(prev_obj, dict) + if not id_exists and name: + prev_obj = self.get_object_by_name(name) + name_exists = prev_obj is not None and isinstance(prev_obj, dict) + if name_exists: + _id = prev_obj.get("id") + if id_exists and name_exists and o_id != _id: + raise InconsistentParameters( + "The 'id' and 'name' params don't refer to the same object") + if _id: + self.new_object.update(dict(id=_id)) + it_exists = prev_obj is not None and isinstance(prev_obj, dict) + return (it_exists, prev_obj) + + def requires_update(self, current_obj): + requested_obj = self.new_object + + obj_params = [ + ("dhcpMode", "dhcpMode"), + ("dhcpRelayServerIps", "dhcpRelayServerIps"), + ("dhcpLeaseTime", "dhcpLeaseTime"), + ("dnsNameserversOption", "dnsNameserversOption"), + ("dnsCustomNameservers", "dnsCustomNameservers"), + ("bootOptionsEnabled", "bootOptionsEnabled"), + ("bootNextServer", "bootNextServer"), + ("bootFileName", "bootFileName"), + ("dhcpOptions", "dhcpOptions"), + ("reservedIpRanges", "reservedIpRanges"), + ("fixedIpAssignments", "fixedIpAssignments"), + ("networkId", "networkId"), + ("switchStackId", "switchStackId"), + ("interfaceId", "interfaceId"), + ] + # Method 1. Params present in request (Ansible) obj are the same as the current (ISE) params + # If any does not have eq params, it requires update + return any(not meraki_compare_equality(current_obj.get(meraki_param), + requested_obj.get(ansible_param)) + for (meraki_param, ansible_param) in obj_params) + + def update(self): + id = self.new_object.get("id") + name = self.new_object.get("name") + result = None + result = self.meraki.exec_meraki( + family="switch", + function="updateNetworkSwitchStackRoutingInterfaceDhcp", + params=self.update_all_params(), + op_modifies=True, + ) + return result + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = False + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + meraki = MERAKI(self._task.args) + obj = NetworksSwitchStacksRoutingInterfacesDhcp(self._task.args, meraki) + + state = self._task.args.get("state") + + response = None + if state == "present": + (obj_exists, prev_obj) = obj.exists() + if obj_exists: + if obj.requires_update(prev_obj): + response = obj.update() + meraki.object_updated() + else: + response = prev_obj + meraki.object_already_present() + else: + meraki.fail_json( + "Object does not exists, plugin only has update") + + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_switch_stacks_routing_interfaces_dhcp_info.py b/ansible_collections/cisco/meraki/plugins/action/networks_switch_stacks_routing_interfaces_dhcp_info.py new file mode 100644 index 000000000..03d12e612 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_switch_stacks_routing_interfaces_dhcp_info.py @@ -0,0 +1,98 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + networkId=dict(type="str"), + switchStackId=dict(type="str"), + interfaceId=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_all(self, params): + new_object = {} + if params.get("networkId") is not None: + new_object["networkId"] = params.get( + "networkId") + if params.get("switchStackId") is not None: + new_object["switchStackId"] = params.get( + "switchStackId") + if params.get("interfaceId") is not None: + new_object["interfaceId"] = params.get( + "interfaceId") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="switch", + function='getNetworkSwitchStackRoutingInterfaceDhcp', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_switch_stacks_routing_interfaces_info.py b/ansible_collections/cisco/meraki/plugins/action/networks_switch_stacks_routing_interfaces_info.py new file mode 100644 index 000000000..f4c70b15d --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_switch_stacks_routing_interfaces_info.py @@ -0,0 +1,119 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + networkId=dict(type="str"), + switchStackId=dict(type="str"), + interfaceId=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_object(self, params): + new_object = {} + if params.get("networkId") is not None: + new_object["networkId"] = params.get( + "networkId") + if params.get("switchStackId") is not None: + new_object["switchStackId"] = params.get( + "switchStackId") + if params.get("interfaceId") is not None: + new_object["interfaceId"] = params.get( + "interfaceId") + return new_object + + def get_all(self, params): + new_object = {} + if params.get("networkId") is not None: + new_object["networkId"] = params.get( + "networkId") + if params.get("switchStackId") is not None: + new_object["switchStackId"] = params.get( + "switchStackId") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + id = self._task.args.get("interfaceId") + if id: + response = meraki.exec_meraki( + family="switch", + function='getNetworkSwitchStackRoutingInterface', + params=self.get_object(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result + if not id: + response = meraki.exec_meraki( + family="switch", + function='getNetworkSwitchStackRoutingInterfaces', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_switch_stacks_routing_static_routes.py b/ansible_collections/cisco/meraki/plugins/action/networks_switch_stacks_routing_static_routes.py new file mode 100644 index 000000000..1ac473570 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_switch_stacks_routing_static_routes.py @@ -0,0 +1,352 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or +# https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, + meraki_compare_equality, + get_dict_result, +) +from ansible_collections.cisco.meraki.plugins.plugin_utils.exceptions import ( + InconsistentParameters, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + state=dict(type="str", default="present", choices=["present", "absent"]), + name=dict(type="str"), + subnet=dict(type="str"), + nextHopIp=dict(type="str"), + advertiseViaOspfEnabled=dict(type="bool"), + preferOverOspfRoutesEnabled=dict(type="bool"), + networkId=dict(type="str"), + switchStackId=dict(type="str"), + staticRouteId=dict(type="str"), +)) + +required_if = [ + ("state", "present", ["name", "networkId", "staticRouteId", "switchStackId"], True), + ("state", "absent", ["name", "networkId", "staticRouteId", "switchStackId"], True), +] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class NetworksSwitchStacksRoutingStaticRoutes(object): + def __init__(self, params, meraki): + self.meraki = meraki + self.new_object = dict( + name=params.get("name"), + subnet=params.get("subnet"), + nextHopIp=params.get("nextHopIp"), + advertiseViaOspfEnabled=params.get("advertiseViaOspfEnabled"), + preferOverOspfRoutesEnabled=params.get("preferOverOspfRoutesEnabled"), + networkId=params.get("networkId"), + switchStackId=params.get("switchStackId"), + staticRouteId=params.get("staticRouteId"), + ) + + def get_all_params(self, name=None, id=None): + new_object_params = {} + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + if self.new_object.get('switchStackId') is not None or self.new_object.get('switch_stack_id') is not None: + new_object_params['switchStackId'] = self.new_object.get('switchStackId') or \ + self.new_object.get('switch_stack_id') + return new_object_params + + def get_params_by_id(self, name=None, id=None): + new_object_params = {} + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + if self.new_object.get('switchStackId') is not None or self.new_object.get('switch_stack_id') is not None: + new_object_params['switchStackId'] = self.new_object.get('switchStackId') or \ + self.new_object.get('switch_stack_id') + if self.new_object.get('staticRouteId') is not None or self.new_object.get('static_route_id') is not None: + new_object_params['staticRouteId'] = self.new_object.get('staticRouteId') or \ + self.new_object.get('static_route_id') + return new_object_params + + def create_params(self): + new_object_params = {} + if self.new_object.get('name') is not None or self.new_object.get('name') is not None: + new_object_params['name'] = self.new_object.get('name') or \ + self.new_object.get('name') + if self.new_object.get('subnet') is not None or self.new_object.get('subnet') is not None: + new_object_params['subnet'] = self.new_object.get('subnet') or \ + self.new_object.get('subnet') + if self.new_object.get('nextHopIp') is not None or self.new_object.get('next_hop_ip') is not None: + new_object_params['nextHopIp'] = self.new_object.get('nextHopIp') or \ + self.new_object.get('next_hop_ip') + if self.new_object.get('advertiseViaOspfEnabled') is not None or self.new_object.get('advertise_via_ospf_enabled') is not None: + new_object_params['advertiseViaOspfEnabled'] = self.new_object.get('advertiseViaOspfEnabled') + if self.new_object.get('preferOverOspfRoutesEnabled') is not None or self.new_object.get('prefer_over_ospf_routes_enabled') is not None: + new_object_params['preferOverOspfRoutesEnabled'] = self.new_object.get('preferOverOspfRoutesEnabled') + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + if self.new_object.get('switchStackId') is not None or self.new_object.get('switch_stack_id') is not None: + new_object_params['switchStackId'] = self.new_object.get('switchStackId') or \ + self.new_object.get('switch_stack_id') + return new_object_params + + def delete_by_id_params(self): + new_object_params = {} + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + if self.new_object.get('switchStackId') is not None or self.new_object.get('switch_stack_id') is not None: + new_object_params['switchStackId'] = self.new_object.get('switchStackId') or \ + self.new_object.get('switch_stack_id') + if self.new_object.get('staticRouteId') is not None or self.new_object.get('static_route_id') is not None: + new_object_params['staticRouteId'] = self.new_object.get('staticRouteId') or \ + self.new_object.get('static_route_id') + return new_object_params + + def update_by_id_params(self): + new_object_params = {} + if self.new_object.get('name') is not None or self.new_object.get('name') is not None: + new_object_params['name'] = self.new_object.get('name') or \ + self.new_object.get('name') + if self.new_object.get('subnet') is not None or self.new_object.get('subnet') is not None: + new_object_params['subnet'] = self.new_object.get('subnet') or \ + self.new_object.get('subnet') + if self.new_object.get('nextHopIp') is not None or self.new_object.get('next_hop_ip') is not None: + new_object_params['nextHopIp'] = self.new_object.get('nextHopIp') or \ + self.new_object.get('next_hop_ip') + if self.new_object.get('advertiseViaOspfEnabled') is not None or self.new_object.get('advertise_via_ospf_enabled') is not None: + new_object_params['advertiseViaOspfEnabled'] = self.new_object.get('advertiseViaOspfEnabled') + if self.new_object.get('preferOverOspfRoutesEnabled') is not None or self.new_object.get('prefer_over_ospf_routes_enabled') is not None: + new_object_params['preferOverOspfRoutesEnabled'] = self.new_object.get('preferOverOspfRoutesEnabled') + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + if self.new_object.get('switchStackId') is not None or self.new_object.get('switch_stack_id') is not None: + new_object_params['switchStackId'] = self.new_object.get('switchStackId') or \ + self.new_object.get('switch_stack_id') + if self.new_object.get('staticRouteId') is not None or self.new_object.get('static_route_id') is not None: + new_object_params['staticRouteId'] = self.new_object.get('staticRouteId') or \ + self.new_object.get('static_route_id') + return new_object_params + + def get_object_by_name(self, name): + result = None + # NOTE: Does not have a get by name method or it is in another action + try: + items = self.meraki.exec_meraki( + family="switch", + function="getNetworkSwitchStackRoutingStaticRoutes", + params=self.get_all_params(name=name), + ) + if isinstance(items, dict): + if 'response' in items: + items = items.get('response') + result = get_dict_result(items, 'name', name) + if result is None: + result = items + except Exception as e: + print("Error: ", e) + result = None + return result + + def get_object_by_id(self, id): + result = None + try: + items = self.meraki.exec_meraki( + family="switch", + function="getNetworkSwitchStackRoutingStaticRoute", + params=self.get_params_by_id() + ) + if isinstance(items, dict): + if 'response' in items: + items = items.get('response') + result = get_dict_result(items, 'staticRouteId', id) + except Exception as e: + print("Error: ", e) + result = None + return result + + def exists(self): + id_exists = False + name_exists = False + prev_obj = None + o_id = self.new_object.get("id") + o_id = o_id or self.new_object.get( + "static_route_id") or self.new_object.get("staticRouteId") + name = self.new_object.get("name") + if o_id: + prev_obj = self.get_object_by_id(o_id) + id_exists = prev_obj is not None and isinstance(prev_obj, dict) + if not id_exists and name: + prev_obj = self.get_object_by_name(name) + name_exists = prev_obj is not None and isinstance(prev_obj, dict) + if name_exists: + _id = prev_obj.get("id") + _id = _id or prev_obj.get("staticRouteId") + if id_exists and name_exists and o_id != _id: + raise InconsistentParameters( + "The 'id' and 'name' params don't refer to the same object") + if _id: + self.new_object.update(dict(id=_id)) + self.new_object.update(dict(staticRouteId=_id)) + if _id: + prev_obj = self.get_object_by_id(_id) + it_exists = prev_obj is not None and isinstance(prev_obj, dict) + return (it_exists, prev_obj) + + def requires_update(self, current_obj): + requested_obj = self.new_object + + obj_params = [ + ("name", "name"), + ("subnet", "subnet"), + ("nextHopIp", "nextHopIp"), + ("advertiseViaOspfEnabled", "advertiseViaOspfEnabled"), + ("preferOverOspfRoutesEnabled", "preferOverOspfRoutesEnabled"), + ("networkId", "networkId"), + ("switchStackId", "switchStackId"), + ("staticRouteId", "staticRouteId"), + ] + # Method 1. Params present in request (Ansible) obj are the same as the current (DNAC) params + # If any does not have eq params, it requires update + return any(not meraki_compare_equality(current_obj.get(meraki_param), + requested_obj.get(ansible_param)) + for (meraki_param, ansible_param) in obj_params) + + def create(self): + result = self.meraki.exec_meraki( + family="switch", + function="createNetworkSwitchStackRoutingStaticRoute", + params=self.create_params(), + op_modifies=True, + ) + return result + + def update(self): + id = self.new_object.get("id") + id = id or self.new_object.get("staticRouteId") + name = self.new_object.get("name") + result = None + if not id: + prev_obj_name = self.get_object_by_name(name) + id_ = None + if prev_obj_name: + id_ = prev_obj_name.get("id") + id_ = id_ or prev_obj_name.get("staticRouteId") + if id_: + self.new_object.update(dict(staticRouteId=id_)) + result = self.meraki.exec_meraki( + family="switch", + function="updateNetworkSwitchStackRoutingStaticRoute", + params=self.update_by_id_params(), + op_modifies=True, + ) + return result + + def delete(self): + id = self.new_object.get("id") + id = id or self.new_object.get("staticRouteId") + name = self.new_object.get("name") + result = None + if not id: + prev_obj_name = self.get_object_by_name(name) + id_ = None + if prev_obj_name: + id_ = prev_obj_name.get("id") + id_ = id_ or prev_obj_name.get("staticRouteId") + if id_: + self.new_object.update(dict(staticRouteId=id_)) + result = self.meraki.exec_meraki( + family="switch", + function="deleteNetworkSwitchStackRoutingStaticRoute", + params=self.delete_by_id_params(), + ) + return result + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = False + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + meraki = MERAKI(self._task.args) + obj = NetworksSwitchStacksRoutingStaticRoutes(self._task.args, meraki) + + state = self._task.args.get("state") + + response = None + + if state == "present": + (obj_exists, prev_obj) = obj.exists() + if obj_exists: + if obj.requires_update(prev_obj): + response = obj.update() + meraki.object_updated() + else: + response = prev_obj + meraki.object_already_present() + else: + response = obj.create() + meraki.object_created() + + elif state == "absent": + (obj_exists, prev_obj) = obj.exists() + if obj_exists: + response = obj.delete() + meraki.object_deleted() + else: + meraki.object_already_absent() + + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_switch_stacks_routing_static_routes_info.py b/ansible_collections/cisco/meraki/plugins/action/networks_switch_stacks_routing_static_routes_info.py new file mode 100644 index 000000000..4ec718a7e --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_switch_stacks_routing_static_routes_info.py @@ -0,0 +1,119 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + networkId=dict(type="str"), + switchStackId=dict(type="str"), + staticRouteId=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_object(self, params): + new_object = {} + if params.get("networkId") is not None: + new_object["networkId"] = params.get( + "networkId") + if params.get("switchStackId") is not None: + new_object["switchStackId"] = params.get( + "switchStackId") + if params.get("staticRouteId") is not None: + new_object["staticRouteId"] = params.get( + "staticRouteId") + return new_object + + def get_all(self, params): + new_object = {} + if params.get("networkId") is not None: + new_object["networkId"] = params.get( + "networkId") + if params.get("switchStackId") is not None: + new_object["switchStackId"] = params.get( + "switchStackId") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + id = self._task.args.get("staticRouteId") + if id: + response = meraki.exec_meraki( + family="switch", + function='getNetworkSwitchStackRoutingStaticRoute', + params=self.get_object(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result + if not id: + response = meraki.exec_meraki( + family="switch", + function='getNetworkSwitchStackRoutingStaticRoutes', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_switch_storm_control.py b/ansible_collections/cisco/meraki/plugins/action/networks_switch_storm_control.py new file mode 100644 index 000000000..1ad3d8008 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_switch_storm_control.py @@ -0,0 +1,212 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or +# https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, + meraki_compare_equality, + get_dict_result, +) +from ansible_collections.cisco.meraki.plugins.plugin_utils.exceptions import ( + InconsistentParameters, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + state=dict(type="str", default="present", choices=["present"]), + broadcastThreshold=dict(type="int"), + multicastThreshold=dict(type="int"), + unknownUnicastThreshold=dict(type="int"), + networkId=dict(type="str"), +)) + +required_if = [ + ("state", "present", ["networkId"], True), +] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class NetworksSwitchStormControl(object): + def __init__(self, params, meraki): + self.meraki = meraki + self.new_object = dict( + broadcastThreshold=params.get("broadcastThreshold"), + multicastThreshold=params.get("multicastThreshold"), + unknownUnicastThreshold=params.get("unknownUnicastThreshold"), + network_id=params.get("networkId"), + ) + + def get_all_params(self, name=None, id=None): + new_object_params = {} + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + return new_object_params + + def update_all_params(self): + new_object_params = {} + if self.new_object.get('broadcastThreshold') is not None or self.new_object.get('broadcast_threshold') is not None: + new_object_params['broadcastThreshold'] = self.new_object.get('broadcastThreshold') or \ + self.new_object.get('broadcast_threshold') + if self.new_object.get('multicastThreshold') is not None or self.new_object.get('multicast_threshold') is not None: + new_object_params['multicastThreshold'] = self.new_object.get('multicastThreshold') or \ + self.new_object.get('multicast_threshold') + if self.new_object.get('unknownUnicastThreshold') is not None or self.new_object.get('unknown_unicast_threshold') is not None: + new_object_params['unknownUnicastThreshold'] = self.new_object.get('unknownUnicastThreshold') or \ + self.new_object.get('unknown_unicast_threshold') + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + return new_object_params + + def get_object_by_name(self, name): + result = None + # NOTE: Does not have a get by name method, using get all + try: + items = self.meraki.exec_meraki( + family="switch", + function="getNetworkSwitchStormControl", + params=self.get_all_params(name=name), + ) + if isinstance(items, dict): + if 'response' in items: + items = items.get('response') + result = get_dict_result(items, 'name', name) + if result is None: + result = items + except Exception as e: + print("Error: ", e) + result = None + return result + + def get_object_by_id(self, id): + result = None + # NOTE: Does not have a get by id method or it is in another action + return result + + def exists(self): + prev_obj = None + id_exists = False + name_exists = False + o_id = self.new_object.get("networkId") or self.new_object.get("network_id") + name = self.new_object.get("name") + if o_id: + prev_obj = self.get_object_by_name(o_id) + id_exists = prev_obj is not None and isinstance(prev_obj, dict) + if not id_exists and name: + prev_obj = self.get_object_by_name(name) + name_exists = prev_obj is not None and isinstance(prev_obj, dict) + if name_exists: + _id = prev_obj.get("id") + if id_exists and name_exists and o_id != _id: + raise InconsistentParameters( + "The 'id' and 'name' params don't refer to the same object") + if _id: + self.new_object.update(dict(id=_id)) + it_exists = prev_obj is not None and isinstance(prev_obj, dict) + return (it_exists, prev_obj) + + def requires_update(self, current_obj): + requested_obj = self.new_object + + obj_params = [ + ("broadcastThreshold", "broadcastThreshold"), + ("multicastThreshold", "multicastThreshold"), + ("unknownUnicastThreshold", "unknownUnicastThreshold"), + ("networkId", "networkId"), + ] + # Method 1. Params present in request (Ansible) obj are the same as the current (ISE) params + # If any does not have eq params, it requires update + return any(not meraki_compare_equality(current_obj.get(meraki_param), + requested_obj.get(ansible_param)) + for (meraki_param, ansible_param) in obj_params) + + def update(self): + id = self.new_object.get("id") + name = self.new_object.get("name") + result = None + result = self.meraki.exec_meraki( + family="switch", + function="updateNetworkSwitchStormControl", + params=self.update_all_params(), + op_modifies=True, + ) + return result + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = False + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + meraki = MERAKI(self._task.args) + obj = NetworksSwitchStormControl(self._task.args, meraki) + + state = self._task.args.get("state") + + response = None + if state == "present": + (obj_exists, prev_obj) = obj.exists() + if obj_exists: + if obj.requires_update(prev_obj): + response = obj.update() + meraki.object_updated() + else: + response = prev_obj + meraki.object_already_present() + else: + meraki.fail_json( + "Object does not exists, plugin only has update") + + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_switch_storm_control_info.py b/ansible_collections/cisco/meraki/plugins/action/networks_switch_storm_control_info.py new file mode 100644 index 000000000..76ab48aab --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_switch_storm_control_info.py @@ -0,0 +1,90 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + networkId=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_all(self, params): + new_object = {} + if params.get("networkId") is not None: + new_object["networkId"] = params.get( + "networkId") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="switch", + function='getNetworkSwitchStormControl', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_switch_stp.py b/ansible_collections/cisco/meraki/plugins/action/networks_switch_stp.py new file mode 100644 index 000000000..a64fce1cc --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_switch_stp.py @@ -0,0 +1,205 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or +# https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, + meraki_compare_equality, + get_dict_result, +) +from ansible_collections.cisco.meraki.plugins.plugin_utils.exceptions import ( + InconsistentParameters, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + state=dict(type="str", default="present", choices=["present"]), + rstpEnabled=dict(type="bool"), + stpBridgePriority=dict(type="list"), + networkId=dict(type="str"), +)) + +required_if = [ + ("state", "present", ["networkId"], True), +] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class NetworksSwitchStp(object): + def __init__(self, params, meraki): + self.meraki = meraki + self.new_object = dict( + rstpEnabled=params.get("rstpEnabled"), + stpBridgePriority=params.get("stpBridgePriority"), + network_id=params.get("networkId"), + ) + + def get_all_params(self, name=None, id=None): + new_object_params = {} + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + return new_object_params + + def update_all_params(self): + new_object_params = {} + if self.new_object.get('rstpEnabled') is not None or self.new_object.get('rstp_enabled') is not None: + new_object_params['rstpEnabled'] = self.new_object.get('rstpEnabled') + if self.new_object.get('stpBridgePriority') is not None or self.new_object.get('stp_bridge_priority') is not None: + new_object_params['stpBridgePriority'] = self.new_object.get('stpBridgePriority') or \ + self.new_object.get('stp_bridge_priority') + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + return new_object_params + + def get_object_by_name(self, name): + result = None + # NOTE: Does not have a get by name method, using get all + try: + items = self.meraki.exec_meraki( + family="switch", + function="getNetworkSwitchStp", + params=self.get_all_params(name=name), + ) + if isinstance(items, dict): + if 'response' in items: + items = items.get('response') + result = get_dict_result(items, 'name', name) + if result is None: + result = items + except Exception as e: + print("Error: ", e) + result = None + return result + + def get_object_by_id(self, id): + result = None + # NOTE: Does not have a get by id method or it is in another action + return result + + def exists(self): + prev_obj = None + id_exists = False + name_exists = False + o_id = self.new_object.get("networkId") or self.new_object.get("network_id") + name = self.new_object.get("name") + if o_id: + prev_obj = self.get_object_by_name(o_id) + id_exists = prev_obj is not None and isinstance(prev_obj, dict) + if not id_exists and name: + prev_obj = self.get_object_by_name(name) + name_exists = prev_obj is not None and isinstance(prev_obj, dict) + if name_exists: + _id = prev_obj.get("id") + if id_exists and name_exists and o_id != _id: + raise InconsistentParameters( + "The 'id' and 'name' params don't refer to the same object") + if _id: + self.new_object.update(dict(id=_id)) + it_exists = prev_obj is not None and isinstance(prev_obj, dict) + return (it_exists, prev_obj) + + def requires_update(self, current_obj): + requested_obj = self.new_object + + obj_params = [ + ("rstpEnabled", "rstpEnabled"), + ("stpBridgePriority", "stpBridgePriority"), + ("networkId", "networkId"), + ] + # Method 1. Params present in request (Ansible) obj are the same as the current (ISE) params + # If any does not have eq params, it requires update + return any(not meraki_compare_equality(current_obj.get(meraki_param), + requested_obj.get(ansible_param)) + for (meraki_param, ansible_param) in obj_params) + + def update(self): + id = self.new_object.get("id") + name = self.new_object.get("name") + result = None + result = self.meraki.exec_meraki( + family="switch", + function="updateNetworkSwitchStp", + params=self.update_all_params(), + op_modifies=True, + ) + return result + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = False + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + meraki = MERAKI(self._task.args) + obj = NetworksSwitchStp(self._task.args, meraki) + + state = self._task.args.get("state") + + response = None + if state == "present": + (obj_exists, prev_obj) = obj.exists() + if obj_exists: + if obj.requires_update(prev_obj): + response = obj.update() + meraki.object_updated() + else: + response = prev_obj + meraki.object_already_present() + else: + meraki.fail_json( + "Object does not exists, plugin only has update") + + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_switch_stp_info.py b/ansible_collections/cisco/meraki/plugins/action/networks_switch_stp_info.py new file mode 100644 index 000000000..591592ea0 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_switch_stp_info.py @@ -0,0 +1,90 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + networkId=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_all(self, params): + new_object = {} + if params.get("networkId") is not None: + new_object["networkId"] = params.get( + "networkId") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="switch", + function='getNetworkSwitchStp', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_syslog_servers.py b/ansible_collections/cisco/meraki/plugins/action/networks_syslog_servers.py new file mode 100644 index 000000000..3a8064aff --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_syslog_servers.py @@ -0,0 +1,89 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguements specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + servers=dict(type="list"), + networkId=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = False + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_object(self, params): + new_object = dict( + servers=params.get("servers"), + networkId=params.get("networkId"), + ) + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="networks", + function='updateNetworkSyslogServers', + op_modifies=True, + params=self.get_object(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_syslog_servers_info.py b/ansible_collections/cisco/meraki/plugins/action/networks_syslog_servers_info.py new file mode 100644 index 000000000..7b0439428 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_syslog_servers_info.py @@ -0,0 +1,90 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + networkId=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_all(self, params): + new_object = {} + if params.get("networkId") is not None: + new_object["networkId"] = params.get( + "networkId") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="networks", + function='getNetworkSyslogServers', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_topology_link_layer_info.py b/ansible_collections/cisco/meraki/plugins/action/networks_topology_link_layer_info.py new file mode 100644 index 000000000..292373e28 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_topology_link_layer_info.py @@ -0,0 +1,90 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + networkId=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_all(self, params): + new_object = {} + if params.get("networkId") is not None: + new_object["networkId"] = params.get( + "networkId") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="networks", + function='getNetworkTopologyLinkLayer', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_traffic_analysis.py b/ansible_collections/cisco/meraki/plugins/action/networks_traffic_analysis.py new file mode 100644 index 000000000..eb815e34c --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_traffic_analysis.py @@ -0,0 +1,206 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or +# https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, + meraki_compare_equality, + get_dict_result, +) +from ansible_collections.cisco.meraki.plugins.plugin_utils.exceptions import ( + InconsistentParameters, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + state=dict(type="str", default="present", choices=["present"]), + mode=dict(type="str"), + customPieChartItems=dict(type="list"), + networkId=dict(type="str"), +)) + +required_if = [ + ("state", "present", ["networkId"], True), +] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class NetworksTrafficAnalysis(object): + def __init__(self, params, meraki): + self.meraki = meraki + self.new_object = dict( + mode=params.get("mode"), + customPieChartItems=params.get("customPieChartItems"), + network_id=params.get("networkId"), + ) + + def get_all_params(self, name=None, id=None): + new_object_params = {} + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + return new_object_params + + def update_all_params(self): + new_object_params = {} + if self.new_object.get('mode') is not None or self.new_object.get('mode') is not None: + new_object_params['mode'] = self.new_object.get('mode') or \ + self.new_object.get('mode') + if self.new_object.get('customPieChartItems') is not None or self.new_object.get('custom_pie_chart_items') is not None: + new_object_params['customPieChartItems'] = self.new_object.get('customPieChartItems') or \ + self.new_object.get('custom_pie_chart_items') + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + return new_object_params + + def get_object_by_name(self, name): + result = None + # NOTE: Does not have a get by name method, using get all + try: + items = self.meraki.exec_meraki( + family="networks", + function="getNetworkTrafficAnalysis", + params=self.get_all_params(name=name), + ) + if isinstance(items, dict): + if 'response' in items: + items = items.get('response') + result = get_dict_result(items, 'name', name) + if result is None: + result = items + except Exception as e: + print("Error: ", e) + result = None + return result + + def get_object_by_id(self, id): + result = None + # NOTE: Does not have a get by id method or it is in another action + return result + + def exists(self): + prev_obj = None + id_exists = False + name_exists = False + o_id = self.new_object.get("networkId") or self.new_object.get("network_id") + name = self.new_object.get("name") + if o_id: + prev_obj = self.get_object_by_name(o_id) + id_exists = prev_obj is not None and isinstance(prev_obj, dict) + if not id_exists and name: + prev_obj = self.get_object_by_name(name) + name_exists = prev_obj is not None and isinstance(prev_obj, dict) + if name_exists: + _id = prev_obj.get("id") + if id_exists and name_exists and o_id != _id: + raise InconsistentParameters( + "The 'id' and 'name' params don't refer to the same object") + if _id: + self.new_object.update(dict(id=_id)) + it_exists = prev_obj is not None and isinstance(prev_obj, dict) + return (it_exists, prev_obj) + + def requires_update(self, current_obj): + requested_obj = self.new_object + + obj_params = [ + ("mode", "mode"), + ("customPieChartItems", "customPieChartItems"), + ("networkId", "networkId"), + ] + # Method 1. Params present in request (Ansible) obj are the same as the current (ISE) params + # If any does not have eq params, it requires update + return any(not meraki_compare_equality(current_obj.get(meraki_param), + requested_obj.get(ansible_param)) + for (meraki_param, ansible_param) in obj_params) + + def update(self): + id = self.new_object.get("id") + name = self.new_object.get("name") + result = None + result = self.meraki.exec_meraki( + family="networks", + function="updateNetworkTrafficAnalysis", + params=self.update_all_params(), + op_modifies=True, + ) + return result + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = False + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + meraki = MERAKI(self._task.args) + obj = NetworksTrafficAnalysis(self._task.args, meraki) + + state = self._task.args.get("state") + + response = None + if state == "present": + (obj_exists, prev_obj) = obj.exists() + if obj_exists: + if obj.requires_update(prev_obj): + response = obj.update() + meraki.object_updated() + else: + response = prev_obj + meraki.object_already_present() + else: + meraki.fail_json( + "Object does not exists, plugin only has update") + + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_traffic_analysis_info.py b/ansible_collections/cisco/meraki/plugins/action/networks_traffic_analysis_info.py new file mode 100644 index 000000000..26554e03b --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_traffic_analysis_info.py @@ -0,0 +1,90 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + networkId=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_all(self, params): + new_object = {} + if params.get("networkId") is not None: + new_object["networkId"] = params.get( + "networkId") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="networks", + function='getNetworkTrafficAnalysis', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_traffic_shaping_application_categories_info.py b/ansible_collections/cisco/meraki/plugins/action/networks_traffic_shaping_application_categories_info.py new file mode 100644 index 000000000..72ec87b72 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_traffic_shaping_application_categories_info.py @@ -0,0 +1,90 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + networkId=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_all(self, params): + new_object = {} + if params.get("networkId") is not None: + new_object["networkId"] = params.get( + "networkId") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="networks", + function='getNetworkTrafficShapingApplicationCategories', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_traffic_shaping_dscp_tagging_options_info.py b/ansible_collections/cisco/meraki/plugins/action/networks_traffic_shaping_dscp_tagging_options_info.py new file mode 100644 index 000000000..9b87a1765 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_traffic_shaping_dscp_tagging_options_info.py @@ -0,0 +1,90 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + networkId=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_all(self, params): + new_object = {} + if params.get("networkId") is not None: + new_object["networkId"] = params.get( + "networkId") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="networks", + function='getNetworkTrafficShapingDscpTaggingOptions', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_unbind.py b/ansible_collections/cisco/meraki/plugins/action/networks_unbind.py new file mode 100644 index 000000000..bb840e577 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_unbind.py @@ -0,0 +1,89 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguements specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + retainConfigs=dict(type="bool"), + networkId=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = False + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_object(self, params): + new_object = dict( + retainConfigs=params.get("retainConfigs"), + networkId=params.get("networkId"), + ) + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="networks", + function='unbindNetwork', + op_modifies=True, + params=self.get_object(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_webhooks_http_servers.py b/ansible_collections/cisco/meraki/plugins/action/networks_webhooks_http_servers.py new file mode 100644 index 000000000..ef9a6d29d --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_webhooks_http_servers.py @@ -0,0 +1,326 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or +# https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, + meraki_compare_equality, + get_dict_result, +) +from ansible_collections.cisco.meraki.plugins.plugin_utils.exceptions import ( + InconsistentParameters, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + state=dict(type="str", default="present", choices=["present", "absent"]), + name=dict(type="str"), + url=dict(type="str"), + sharedSecret=dict(type="str"), + payloadTemplate=dict(type="dict"), + networkId=dict(type="str"), + httpServerId=dict(type="str"), +)) + +required_if = [ + ("state", "present", ["httpServerId", "name", "networkId"], True), + ("state", "absent", ["httpServerId", "name", "networkId"], True), +] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class NetworksWebhooksHttpServers(object): + def __init__(self, params, meraki): + self.meraki = meraki + self.new_object = dict( + name=params.get("name"), + url=params.get("url"), + sharedSecret=params.get("sharedSecret"), + payloadTemplate=params.get("payloadTemplate"), + networkId=params.get("networkId"), + httpServerId=params.get("httpServerId"), + ) + + def get_all_params(self, name=None, id=None): + new_object_params = {} + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + return new_object_params + + def get_params_by_id(self, name=None, id=None): + new_object_params = {} + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + if self.new_object.get('httpServerId') is not None or self.new_object.get('http_server_id') is not None: + new_object_params['httpServerId'] = self.new_object.get('httpServerId') or \ + self.new_object.get('http_server_id') + return new_object_params + + def create_params(self): + new_object_params = {} + if self.new_object.get('name') is not None or self.new_object.get('name') is not None: + new_object_params['name'] = self.new_object.get('name') or \ + self.new_object.get('name') + if self.new_object.get('url') is not None or self.new_object.get('url') is not None: + new_object_params['url'] = self.new_object.get('url') or \ + self.new_object.get('url') + if self.new_object.get('sharedSecret') is not None or self.new_object.get('shared_secret') is not None: + new_object_params['sharedSecret'] = self.new_object.get('sharedSecret') or \ + self.new_object.get('shared_secret') + if self.new_object.get('payloadTemplate') is not None or self.new_object.get('payload_template') is not None: + new_object_params['payloadTemplate'] = self.new_object.get('payloadTemplate') or \ + self.new_object.get('payload_template') + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + return new_object_params + + def delete_by_id_params(self): + new_object_params = {} + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + if self.new_object.get('httpServerId') is not None or self.new_object.get('http_server_id') is not None: + new_object_params['httpServerId'] = self.new_object.get('httpServerId') or \ + self.new_object.get('http_server_id') + return new_object_params + + def update_by_id_params(self): + new_object_params = {} + if self.new_object.get('name') is not None or self.new_object.get('name') is not None: + new_object_params['name'] = self.new_object.get('name') or \ + self.new_object.get('name') + if self.new_object.get('sharedSecret') is not None or self.new_object.get('shared_secret') is not None: + new_object_params['sharedSecret'] = self.new_object.get('sharedSecret') or \ + self.new_object.get('shared_secret') + if self.new_object.get('payloadTemplate') is not None or self.new_object.get('payload_template') is not None: + new_object_params['payloadTemplate'] = self.new_object.get('payloadTemplate') or \ + self.new_object.get('payload_template') + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + if self.new_object.get('httpServerId') is not None or self.new_object.get('http_server_id') is not None: + new_object_params['httpServerId'] = self.new_object.get('httpServerId') or \ + self.new_object.get('http_server_id') + return new_object_params + + def get_object_by_name(self, name): + result = None + # NOTE: Does not have a get by name method or it is in another action + try: + items = self.meraki.exec_meraki( + family="networks", + function="getNetworkWebhooksHttpServers", + params=self.get_all_params(name=name), + ) + if isinstance(items, dict): + if 'response' in items: + items = items.get('response') + result = get_dict_result(items, 'name', name) + if result is None: + result = items + except Exception as e: + print("Error: ", e) + result = None + return result + + def get_object_by_id(self, id): + result = None + try: + items = self.meraki.exec_meraki( + family="networks", + function="getNetworkWebhooksHttpServer", + params=self.get_params_by_id() + ) + if isinstance(items, dict): + if 'response' in items: + items = items.get('response') + result = get_dict_result(items, 'httpServerId', id) + except Exception as e: + print("Error: ", e) + result = None + return result + + def exists(self): + id_exists = False + name_exists = False + prev_obj = None + o_id = self.new_object.get("id") + o_id = o_id or self.new_object.get( + "http_server_id") or self.new_object.get("httpServerId") + name = self.new_object.get("name") + if o_id: + prev_obj = self.get_object_by_id(o_id) + id_exists = prev_obj is not None and isinstance(prev_obj, dict) + if not id_exists and name: + prev_obj = self.get_object_by_name(name) + name_exists = prev_obj is not None and isinstance(prev_obj, dict) + if name_exists: + _id = prev_obj.get("id") + _id = _id or prev_obj.get("httpServerId") + if id_exists and name_exists and o_id != _id: + raise InconsistentParameters( + "The 'id' and 'name' params don't refer to the same object") + if _id: + self.new_object.update(dict(id=_id)) + self.new_object.update(dict(httpServerId=_id)) + if _id: + prev_obj = self.get_object_by_id(_id) + it_exists = prev_obj is not None and isinstance(prev_obj, dict) + return (it_exists, prev_obj) + + def requires_update(self, current_obj): + requested_obj = self.new_object + + obj_params = [ + ("name", "name"), + ("url", "url"), + ("sharedSecret", "sharedSecret"), + ("payloadTemplate", "payloadTemplate"), + ("networkId", "networkId"), + ("httpServerId", "httpServerId"), + ] + # Method 1. Params present in request (Ansible) obj are the same as the current (DNAC) params + # If any does not have eq params, it requires update + return any(not meraki_compare_equality(current_obj.get(meraki_param), + requested_obj.get(ansible_param)) + for (meraki_param, ansible_param) in obj_params) + + def create(self): + result = self.meraki.exec_meraki( + family="networks", + function="createNetworkWebhooksHttpServer", + params=self.create_params(), + op_modifies=True, + ) + return result + + def update(self): + id = self.new_object.get("id") + id = id or self.new_object.get("httpServerId") + name = self.new_object.get("name") + result = None + if not id: + prev_obj_name = self.get_object_by_name(name) + id_ = None + if prev_obj_name: + id_ = prev_obj_name.get("id") + id_ = id_ or prev_obj_name.get("httpServerId") + if id_: + self.new_object.update(dict(httpServerId=id_)) + result = self.meraki.exec_meraki( + family="networks", + function="updateNetworkWebhooksHttpServer", + params=self.update_by_id_params(), + op_modifies=True, + ) + return result + + def delete(self): + id = self.new_object.get("id") + id = id or self.new_object.get("httpServerId") + name = self.new_object.get("name") + result = None + if not id: + prev_obj_name = self.get_object_by_name(name) + id_ = None + if prev_obj_name: + id_ = prev_obj_name.get("id") + id_ = id_ or prev_obj_name.get("httpServerId") + if id_: + self.new_object.update(dict(httpServerId=id_)) + result = self.meraki.exec_meraki( + family="networks", + function="deleteNetworkWebhooksHttpServer", + params=self.delete_by_id_params(), + ) + return result + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = False + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + meraki = MERAKI(self._task.args) + obj = NetworksWebhooksHttpServers(self._task.args, meraki) + + state = self._task.args.get("state") + + response = None + + if state == "present": + (obj_exists, prev_obj) = obj.exists() + if obj_exists: + if obj.requires_update(prev_obj): + response = obj.update() + meraki.object_updated() + else: + response = prev_obj + meraki.object_already_present() + else: + response = obj.create() + meraki.object_created() + + elif state == "absent": + (obj_exists, prev_obj) = obj.exists() + if obj_exists: + response = obj.delete() + meraki.object_deleted() + else: + meraki.object_already_absent() + + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_webhooks_http_servers_info.py b/ansible_collections/cisco/meraki/plugins/action/networks_webhooks_http_servers_info.py new file mode 100644 index 000000000..4c37c1f74 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_webhooks_http_servers_info.py @@ -0,0 +1,112 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + networkId=dict(type="str"), + httpServerId=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_object(self, params): + new_object = {} + if params.get("networkId") is not None: + new_object["networkId"] = params.get( + "networkId") + if params.get("httpServerId") is not None: + new_object["httpServerId"] = params.get( + "httpServerId") + return new_object + + def get_all(self, params): + new_object = {} + if params.get("networkId") is not None: + new_object["networkId"] = params.get( + "networkId") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + id = self._task.args.get("httpServerId") + if id: + response = meraki.exec_meraki( + family="networks", + function='getNetworkWebhooksHttpServer', + params=self.get_object(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result + if not id: + response = meraki.exec_meraki( + family="networks", + function='getNetworkWebhooksHttpServers', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_webhooks_payload_templates.py b/ansible_collections/cisco/meraki/plugins/action/networks_webhooks_payload_templates.py new file mode 100644 index 000000000..335a112bc --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_webhooks_payload_templates.py @@ -0,0 +1,338 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or +# https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, + meraki_compare_equality, + get_dict_result, +) +from ansible_collections.cisco.meraki.plugins.plugin_utils.exceptions import ( + InconsistentParameters, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + state=dict(type="str", default="present", choices=["present", "absent"]), + name=dict(type="str"), + body=dict(type="str"), + headers=dict(type="list"), + bodyFile=dict(type="str"), + headersFile=dict(type="str"), + networkId=dict(type="str"), + payloadTemplateId=dict(type="str"), +)) + +required_if = [ + ("state", "present", ["name", "networkId", "payloadTemplateId"], True), + ("state", "absent", ["name", "networkId", "payloadTemplateId"], True), +] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class NetworksWebhooksPayloadTemplates(object): + def __init__(self, params, meraki): + self.meraki = meraki + self.new_object = dict( + name=params.get("name"), + body=params.get("body"), + headers=params.get("headers"), + bodyFile=params.get("bodyFile"), + headersFile=params.get("headersFile"), + networkId=params.get("networkId"), + payloadTemplateId=params.get("payloadTemplateId"), + ) + + def get_all_params(self, name=None, id=None): + new_object_params = {} + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + return new_object_params + + def get_params_by_id(self, name=None, id=None): + new_object_params = {} + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + if self.new_object.get('payloadTemplateId') is not None or self.new_object.get('payload_template_id') is not None: + new_object_params['payloadTemplateId'] = self.new_object.get('payloadTemplateId') or \ + self.new_object.get('payload_template_id') + return new_object_params + + def create_params(self): + new_object_params = {} + if self.new_object.get('name') is not None or self.new_object.get('name') is not None: + new_object_params['name'] = self.new_object.get('name') or \ + self.new_object.get('name') + if self.new_object.get('body') is not None or self.new_object.get('body') is not None: + new_object_params['body'] = self.new_object.get('body') or \ + self.new_object.get('body') + if self.new_object.get('headers') is not None or self.new_object.get('headers') is not None: + new_object_params['headers'] = self.new_object.get('headers') or \ + self.new_object.get('headers') + if self.new_object.get('bodyFile') is not None or self.new_object.get('body_file') is not None: + new_object_params['bodyFile'] = self.new_object.get('bodyFile') or \ + self.new_object.get('body_file') + if self.new_object.get('headersFile') is not None or self.new_object.get('headers_file') is not None: + new_object_params['headersFile'] = self.new_object.get('headersFile') or \ + self.new_object.get('headers_file') + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + return new_object_params + + def delete_by_id_params(self): + new_object_params = {} + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + if self.new_object.get('payloadTemplateId') is not None or self.new_object.get('payload_template_id') is not None: + new_object_params['payloadTemplateId'] = self.new_object.get('payloadTemplateId') or \ + self.new_object.get('payload_template_id') + return new_object_params + + def update_by_id_params(self): + new_object_params = {} + if self.new_object.get('name') is not None or self.new_object.get('name') is not None: + new_object_params['name'] = self.new_object.get('name') or \ + self.new_object.get('name') + if self.new_object.get('body') is not None or self.new_object.get('body') is not None: + new_object_params['body'] = self.new_object.get('body') or \ + self.new_object.get('body') + if self.new_object.get('headers') is not None or self.new_object.get('headers') is not None: + new_object_params['headers'] = self.new_object.get('headers') or \ + self.new_object.get('headers') + if self.new_object.get('bodyFile') is not None or self.new_object.get('body_file') is not None: + new_object_params['bodyFile'] = self.new_object.get('bodyFile') or \ + self.new_object.get('body_file') + if self.new_object.get('headersFile') is not None or self.new_object.get('headers_file') is not None: + new_object_params['headersFile'] = self.new_object.get('headersFile') or \ + self.new_object.get('headers_file') + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + if self.new_object.get('payloadTemplateId') is not None or self.new_object.get('payload_template_id') is not None: + new_object_params['payloadTemplateId'] = self.new_object.get('payloadTemplateId') or \ + self.new_object.get('payload_template_id') + return new_object_params + + def get_object_by_name(self, name): + result = None + # NOTE: Does not have a get by name method or it is in another action + try: + items = self.meraki.exec_meraki( + family="networks", + function="getNetworkWebhooksPayloadTemplates", + params=self.get_all_params(name=name), + ) + if isinstance(items, dict): + if 'response' in items: + items = items.get('response') + result = get_dict_result(items, 'name', name) + if result is None: + result = items + except Exception as e: + print("Error: ", e) + result = None + return result + + def get_object_by_id(self, id): + result = None + try: + items = self.meraki.exec_meraki( + family="networks", + function="getNetworkWebhooksPayloadTemplate", + params=self.get_params_by_id() + ) + if isinstance(items, dict): + if 'response' in items: + items = items.get('response') + result = get_dict_result(items, 'payloadTemplateId', id) + except Exception as e: + print("Error: ", e) + result = None + return result + + def exists(self): + id_exists = False + name_exists = False + prev_obj = None + o_id = self.new_object.get("id") + o_id = o_id or self.new_object.get( + "payload_template_id") or self.new_object.get("payloadTemplateId") + name = self.new_object.get("name") + if o_id: + prev_obj = self.get_object_by_id(o_id) + id_exists = prev_obj is not None and isinstance(prev_obj, dict) + if not id_exists and name: + prev_obj = self.get_object_by_name(name) + name_exists = prev_obj is not None and isinstance(prev_obj, dict) + if name_exists: + _id = prev_obj.get("id") + _id = _id or prev_obj.get("payloadTemplateId") + if id_exists and name_exists and o_id != _id: + raise InconsistentParameters( + "The 'id' and 'name' params don't refer to the same object") + if _id: + self.new_object.update(dict(id=_id)) + self.new_object.update(dict(payloadTemplateId=_id)) + if _id: + prev_obj = self.get_object_by_id(_id) + it_exists = prev_obj is not None and isinstance(prev_obj, dict) + return (it_exists, prev_obj) + + def requires_update(self, current_obj): + requested_obj = self.new_object + + obj_params = [ + ("name", "name"), + ("body", "body"), + ("headers", "headers"), + ("bodyFile", "bodyFile"), + ("headersFile", "headersFile"), + ("networkId", "networkId"), + ("payloadTemplateId", "payloadTemplateId"), + ] + # Method 1. Params present in request (Ansible) obj are the same as the current (DNAC) params + # If any does not have eq params, it requires update + return any(not meraki_compare_equality(current_obj.get(meraki_param), + requested_obj.get(ansible_param)) + for (meraki_param, ansible_param) in obj_params) + + def create(self): + result = self.meraki.exec_meraki( + family="networks", + function="createNetworkWebhooksPayloadTemplate", + params=self.create_params(), + op_modifies=True, + ) + return result + + def update(self): + id = self.new_object.get("id") + id = id or self.new_object.get("payloadTemplateId") + name = self.new_object.get("name") + result = None + if not id: + prev_obj_name = self.get_object_by_name(name) + id_ = None + if prev_obj_name: + id_ = prev_obj_name.get("id") + id_ = id_ or prev_obj_name.get("payloadTemplateId") + if id_: + self.new_object.update(dict(payloadTemplateId=id_)) + result = self.meraki.exec_meraki( + family="networks", + function="updateNetworkWebhooksPayloadTemplate", + params=self.update_by_id_params(), + op_modifies=True, + ) + return result + + def delete(self): + id = self.new_object.get("id") + id = id or self.new_object.get("payloadTemplateId") + name = self.new_object.get("name") + result = None + if not id: + prev_obj_name = self.get_object_by_name(name) + id_ = None + if prev_obj_name: + id_ = prev_obj_name.get("id") + id_ = id_ or prev_obj_name.get("payloadTemplateId") + if id_: + self.new_object.update(dict(payloadTemplateId=id_)) + result = self.meraki.exec_meraki( + family="networks", + function="deleteNetworkWebhooksPayloadTemplate", + params=self.delete_by_id_params(), + ) + return result + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = False + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + meraki = MERAKI(self._task.args) + obj = NetworksWebhooksPayloadTemplates(self._task.args, meraki) + + state = self._task.args.get("state") + + response = None + + if state == "present": + (obj_exists, prev_obj) = obj.exists() + if obj_exists: + if obj.requires_update(prev_obj): + response = obj.update() + meraki.object_updated() + else: + response = prev_obj + meraki.object_already_present() + else: + response = obj.create() + meraki.object_created() + + elif state == "absent": + (obj_exists, prev_obj) = obj.exists() + if obj_exists: + response = obj.delete() + meraki.object_deleted() + else: + meraki.object_already_absent() + + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_webhooks_payload_templates_info.py b/ansible_collections/cisco/meraki/plugins/action/networks_webhooks_payload_templates_info.py new file mode 100644 index 000000000..f38b9b4c2 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_webhooks_payload_templates_info.py @@ -0,0 +1,112 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + networkId=dict(type="str"), + payloadTemplateId=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_object(self, params): + new_object = {} + if params.get("networkId") is not None: + new_object["networkId"] = params.get( + "networkId") + if params.get("payloadTemplateId") is not None: + new_object["payloadTemplateId"] = params.get( + "payloadTemplateId") + return new_object + + def get_all(self, params): + new_object = {} + if params.get("networkId") is not None: + new_object["networkId"] = params.get( + "networkId") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + id = self._task.args.get("payloadTemplateId") + if id: + response = meraki.exec_meraki( + family="networks", + function='getNetworkWebhooksPayloadTemplate', + params=self.get_object(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result + if not id: + response = meraki.exec_meraki( + family="networks", + function='getNetworkWebhooksPayloadTemplates', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_webhooks_webhook_tests_info.py b/ansible_collections/cisco/meraki/plugins/action/networks_webhooks_webhook_tests_info.py new file mode 100644 index 000000000..77b77a402 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_webhooks_webhook_tests_info.py @@ -0,0 +1,102 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + networkId=dict(type="str"), + webhookTestId=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_object(self, params): + new_object = {} + if params.get("networkId") is not None: + new_object["networkId"] = params.get( + "networkId") + if params.get("webhookTestId") is not None: + new_object["webhookTestId"] = params.get( + "webhookTestId") + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + id = self._task.args.get("webhookTestId") + if id: + response = meraki.exec_meraki( + family="networks", + function='getNetworkWebhooksWebhookTest', + params=self.get_object(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result + if not id: + # NOTE: Does not have a get all method or it is in another action + response = None + meraki.object_modify_result(changed=False, result="Module does not have get all, check arguments of module") + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_wireless_alternate_management_interface.py b/ansible_collections/cisco/meraki/plugins/action/networks_wireless_alternate_management_interface.py new file mode 100644 index 000000000..899d9f264 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_wireless_alternate_management_interface.py @@ -0,0 +1,217 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or +# https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, + meraki_compare_equality, + get_dict_result, +) +from ansible_collections.cisco.meraki.plugins.plugin_utils.exceptions import ( + InconsistentParameters, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + state=dict(type="str", default="present", choices=["present"]), + enabled=dict(type="bool"), + vlanId=dict(type="int"), + protocols=dict(type="list"), + accessPoints=dict(type="list"), + networkId=dict(type="str"), +)) + +required_if = [ + ("state", "present", ["networkId"], True), +] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class NetworksWirelessAlternateManagementInterface(object): + def __init__(self, params, meraki): + self.meraki = meraki + self.new_object = dict( + enabled=params.get("enabled"), + vlanId=params.get("vlanId"), + protocols=params.get("protocols"), + accessPoints=params.get("accessPoints"), + network_id=params.get("networkId"), + ) + + def get_all_params(self, name=None, id=None): + new_object_params = {} + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + return new_object_params + + def update_all_params(self): + new_object_params = {} + if self.new_object.get('enabled') is not None or self.new_object.get('enabled') is not None: + new_object_params['enabled'] = self.new_object.get('enabled') + if self.new_object.get('vlanId') is not None or self.new_object.get('vlan_id') is not None: + new_object_params['vlanId'] = self.new_object.get('vlanId') or \ + self.new_object.get('vlan_id') + if self.new_object.get('protocols') is not None or self.new_object.get('protocols') is not None: + new_object_params['protocols'] = self.new_object.get('protocols') or \ + self.new_object.get('protocols') + if self.new_object.get('accessPoints') is not None or self.new_object.get('access_points') is not None: + new_object_params['accessPoints'] = self.new_object.get('accessPoints') or \ + self.new_object.get('access_points') + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + return new_object_params + + def get_object_by_name(self, name): + result = None + # NOTE: Does not have a get by name method, using get all + try: + items = self.meraki.exec_meraki( + family="wireless", + function="getNetworkWirelessAlternateManagementInterface", + params=self.get_all_params(name=name), + ) + if isinstance(items, dict): + if 'response' in items: + items = items.get('response') + result = get_dict_result(items, 'name', name) + if result is None: + result = items + except Exception as e: + print("Error: ", e) + result = None + return result + + def get_object_by_id(self, id): + result = None + # NOTE: Does not have a get by id method or it is in another action + return result + + def exists(self): + prev_obj = None + id_exists = False + name_exists = False + o_id = self.new_object.get("networkId") or self.new_object.get("network_id") + name = self.new_object.get("name") + if o_id: + prev_obj = self.get_object_by_name(o_id) + id_exists = prev_obj is not None and isinstance(prev_obj, dict) + if not id_exists and name: + prev_obj = self.get_object_by_name(name) + name_exists = prev_obj is not None and isinstance(prev_obj, dict) + if name_exists: + _id = prev_obj.get("id") + if id_exists and name_exists and o_id != _id: + raise InconsistentParameters( + "The 'id' and 'name' params don't refer to the same object") + if _id: + self.new_object.update(dict(id=_id)) + it_exists = prev_obj is not None and isinstance(prev_obj, dict) + return (it_exists, prev_obj) + + def requires_update(self, current_obj): + requested_obj = self.new_object + + obj_params = [ + ("enabled", "enabled"), + ("vlanId", "vlanId"), + ("protocols", "protocols"), + ("accessPoints", "accessPoints"), + ("networkId", "networkId"), + ] + # Method 1. Params present in request (Ansible) obj are the same as the current (ISE) params + # If any does not have eq params, it requires update + return any(not meraki_compare_equality(current_obj.get(meraki_param), + requested_obj.get(ansible_param)) + for (meraki_param, ansible_param) in obj_params) + + def update(self): + id = self.new_object.get("id") + name = self.new_object.get("name") + result = None + result = self.meraki.exec_meraki( + family="wireless", + function="updateNetworkWirelessAlternateManagementInterface", + params=self.update_all_params(), + op_modifies=True, + ) + return result + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = False + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + meraki = MERAKI(self._task.args) + obj = NetworksWirelessAlternateManagementInterface(self._task.args, meraki) + + state = self._task.args.get("state") + + response = None + if state == "present": + (obj_exists, prev_obj) = obj.exists() + if obj_exists: + if obj.requires_update(prev_obj): + response = obj.update() + meraki.object_updated() + else: + response = prev_obj + meraki.object_already_present() + else: + meraki.fail_json( + "Object does not exists, plugin only has update") + + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_wireless_alternate_management_interface_info.py b/ansible_collections/cisco/meraki/plugins/action/networks_wireless_alternate_management_interface_info.py new file mode 100644 index 000000000..cc934ca72 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_wireless_alternate_management_interface_info.py @@ -0,0 +1,90 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + networkId=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_all(self, params): + new_object = {} + if params.get("networkId") is not None: + new_object["networkId"] = params.get( + "networkId") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="wireless", + function='getNetworkWirelessAlternateManagementInterface', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_wireless_billing.py b/ansible_collections/cisco/meraki/plugins/action/networks_wireless_billing.py new file mode 100644 index 000000000..7db53a481 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_wireless_billing.py @@ -0,0 +1,206 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or +# https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, + meraki_compare_equality, + get_dict_result, +) +from ansible_collections.cisco.meraki.plugins.plugin_utils.exceptions import ( + InconsistentParameters, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + state=dict(type="str", default="present", choices=["present"]), + currency=dict(type="str"), + plans=dict(type="list"), + networkId=dict(type="str"), +)) + +required_if = [ + ("state", "present", ["networkId"], True), +] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class NetworksWirelessBilling(object): + def __init__(self, params, meraki): + self.meraki = meraki + self.new_object = dict( + currency=params.get("currency"), + plans=params.get("plans"), + network_id=params.get("networkId"), + ) + + def get_all_params(self, name=None, id=None): + new_object_params = {} + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + return new_object_params + + def update_all_params(self): + new_object_params = {} + if self.new_object.get('currency') is not None or self.new_object.get('currency') is not None: + new_object_params['currency'] = self.new_object.get('currency') or \ + self.new_object.get('currency') + if self.new_object.get('plans') is not None or self.new_object.get('plans') is not None: + new_object_params['plans'] = self.new_object.get('plans') or \ + self.new_object.get('plans') + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + return new_object_params + + def get_object_by_name(self, name): + result = None + # NOTE: Does not have a get by name method, using get all + try: + items = self.meraki.exec_meraki( + family="wireless", + function="getNetworkWirelessBilling", + params=self.get_all_params(name=name), + ) + if isinstance(items, dict): + if 'response' in items: + items = items.get('response') + result = get_dict_result(items, 'name', name) + if result is None: + result = items + except Exception as e: + print("Error: ", e) + result = None + return result + + def get_object_by_id(self, id): + result = None + # NOTE: Does not have a get by id method or it is in another action + return result + + def exists(self): + prev_obj = None + id_exists = False + name_exists = False + o_id = self.new_object.get("networkId") or self.new_object.get("network_id") + name = self.new_object.get("name") + if o_id: + prev_obj = self.get_object_by_name(o_id) + id_exists = prev_obj is not None and isinstance(prev_obj, dict) + if not id_exists and name: + prev_obj = self.get_object_by_name(name) + name_exists = prev_obj is not None and isinstance(prev_obj, dict) + if name_exists: + _id = prev_obj.get("id") + if id_exists and name_exists and o_id != _id: + raise InconsistentParameters( + "The 'id' and 'name' params don't refer to the same object") + if _id: + self.new_object.update(dict(id=_id)) + it_exists = prev_obj is not None and isinstance(prev_obj, dict) + return (it_exists, prev_obj) + + def requires_update(self, current_obj): + requested_obj = self.new_object + + obj_params = [ + ("currency", "currency"), + ("plans", "plans"), + ("networkId", "networkId"), + ] + # Method 1. Params present in request (Ansible) obj are the same as the current (ISE) params + # If any does not have eq params, it requires update + return any(not meraki_compare_equality(current_obj.get(meraki_param), + requested_obj.get(ansible_param)) + for (meraki_param, ansible_param) in obj_params) + + def update(self): + id = self.new_object.get("id") + name = self.new_object.get("name") + result = None + result = self.meraki.exec_meraki( + family="wireless", + function="updateNetworkWirelessBilling", + params=self.update_all_params(), + op_modifies=True, + ) + return result + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = False + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + meraki = MERAKI(self._task.args) + obj = NetworksWirelessBilling(self._task.args, meraki) + + state = self._task.args.get("state") + + response = None + if state == "present": + (obj_exists, prev_obj) = obj.exists() + if obj_exists: + if obj.requires_update(prev_obj): + response = obj.update() + meraki.object_updated() + else: + response = prev_obj + meraki.object_already_present() + else: + meraki.fail_json( + "Object does not exists, plugin only has update") + + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_wireless_billing_info.py b/ansible_collections/cisco/meraki/plugins/action/networks_wireless_billing_info.py new file mode 100644 index 000000000..b978e91b4 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_wireless_billing_info.py @@ -0,0 +1,90 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + networkId=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_all(self, params): + new_object = {} + if params.get("networkId") is not None: + new_object["networkId"] = params.get( + "networkId") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="wireless", + function='getNetworkWirelessBilling', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_wireless_bluetooth_settings.py b/ansible_collections/cisco/meraki/plugins/action/networks_wireless_bluetooth_settings.py new file mode 100644 index 000000000..59f9f6c75 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_wireless_bluetooth_settings.py @@ -0,0 +1,228 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or +# https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, + meraki_compare_equality, + get_dict_result, +) +from ansible_collections.cisco.meraki.plugins.plugin_utils.exceptions import ( + InconsistentParameters, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + state=dict(type="str", default="present", choices=["present"]), + scanningEnabled=dict(type="bool"), + advertisingEnabled=dict(type="bool"), + uuid=dict(type="str"), + majorMinorAssignmentMode=dict(type="str"), + major=dict(type="int"), + minor=dict(type="int"), + networkId=dict(type="str"), +)) + +required_if = [ + ("state", "present", ["networkId"], True), +] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class NetworksWirelessBluetoothSettings(object): + def __init__(self, params, meraki): + self.meraki = meraki + self.new_object = dict( + scanningEnabled=params.get("scanningEnabled"), + advertisingEnabled=params.get("advertisingEnabled"), + uuid=params.get("uuid"), + majorMinorAssignmentMode=params.get("majorMinorAssignmentMode"), + major=params.get("major"), + minor=params.get("minor"), + network_id=params.get("networkId"), + ) + + def get_all_params(self, name=None, id=None): + new_object_params = {} + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + return new_object_params + + def update_all_params(self): + new_object_params = {} + if self.new_object.get('scanningEnabled') is not None or self.new_object.get('scanning_enabled') is not None: + new_object_params['scanningEnabled'] = self.new_object.get('scanningEnabled') + if self.new_object.get('advertisingEnabled') is not None or self.new_object.get('advertising_enabled') is not None: + new_object_params['advertisingEnabled'] = self.new_object.get('advertisingEnabled') + if self.new_object.get('uuid') is not None or self.new_object.get('uuid') is not None: + new_object_params['uuid'] = self.new_object.get('uuid') or \ + self.new_object.get('uuid') + if self.new_object.get('majorMinorAssignmentMode') is not None or self.new_object.get('major_minor_assignment_mode') is not None: + new_object_params['majorMinorAssignmentMode'] = self.new_object.get('majorMinorAssignmentMode') or \ + self.new_object.get('major_minor_assignment_mode') + if self.new_object.get('major') is not None or self.new_object.get('major') is not None: + new_object_params['major'] = self.new_object.get('major') or \ + self.new_object.get('major') + if self.new_object.get('minor') is not None or self.new_object.get('minor') is not None: + new_object_params['minor'] = self.new_object.get('minor') or \ + self.new_object.get('minor') + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + return new_object_params + + def get_object_by_name(self, name): + result = None + # NOTE: Does not have a get by name method, using get all + try: + items = self.meraki.exec_meraki( + family="wireless", + function="getNetworkWirelessBluetoothSettings", + params=self.get_all_params(name=name), + ) + if isinstance(items, dict): + if 'response' in items: + items = items.get('response') + result = get_dict_result(items, 'name', name) + if result is None: + result = items + except Exception as e: + print("Error: ", e) + result = None + return result + + def get_object_by_id(self, id): + result = None + # NOTE: Does not have a get by id method or it is in another action + return result + + def exists(self): + prev_obj = None + id_exists = False + name_exists = False + o_id = self.new_object.get("networkId") or self.new_object.get("network_id") + name = self.new_object.get("name") + if o_id: + prev_obj = self.get_object_by_name(o_id) + id_exists = prev_obj is not None and isinstance(prev_obj, dict) + if not id_exists and name: + prev_obj = self.get_object_by_name(name) + name_exists = prev_obj is not None and isinstance(prev_obj, dict) + if name_exists: + _id = prev_obj.get("id") + if id_exists and name_exists and o_id != _id: + raise InconsistentParameters( + "The 'id' and 'name' params don't refer to the same object") + if _id: + self.new_object.update(dict(id=_id)) + it_exists = prev_obj is not None and isinstance(prev_obj, dict) + return (it_exists, prev_obj) + + def requires_update(self, current_obj): + requested_obj = self.new_object + + obj_params = [ + ("scanningEnabled", "scanningEnabled"), + ("advertisingEnabled", "advertisingEnabled"), + ("uuid", "uuid"), + ("majorMinorAssignmentMode", "majorMinorAssignmentMode"), + ("major", "major"), + ("minor", "minor"), + ("networkId", "networkId"), + ] + # Method 1. Params present in request (Ansible) obj are the same as the current (ISE) params + # If any does not have eq params, it requires update + return any(not meraki_compare_equality(current_obj.get(meraki_param), + requested_obj.get(ansible_param)) + for (meraki_param, ansible_param) in obj_params) + + def update(self): + id = self.new_object.get("id") + name = self.new_object.get("name") + result = None + result = self.meraki.exec_meraki( + family="wireless", + function="updateNetworkWirelessBluetoothSettings", + params=self.update_all_params(), + op_modifies=True, + ) + return result + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = False + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + meraki = MERAKI(self._task.args) + obj = NetworksWirelessBluetoothSettings(self._task.args, meraki) + + state = self._task.args.get("state") + + response = None + if state == "present": + (obj_exists, prev_obj) = obj.exists() + if obj_exists: + if obj.requires_update(prev_obj): + response = obj.update() + meraki.object_updated() + else: + response = prev_obj + meraki.object_already_present() + else: + meraki.fail_json( + "Object does not exists, plugin only has update") + + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_wireless_bluetooth_settings_info.py b/ansible_collections/cisco/meraki/plugins/action/networks_wireless_bluetooth_settings_info.py new file mode 100644 index 000000000..9489b0342 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_wireless_bluetooth_settings_info.py @@ -0,0 +1,90 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + networkId=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_all(self, params): + new_object = {} + if params.get("networkId") is not None: + new_object["networkId"] = params.get( + "networkId") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="wireless", + function='getNetworkWirelessBluetoothSettings', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_wireless_channel_utilization_history_info.py b/ansible_collections/cisco/meraki/plugins/action/networks_wireless_channel_utilization_history_info.py new file mode 100644 index 000000000..535bc4b93 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_wireless_channel_utilization_history_info.py @@ -0,0 +1,126 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + networkId=dict(type="str"), + t0=dict(type="str"), + t1=dict(type="str"), + timespan=dict(type="float"), + resolution=dict(type="int"), + autoResolution=dict(type="bool"), + clientId=dict(type="str"), + deviceSerial=dict(type="str"), + apTag=dict(type="str"), + band=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_all(self, params): + new_object = {} + if params.get("networkId") is not None: + new_object["networkId"] = params.get( + "networkId") + if params.get("t0") is not None: + new_object["t0"] = params.get( + "t0") + if params.get("t1") is not None: + new_object["t1"] = params.get( + "t1") + if params.get("timespan") is not None: + new_object["timespan"] = params.get( + "timespan") + if params.get("resolution") is not None: + new_object["resolution"] = params.get( + "resolution") + if params.get("autoResolution") is not None: + new_object["autoResolution"] = params.get( + "autoResolution") + if params.get("clientId") is not None: + new_object["clientId"] = params.get( + "clientId") + if params.get("deviceSerial") is not None: + new_object["deviceSerial"] = params.get( + "deviceSerial") + if params.get("apTag") is not None: + new_object["apTag"] = params.get( + "apTag") + if params.get("band") is not None: + new_object["band"] = params.get( + "band") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="wireless", + function='getNetworkWirelessChannelUtilizationHistory', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_wireless_client_count_history_info.py b/ansible_collections/cisco/meraki/plugins/action/networks_wireless_client_count_history_info.py new file mode 100644 index 000000000..96b80477e --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_wireless_client_count_history_info.py @@ -0,0 +1,130 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + networkId=dict(type="str"), + t0=dict(type="str"), + t1=dict(type="str"), + timespan=dict(type="float"), + resolution=dict(type="int"), + autoResolution=dict(type="bool"), + clientId=dict(type="str"), + deviceSerial=dict(type="str"), + apTag=dict(type="str"), + band=dict(type="str"), + ssid=dict(type="int"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_all(self, params): + new_object = {} + if params.get("networkId") is not None: + new_object["networkId"] = params.get( + "networkId") + if params.get("t0") is not None: + new_object["t0"] = params.get( + "t0") + if params.get("t1") is not None: + new_object["t1"] = params.get( + "t1") + if params.get("timespan") is not None: + new_object["timespan"] = params.get( + "timespan") + if params.get("resolution") is not None: + new_object["resolution"] = params.get( + "resolution") + if params.get("autoResolution") is not None: + new_object["autoResolution"] = params.get( + "autoResolution") + if params.get("clientId") is not None: + new_object["clientId"] = params.get( + "clientId") + if params.get("deviceSerial") is not None: + new_object["deviceSerial"] = params.get( + "deviceSerial") + if params.get("apTag") is not None: + new_object["apTag"] = params.get( + "apTag") + if params.get("band") is not None: + new_object["band"] = params.get( + "band") + if params.get("ssid") is not None: + new_object["ssid"] = params.get( + "ssid") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="wireless", + function='getNetworkWirelessClientCountHistory', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_wireless_clients_connection_stats_info.py b/ansible_collections/cisco/meraki/plugins/action/networks_wireless_clients_connection_stats_info.py new file mode 100644 index 000000000..0d3ec9d7f --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_wireless_clients_connection_stats_info.py @@ -0,0 +1,122 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + networkId=dict(type="str"), + clientId=dict(type="str"), + t0=dict(type="str"), + t1=dict(type="str"), + timespan=dict(type="float"), + band=dict(type="str"), + ssid=dict(type="int"), + vlan=dict(type="int"), + apTag=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_all(self, params): + new_object = {} + if params.get("networkId") is not None: + new_object["networkId"] = params.get( + "networkId") + if params.get("clientId") is not None: + new_object["clientId"] = params.get( + "clientId") + if params.get("t0") is not None: + new_object["t0"] = params.get( + "t0") + if params.get("t1") is not None: + new_object["t1"] = params.get( + "t1") + if params.get("timespan") is not None: + new_object["timespan"] = params.get( + "timespan") + if params.get("band") is not None: + new_object["band"] = params.get( + "band") + if params.get("ssid") is not None: + new_object["ssid"] = params.get( + "ssid") + if params.get("vlan") is not None: + new_object["vlan"] = params.get( + "vlan") + if params.get("apTag") is not None: + new_object["apTag"] = params.get( + "apTag") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="wireless", + function='getNetworkWirelessClientConnectionStats', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_wireless_clients_latency_stats_info.py b/ansible_collections/cisco/meraki/plugins/action/networks_wireless_clients_latency_stats_info.py new file mode 100644 index 000000000..54b3998d8 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_wireless_clients_latency_stats_info.py @@ -0,0 +1,126 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + networkId=dict(type="str"), + clientId=dict(type="str"), + t0=dict(type="str"), + t1=dict(type="str"), + timespan=dict(type="float"), + band=dict(type="str"), + ssid=dict(type="int"), + vlan=dict(type="int"), + apTag=dict(type="str"), + fields=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_all(self, params): + new_object = {} + if params.get("networkId") is not None: + new_object["networkId"] = params.get( + "networkId") + if params.get("clientId") is not None: + new_object["clientId"] = params.get( + "clientId") + if params.get("t0") is not None: + new_object["t0"] = params.get( + "t0") + if params.get("t1") is not None: + new_object["t1"] = params.get( + "t1") + if params.get("timespan") is not None: + new_object["timespan"] = params.get( + "timespan") + if params.get("band") is not None: + new_object["band"] = params.get( + "band") + if params.get("ssid") is not None: + new_object["ssid"] = params.get( + "ssid") + if params.get("vlan") is not None: + new_object["vlan"] = params.get( + "vlan") + if params.get("apTag") is not None: + new_object["apTag"] = params.get( + "apTag") + if params.get("fields") is not None: + new_object["fields"] = params.get( + "fields") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="wireless", + function='getNetworkWirelessClientLatencyStats', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_wireless_connection_stats_info.py b/ansible_collections/cisco/meraki/plugins/action/networks_wireless_connection_stats_info.py new file mode 100644 index 000000000..72fdfe283 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_wireless_connection_stats_info.py @@ -0,0 +1,118 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + networkId=dict(type="str"), + t0=dict(type="str"), + t1=dict(type="str"), + timespan=dict(type="float"), + band=dict(type="str"), + ssid=dict(type="int"), + vlan=dict(type="int"), + apTag=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_all(self, params): + new_object = {} + if params.get("networkId") is not None: + new_object["networkId"] = params.get( + "networkId") + if params.get("t0") is not None: + new_object["t0"] = params.get( + "t0") + if params.get("t1") is not None: + new_object["t1"] = params.get( + "t1") + if params.get("timespan") is not None: + new_object["timespan"] = params.get( + "timespan") + if params.get("band") is not None: + new_object["band"] = params.get( + "band") + if params.get("ssid") is not None: + new_object["ssid"] = params.get( + "ssid") + if params.get("vlan") is not None: + new_object["vlan"] = params.get( + "vlan") + if params.get("apTag") is not None: + new_object["apTag"] = params.get( + "apTag") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="wireless", + function='getNetworkWirelessConnectionStats', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_wireless_data_rate_history_info.py b/ansible_collections/cisco/meraki/plugins/action/networks_wireless_data_rate_history_info.py new file mode 100644 index 000000000..df1b3ce1a --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_wireless_data_rate_history_info.py @@ -0,0 +1,130 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + networkId=dict(type="str"), + t0=dict(type="str"), + t1=dict(type="str"), + timespan=dict(type="float"), + resolution=dict(type="int"), + autoResolution=dict(type="bool"), + clientId=dict(type="str"), + deviceSerial=dict(type="str"), + apTag=dict(type="str"), + band=dict(type="str"), + ssid=dict(type="int"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_all(self, params): + new_object = {} + if params.get("networkId") is not None: + new_object["networkId"] = params.get( + "networkId") + if params.get("t0") is not None: + new_object["t0"] = params.get( + "t0") + if params.get("t1") is not None: + new_object["t1"] = params.get( + "t1") + if params.get("timespan") is not None: + new_object["timespan"] = params.get( + "timespan") + if params.get("resolution") is not None: + new_object["resolution"] = params.get( + "resolution") + if params.get("autoResolution") is not None: + new_object["autoResolution"] = params.get( + "autoResolution") + if params.get("clientId") is not None: + new_object["clientId"] = params.get( + "clientId") + if params.get("deviceSerial") is not None: + new_object["deviceSerial"] = params.get( + "deviceSerial") + if params.get("apTag") is not None: + new_object["apTag"] = params.get( + "apTag") + if params.get("band") is not None: + new_object["band"] = params.get( + "band") + if params.get("ssid") is not None: + new_object["ssid"] = params.get( + "ssid") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="wireless", + function='getNetworkWirelessDataRateHistory', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_wireless_devices_connection_stats_info.py b/ansible_collections/cisco/meraki/plugins/action/networks_wireless_devices_connection_stats_info.py new file mode 100644 index 000000000..d6399b945 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_wireless_devices_connection_stats_info.py @@ -0,0 +1,118 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + networkId=dict(type="str"), + t0=dict(type="str"), + t1=dict(type="str"), + timespan=dict(type="float"), + band=dict(type="str"), + ssid=dict(type="int"), + vlan=dict(type="int"), + apTag=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_all(self, params): + new_object = {} + if params.get("networkId") is not None: + new_object["networkId"] = params.get( + "networkId") + if params.get("t0") is not None: + new_object["t0"] = params.get( + "t0") + if params.get("t1") is not None: + new_object["t1"] = params.get( + "t1") + if params.get("timespan") is not None: + new_object["timespan"] = params.get( + "timespan") + if params.get("band") is not None: + new_object["band"] = params.get( + "band") + if params.get("ssid") is not None: + new_object["ssid"] = params.get( + "ssid") + if params.get("vlan") is not None: + new_object["vlan"] = params.get( + "vlan") + if params.get("apTag") is not None: + new_object["apTag"] = params.get( + "apTag") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="wireless", + function='getNetworkWirelessDevicesConnectionStats', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_wireless_failed_connections_info.py b/ansible_collections/cisco/meraki/plugins/action/networks_wireless_failed_connections_info.py new file mode 100644 index 000000000..5985dc8fc --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_wireless_failed_connections_info.py @@ -0,0 +1,126 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + networkId=dict(type="str"), + t0=dict(type="str"), + t1=dict(type="str"), + timespan=dict(type="float"), + band=dict(type="str"), + ssid=dict(type="int"), + vlan=dict(type="int"), + apTag=dict(type="str"), + serial=dict(type="str"), + clientId=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_all(self, params): + new_object = {} + if params.get("networkId") is not None: + new_object["networkId"] = params.get( + "networkId") + if params.get("t0") is not None: + new_object["t0"] = params.get( + "t0") + if params.get("t1") is not None: + new_object["t1"] = params.get( + "t1") + if params.get("timespan") is not None: + new_object["timespan"] = params.get( + "timespan") + if params.get("band") is not None: + new_object["band"] = params.get( + "band") + if params.get("ssid") is not None: + new_object["ssid"] = params.get( + "ssid") + if params.get("vlan") is not None: + new_object["vlan"] = params.get( + "vlan") + if params.get("apTag") is not None: + new_object["apTag"] = params.get( + "apTag") + if params.get("serial") is not None: + new_object["serial"] = params.get( + "serial") + if params.get("clientId") is not None: + new_object["clientId"] = params.get( + "clientId") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="wireless", + function='getNetworkWirelessFailedConnections', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_wireless_latency_history_info.py b/ansible_collections/cisco/meraki/plugins/action/networks_wireless_latency_history_info.py new file mode 100644 index 000000000..795ef98e1 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_wireless_latency_history_info.py @@ -0,0 +1,134 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + networkId=dict(type="str"), + t0=dict(type="str"), + t1=dict(type="str"), + timespan=dict(type="float"), + resolution=dict(type="int"), + autoResolution=dict(type="bool"), + clientId=dict(type="str"), + deviceSerial=dict(type="str"), + apTag=dict(type="str"), + band=dict(type="str"), + ssid=dict(type="int"), + accessCategory=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_all(self, params): + new_object = {} + if params.get("networkId") is not None: + new_object["networkId"] = params.get( + "networkId") + if params.get("t0") is not None: + new_object["t0"] = params.get( + "t0") + if params.get("t1") is not None: + new_object["t1"] = params.get( + "t1") + if params.get("timespan") is not None: + new_object["timespan"] = params.get( + "timespan") + if params.get("resolution") is not None: + new_object["resolution"] = params.get( + "resolution") + if params.get("autoResolution") is not None: + new_object["autoResolution"] = params.get( + "autoResolution") + if params.get("clientId") is not None: + new_object["clientId"] = params.get( + "clientId") + if params.get("deviceSerial") is not None: + new_object["deviceSerial"] = params.get( + "deviceSerial") + if params.get("apTag") is not None: + new_object["apTag"] = params.get( + "apTag") + if params.get("band") is not None: + new_object["band"] = params.get( + "band") + if params.get("ssid") is not None: + new_object["ssid"] = params.get( + "ssid") + if params.get("accessCategory") is not None: + new_object["accessCategory"] = params.get( + "accessCategory") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="wireless", + function='getNetworkWirelessLatencyHistory', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_wireless_latency_stats_info.py b/ansible_collections/cisco/meraki/plugins/action/networks_wireless_latency_stats_info.py new file mode 100644 index 000000000..ee1d52e6c --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_wireless_latency_stats_info.py @@ -0,0 +1,122 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + networkId=dict(type="str"), + t0=dict(type="str"), + t1=dict(type="str"), + timespan=dict(type="float"), + band=dict(type="str"), + ssid=dict(type="int"), + vlan=dict(type="int"), + apTag=dict(type="str"), + fields=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_all(self, params): + new_object = {} + if params.get("networkId") is not None: + new_object["networkId"] = params.get( + "networkId") + if params.get("t0") is not None: + new_object["t0"] = params.get( + "t0") + if params.get("t1") is not None: + new_object["t1"] = params.get( + "t1") + if params.get("timespan") is not None: + new_object["timespan"] = params.get( + "timespan") + if params.get("band") is not None: + new_object["band"] = params.get( + "band") + if params.get("ssid") is not None: + new_object["ssid"] = params.get( + "ssid") + if params.get("vlan") is not None: + new_object["vlan"] = params.get( + "vlan") + if params.get("apTag") is not None: + new_object["apTag"] = params.get( + "apTag") + if params.get("fields") is not None: + new_object["fields"] = params.get( + "fields") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="wireless", + function='getNetworkWirelessLatencyStats', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_wireless_mesh_statuses_info.py b/ansible_collections/cisco/meraki/plugins/action/networks_wireless_mesh_statuses_info.py new file mode 100644 index 000000000..c7c0d5fa0 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_wireless_mesh_statuses_info.py @@ -0,0 +1,108 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + networkId=dict(type="str"), + perPage=dict(type="int"), + total_pages=dict(type="int"), + direction=dict(type="str"), + startingAfter=dict(type="str"), + endingBefore=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_all(self, params): + new_object = {} + if params.get("networkId") is not None: + new_object["networkId"] = params.get( + "networkId") + if params.get("perPage") is not None: + new_object["perPage"] = params.get( + "perPage") + new_object['total_pages'] = params.get( + "total_pages") or 1 + new_object['direction'] = params.get( + "direction") or "next" + if params.get("startingAfter") is not None: + new_object["startingAfter"] = params.get( + "startingAfter") + if params.get("endingBefore") is not None: + new_object["endingBefore"] = params.get( + "endingBefore") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="wireless", + function='getNetworkWirelessMeshStatuses', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_wireless_rf_profiles.py b/ansible_collections/cisco/meraki/plugins/action/networks_wireless_rf_profiles.py new file mode 100644 index 000000000..ad3f0d8ec --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_wireless_rf_profiles.py @@ -0,0 +1,384 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or +# https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, + meraki_compare_equality, + get_dict_result, +) +from ansible_collections.cisco.meraki.plugins.plugin_utils.exceptions import ( + InconsistentParameters, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + state=dict(type="str", default="present", choices=["present", "absent"]), + name=dict(type="str"), + clientBalancingEnabled=dict(type="bool"), + minBitrateType=dict(type="str"), + bandSelectionType=dict(type="str"), + apBandSettings=dict(type="dict"), + twoFourGhzSettings=dict(type="dict"), + fiveGhzSettings=dict(type="dict"), + sixGhzSettings=dict(type="dict"), + transmission=dict(type="dict"), + perSsidSettings=dict(type="dict"), + networkId=dict(type="str"), + rfProfileId=dict(type="str"), +)) + +required_if = [ + ("state", "present", ["name", "networkId", "rfProfileId"], True), + ("state", "absent", ["name", "networkId", "rfProfileId"], True), +] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class NetworksWirelessRfProfiles(object): + def __init__(self, params, meraki): + self.meraki = meraki + self.new_object = dict( + name=params.get("name"), + clientBalancingEnabled=params.get("clientBalancingEnabled"), + minBitrateType=params.get("minBitrateType"), + bandSelectionType=params.get("bandSelectionType"), + apBandSettings=params.get("apBandSettings"), + twoFourGhzSettings=params.get("twoFourGhzSettings"), + fiveGhzSettings=params.get("fiveGhzSettings"), + sixGhzSettings=params.get("sixGhzSettings"), + transmission=params.get("transmission"), + perSsidSettings=params.get("perSsidSettings"), + networkId=params.get("networkId"), + rfProfileId=params.get("rfProfileId"), + ) + + def get_all_params(self, name=None, id=None): + new_object_params = {} + if self.new_object.get('includeTemplateProfiles') is not None or self.new_object.get('include_template_profiles') is not None: + new_object_params['includeTemplateProfiles'] = self.new_object.get('includeTemplateProfiles') or \ + self.new_object.get('include_template_profiles') + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + return new_object_params + + def get_params_by_id(self, name=None, id=None): + new_object_params = {} + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + if self.new_object.get('rfProfileId') is not None or self.new_object.get('rf_profile_id') is not None: + new_object_params['rfProfileId'] = self.new_object.get('rfProfileId') or \ + self.new_object.get('rf_profile_id') + return new_object_params + + def create_params(self): + new_object_params = {} + if self.new_object.get('name') is not None or self.new_object.get('name') is not None: + new_object_params['name'] = self.new_object.get('name') or \ + self.new_object.get('name') + if self.new_object.get('clientBalancingEnabled') is not None or self.new_object.get('client_balancing_enabled') is not None: + new_object_params['clientBalancingEnabled'] = self.new_object.get('clientBalancingEnabled') + if self.new_object.get('minBitrateType') is not None or self.new_object.get('min_bitrate_type') is not None: + new_object_params['minBitrateType'] = self.new_object.get('minBitrateType') or \ + self.new_object.get('min_bitrate_type') + if self.new_object.get('bandSelectionType') is not None or self.new_object.get('band_selection_type') is not None: + new_object_params['bandSelectionType'] = self.new_object.get('bandSelectionType') or \ + self.new_object.get('band_selection_type') + if self.new_object.get('apBandSettings') is not None or self.new_object.get('ap_band_settings') is not None: + new_object_params['apBandSettings'] = self.new_object.get('apBandSettings') or \ + self.new_object.get('ap_band_settings') + if self.new_object.get('twoFourGhzSettings') is not None or self.new_object.get('two_four_ghz_settings') is not None: + new_object_params['twoFourGhzSettings'] = self.new_object.get('twoFourGhzSettings') or \ + self.new_object.get('two_four_ghz_settings') + if self.new_object.get('fiveGhzSettings') is not None or self.new_object.get('five_ghz_settings') is not None: + new_object_params['fiveGhzSettings'] = self.new_object.get('fiveGhzSettings') or \ + self.new_object.get('five_ghz_settings') + if self.new_object.get('sixGhzSettings') is not None or self.new_object.get('six_ghz_settings') is not None: + new_object_params['sixGhzSettings'] = self.new_object.get('sixGhzSettings') or \ + self.new_object.get('six_ghz_settings') + if self.new_object.get('transmission') is not None or self.new_object.get('transmission') is not None: + new_object_params['transmission'] = self.new_object.get('transmission') or \ + self.new_object.get('transmission') + if self.new_object.get('perSsidSettings') is not None or self.new_object.get('per_ssid_settings') is not None: + new_object_params['perSsidSettings'] = self.new_object.get('perSsidSettings') or \ + self.new_object.get('per_ssid_settings') + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + return new_object_params + + def delete_by_id_params(self): + new_object_params = {} + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + if self.new_object.get('rfProfileId') is not None or self.new_object.get('rf_profile_id') is not None: + new_object_params['rfProfileId'] = self.new_object.get('rfProfileId') or \ + self.new_object.get('rf_profile_id') + return new_object_params + + def update_by_id_params(self): + new_object_params = {} + if self.new_object.get('name') is not None or self.new_object.get('name') is not None: + new_object_params['name'] = self.new_object.get('name') or \ + self.new_object.get('name') + if self.new_object.get('clientBalancingEnabled') is not None or self.new_object.get('client_balancing_enabled') is not None: + new_object_params['clientBalancingEnabled'] = self.new_object.get('clientBalancingEnabled') + if self.new_object.get('minBitrateType') is not None or self.new_object.get('min_bitrate_type') is not None: + new_object_params['minBitrateType'] = self.new_object.get('minBitrateType') or \ + self.new_object.get('min_bitrate_type') + if self.new_object.get('bandSelectionType') is not None or self.new_object.get('band_selection_type') is not None: + new_object_params['bandSelectionType'] = self.new_object.get('bandSelectionType') or \ + self.new_object.get('band_selection_type') + if self.new_object.get('apBandSettings') is not None or self.new_object.get('ap_band_settings') is not None: + new_object_params['apBandSettings'] = self.new_object.get('apBandSettings') or \ + self.new_object.get('ap_band_settings') + if self.new_object.get('twoFourGhzSettings') is not None or self.new_object.get('two_four_ghz_settings') is not None: + new_object_params['twoFourGhzSettings'] = self.new_object.get('twoFourGhzSettings') or \ + self.new_object.get('two_four_ghz_settings') + if self.new_object.get('fiveGhzSettings') is not None or self.new_object.get('five_ghz_settings') is not None: + new_object_params['fiveGhzSettings'] = self.new_object.get('fiveGhzSettings') or \ + self.new_object.get('five_ghz_settings') + if self.new_object.get('sixGhzSettings') is not None or self.new_object.get('six_ghz_settings') is not None: + new_object_params['sixGhzSettings'] = self.new_object.get('sixGhzSettings') or \ + self.new_object.get('six_ghz_settings') + if self.new_object.get('transmission') is not None or self.new_object.get('transmission') is not None: + new_object_params['transmission'] = self.new_object.get('transmission') or \ + self.new_object.get('transmission') + if self.new_object.get('perSsidSettings') is not None or self.new_object.get('per_ssid_settings') is not None: + new_object_params['perSsidSettings'] = self.new_object.get('perSsidSettings') or \ + self.new_object.get('per_ssid_settings') + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + if self.new_object.get('rfProfileId') is not None or self.new_object.get('rf_profile_id') is not None: + new_object_params['rfProfileId'] = self.new_object.get('rfProfileId') or \ + self.new_object.get('rf_profile_id') + return new_object_params + + def get_object_by_name(self, name): + result = None + # NOTE: Does not have a get by name method or it is in another action + try: + items = self.meraki.exec_meraki( + family="wireless", + function="getNetworkWirelessRfProfiles", + params=self.get_all_params(name=name), + ) + if isinstance(items, dict): + if 'response' in items: + items = items.get('response') + result = get_dict_result(items, 'name', name) + if result is None: + result = items + except Exception as e: + print("Error: ", e) + result = None + return result + + def get_object_by_id(self, id): + result = None + try: + items = self.meraki.exec_meraki( + family="wireless", + function="getNetworkWirelessRfProfile", + params=self.get_params_by_id() + ) + if isinstance(items, dict): + if 'response' in items: + items = items.get('response') + result = get_dict_result(items, 'rfProfileId', id) + except Exception as e: + print("Error: ", e) + result = None + return result + + def exists(self): + id_exists = False + name_exists = False + prev_obj = None + o_id = self.new_object.get("id") + o_id = o_id or self.new_object.get( + "rf_profile_id") or self.new_object.get("rfProfileId") + name = self.new_object.get("name") + if o_id: + prev_obj = self.get_object_by_id(o_id) + id_exists = prev_obj is not None and isinstance(prev_obj, dict) + if not id_exists and name: + prev_obj = self.get_object_by_name(name) + name_exists = prev_obj is not None and isinstance(prev_obj, dict) + if name_exists: + _id = prev_obj.get("id") + _id = _id or prev_obj.get("rfProfileId") + if id_exists and name_exists and o_id != _id: + raise InconsistentParameters( + "The 'id' and 'name' params don't refer to the same object") + if _id: + self.new_object.update(dict(id=_id)) + self.new_object.update(dict(rfProfileId=_id)) + if _id: + prev_obj = self.get_object_by_id(_id) + it_exists = prev_obj is not None and isinstance(prev_obj, dict) + return (it_exists, prev_obj) + + def requires_update(self, current_obj): + requested_obj = self.new_object + + obj_params = [ + ("name", "name"), + ("clientBalancingEnabled", "clientBalancingEnabled"), + ("minBitrateType", "minBitrateType"), + ("bandSelectionType", "bandSelectionType"), + ("apBandSettings", "apBandSettings"), + ("twoFourGhzSettings", "twoFourGhzSettings"), + ("fiveGhzSettings", "fiveGhzSettings"), + ("sixGhzSettings", "sixGhzSettings"), + ("transmission", "transmission"), + ("perSsidSettings", "perSsidSettings"), + ("networkId", "networkId"), + ("rfProfileId", "rfProfileId"), + ] + # Method 1. Params present in request (Ansible) obj are the same as the current (DNAC) params + # If any does not have eq params, it requires update + return any(not meraki_compare_equality(current_obj.get(meraki_param), + requested_obj.get(ansible_param)) + for (meraki_param, ansible_param) in obj_params) + + def create(self): + result = self.meraki.exec_meraki( + family="wireless", + function="createNetworkWirelessRfProfile", + params=self.create_params(), + op_modifies=True, + ) + return result + + def update(self): + id = self.new_object.get("id") + id = id or self.new_object.get("rfProfileId") + name = self.new_object.get("name") + result = None + if not id: + prev_obj_name = self.get_object_by_name(name) + id_ = None + if prev_obj_name: + id_ = prev_obj_name.get("id") + id_ = id_ or prev_obj_name.get("rfProfileId") + if id_: + self.new_object.update(dict(rfProfileId=id_)) + result = self.meraki.exec_meraki( + family="wireless", + function="updateNetworkWirelessRfProfile", + params=self.update_by_id_params(), + op_modifies=True, + ) + return result + + def delete(self): + id = self.new_object.get("id") + id = id or self.new_object.get("rfProfileId") + name = self.new_object.get("name") + result = None + if not id: + prev_obj_name = self.get_object_by_name(name) + id_ = None + if prev_obj_name: + id_ = prev_obj_name.get("id") + id_ = id_ or prev_obj_name.get("rfProfileId") + if id_: + self.new_object.update(dict(rfProfileId=id_)) + result = self.meraki.exec_meraki( + family="wireless", + function="deleteNetworkWirelessRfProfile", + params=self.delete_by_id_params(), + ) + return result + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = False + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + meraki = MERAKI(self._task.args) + obj = NetworksWirelessRfProfiles(self._task.args, meraki) + + state = self._task.args.get("state") + + response = None + + if state == "present": + (obj_exists, prev_obj) = obj.exists() + if obj_exists: + if obj.requires_update(prev_obj): + response = obj.update() + meraki.object_updated() + else: + response = prev_obj + meraki.object_already_present() + else: + response = obj.create() + meraki.object_created() + + elif state == "absent": + (obj_exists, prev_obj) = obj.exists() + if obj_exists: + response = obj.delete() + meraki.object_deleted() + else: + meraki.object_already_absent() + + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_wireless_rf_profiles_info.py b/ansible_collections/cisco/meraki/plugins/action/networks_wireless_rf_profiles_info.py new file mode 100644 index 000000000..6d56c0639 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_wireless_rf_profiles_info.py @@ -0,0 +1,116 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + networkId=dict(type="str"), + includeTemplateProfiles=dict(type="bool"), + rfProfileId=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_object(self, params): + new_object = {} + if params.get("networkId") is not None: + new_object["networkId"] = params.get( + "networkId") + if params.get("rfProfileId") is not None: + new_object["rfProfileId"] = params.get( + "rfProfileId") + return new_object + + def get_all(self, params): + new_object = {} + if params.get("networkId") is not None: + new_object["networkId"] = params.get( + "networkId") + if params.get("includeTemplateProfiles") is not None: + new_object["includeTemplateProfiles"] = params.get( + "includeTemplateProfiles") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + id = self._task.args.get("rfProfileId") + if id: + response = meraki.exec_meraki( + family="wireless", + function='getNetworkWirelessRfProfile', + params=self.get_object(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result + if not id: + response = meraki.exec_meraki( + family="wireless", + function='getNetworkWirelessRfProfiles', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_wireless_settings.py b/ansible_collections/cisco/meraki/plugins/action/networks_wireless_settings.py new file mode 100644 index 000000000..2a7543475 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_wireless_settings.py @@ -0,0 +1,220 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or +# https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, + meraki_compare_equality, + get_dict_result, +) +from ansible_collections.cisco.meraki.plugins.plugin_utils.exceptions import ( + InconsistentParameters, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + state=dict(type="str", default="present", choices=["present"]), + meshingEnabled=dict(type="bool"), + ipv6BridgeEnabled=dict(type="bool"), + locationAnalyticsEnabled=dict(type="bool"), + upgradeStrategy=dict(type="str"), + ledLightsOn=dict(type="bool"), + networkId=dict(type="str"), +)) + +required_if = [ + ("state", "present", ["networkId"], True), +] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class NetworksWirelessSettings(object): + def __init__(self, params, meraki): + self.meraki = meraki + self.new_object = dict( + meshingEnabled=params.get("meshingEnabled"), + ipv6BridgeEnabled=params.get("ipv6BridgeEnabled"), + locationAnalyticsEnabled=params.get("locationAnalyticsEnabled"), + upgradeStrategy=params.get("upgradeStrategy"), + ledLightsOn=params.get("ledLightsOn"), + network_id=params.get("networkId"), + ) + + def get_all_params(self, name=None, id=None): + new_object_params = {} + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + return new_object_params + + def update_all_params(self): + new_object_params = {} + if self.new_object.get('meshingEnabled') is not None or self.new_object.get('meshing_enabled') is not None: + new_object_params['meshingEnabled'] = self.new_object.get('meshingEnabled') + if self.new_object.get('ipv6BridgeEnabled') is not None or self.new_object.get('ipv6_bridge_enabled') is not None: + new_object_params['ipv6BridgeEnabled'] = self.new_object.get('ipv6BridgeEnabled') + if self.new_object.get('locationAnalyticsEnabled') is not None or self.new_object.get('location_analytics_enabled') is not None: + new_object_params['locationAnalyticsEnabled'] = self.new_object.get('locationAnalyticsEnabled') + if self.new_object.get('upgradeStrategy') is not None or self.new_object.get('upgrade_strategy') is not None: + new_object_params['upgradeStrategy'] = self.new_object.get('upgradeStrategy') or \ + self.new_object.get('upgrade_strategy') + if self.new_object.get('ledLightsOn') is not None or self.new_object.get('led_lights_on') is not None: + new_object_params['ledLightsOn'] = self.new_object.get('ledLightsOn') + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + return new_object_params + + def get_object_by_name(self, name): + result = None + # NOTE: Does not have a get by name method, using get all + try: + items = self.meraki.exec_meraki( + family="wireless", + function="getNetworkWirelessSettings", + params=self.get_all_params(name=name), + ) + if isinstance(items, dict): + if 'response' in items: + items = items.get('response') + result = get_dict_result(items, 'name', name) + if result is None: + result = items + except Exception as e: + print("Error: ", e) + result = None + return result + + def get_object_by_id(self, id): + result = None + # NOTE: Does not have a get by id method or it is in another action + return result + + def exists(self): + prev_obj = None + id_exists = False + name_exists = False + o_id = self.new_object.get("networkId") or self.new_object.get("network_id") + name = self.new_object.get("name") + if o_id: + prev_obj = self.get_object_by_name(o_id) + id_exists = prev_obj is not None and isinstance(prev_obj, dict) + if not id_exists and name: + prev_obj = self.get_object_by_name(name) + name_exists = prev_obj is not None and isinstance(prev_obj, dict) + if name_exists: + _id = prev_obj.get("id") + if id_exists and name_exists and o_id != _id: + raise InconsistentParameters( + "The 'id' and 'name' params don't refer to the same object") + if _id: + self.new_object.update(dict(id=_id)) + it_exists = prev_obj is not None and isinstance(prev_obj, dict) + return (it_exists, prev_obj) + + def requires_update(self, current_obj): + requested_obj = self.new_object + + obj_params = [ + ("meshingEnabled", "meshingEnabled"), + ("ipv6BridgeEnabled", "ipv6BridgeEnabled"), + ("locationAnalyticsEnabled", "locationAnalyticsEnabled"), + ("upgradeStrategy", "upgradeStrategy"), + ("ledLightsOn", "ledLightsOn"), + ("networkId", "networkId"), + ] + # Method 1. Params present in request (Ansible) obj are the same as the current (ISE) params + # If any does not have eq params, it requires update + return any(not meraki_compare_equality(current_obj.get(meraki_param), + requested_obj.get(ansible_param)) + for (meraki_param, ansible_param) in obj_params) + + def update(self): + id = self.new_object.get("id") + name = self.new_object.get("name") + result = None + result = self.meraki.exec_meraki( + family="wireless", + function="updateNetworkWirelessSettings", + params=self.update_all_params(), + op_modifies=True, + ) + return result + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = False + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + meraki = MERAKI(self._task.args) + obj = NetworksWirelessSettings(self._task.args, meraki) + + state = self._task.args.get("state") + + response = None + if state == "present": + (obj_exists, prev_obj) = obj.exists() + if obj_exists: + if obj.requires_update(prev_obj): + response = obj.update() + meraki.object_updated() + else: + response = prev_obj + meraki.object_already_present() + else: + meraki.fail_json( + "Object does not exists, plugin only has update") + + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_wireless_settings_info.py b/ansible_collections/cisco/meraki/plugins/action/networks_wireless_settings_info.py new file mode 100644 index 000000000..fdee2e368 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_wireless_settings_info.py @@ -0,0 +1,90 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + networkId=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_all(self, params): + new_object = {} + if params.get("networkId") is not None: + new_object["networkId"] = params.get( + "networkId") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="wireless", + function='getNetworkWirelessSettings', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_wireless_signal_quality_history_info.py b/ansible_collections/cisco/meraki/plugins/action/networks_wireless_signal_quality_history_info.py new file mode 100644 index 000000000..51105dee7 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_wireless_signal_quality_history_info.py @@ -0,0 +1,130 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + networkId=dict(type="str"), + t0=dict(type="str"), + t1=dict(type="str"), + timespan=dict(type="float"), + resolution=dict(type="int"), + autoResolution=dict(type="bool"), + clientId=dict(type="str"), + deviceSerial=dict(type="str"), + apTag=dict(type="str"), + band=dict(type="str"), + ssid=dict(type="int"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_all(self, params): + new_object = {} + if params.get("networkId") is not None: + new_object["networkId"] = params.get( + "networkId") + if params.get("t0") is not None: + new_object["t0"] = params.get( + "t0") + if params.get("t1") is not None: + new_object["t1"] = params.get( + "t1") + if params.get("timespan") is not None: + new_object["timespan"] = params.get( + "timespan") + if params.get("resolution") is not None: + new_object["resolution"] = params.get( + "resolution") + if params.get("autoResolution") is not None: + new_object["autoResolution"] = params.get( + "autoResolution") + if params.get("clientId") is not None: + new_object["clientId"] = params.get( + "clientId") + if params.get("deviceSerial") is not None: + new_object["deviceSerial"] = params.get( + "deviceSerial") + if params.get("apTag") is not None: + new_object["apTag"] = params.get( + "apTag") + if params.get("band") is not None: + new_object["band"] = params.get( + "band") + if params.get("ssid") is not None: + new_object["ssid"] = params.get( + "ssid") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="wireless", + function='getNetworkWirelessSignalQualityHistory', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_wireless_ssids.py b/ansible_collections/cisco/meraki/plugins/action/networks_wireless_ssids.py new file mode 100644 index 000000000..eb8affa88 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_wireless_ssids.py @@ -0,0 +1,569 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or +# https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, + meraki_compare_equality, + get_dict_result, +) +from ansible_collections.cisco.meraki.plugins.plugin_utils.exceptions import ( + InconsistentParameters, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + state=dict(type="str", default="present", choices=["present"]), + name=dict(type="str"), + enabled=dict(type="bool"), + authMode=dict(type="str"), + enterpriseAdminAccess=dict(type="str"), + encryptionMode=dict(type="str"), + psk=dict(type="str"), + wpaEncryptionMode=dict(type="str"), + dot11w=dict(type="dict"), + dot11r=dict(type="dict"), + splashPage=dict(type="str"), + splashGuestSponsorDomains=dict(type="list"), + oauth=dict(type="dict"), + localRadius=dict(type="dict"), + ldap=dict(type="dict"), + activeDirectory=dict(type="dict"), + radiusServers=dict(type="list"), + radiusProxyEnabled=dict(type="bool"), + radiusTestingEnabled=dict(type="bool"), + radiusCalledStationId=dict(type="str"), + radiusAuthenticationNasId=dict(type="str"), + radiusServerTimeout=dict(type="int"), + radiusServerAttemptsLimit=dict(type="int"), + radiusFallbackEnabled=dict(type="bool"), + radiusCoaEnabled=dict(type="bool"), + radiusFailoverPolicy=dict(type="str"), + radiusLoadBalancingPolicy=dict(type="str"), + radiusAccountingEnabled=dict(type="bool"), + radiusAccountingServers=dict(type="list"), + radiusAccountingInterimInterval=dict(type="int"), + radiusAttributeForGroupPolicies=dict(type="str"), + ipAssignmentMode=dict(type="str"), + useVlanTagging=dict(type="bool"), + concentratorNetworkId=dict(type="str"), + secondaryConcentratorNetworkId=dict(type="str"), + disassociateClientsOnVpnFailover=dict(type="bool"), + vlanId=dict(type="int"), + defaultVlanId=dict(type="int"), + apTagsAndVlanIds=dict(type="list"), + walledGardenEnabled=dict(type="bool"), + walledGardenRanges=dict(type="list"), + gre=dict(type="dict"), + radiusOverride=dict(type="bool"), + radiusGuestVlanEnabled=dict(type="bool"), + radiusGuestVlanId=dict(type="int"), + minBitrate=dict(type="float"), + bandSelection=dict(type="str"), + perClientBandwidthLimitUp=dict(type="int"), + perClientBandwidthLimitDown=dict(type="int"), + perSsidBandwidthLimitUp=dict(type="int"), + perSsidBandwidthLimitDown=dict(type="int"), + lanIsolationEnabled=dict(type="bool"), + visible=dict(type="bool"), + availableOnAllAps=dict(type="bool"), + availabilityTags=dict(type="list"), + mandatoryDhcpEnabled=dict(type="bool"), + adultContentFilteringEnabled=dict(type="bool"), + dnsRewrite=dict(type="dict"), + speedBurst=dict(type="dict"), + networkId=dict(type="str"), + number=dict(type="str"), +)) + +required_if = [ + ("state", "present", ["name", "networkId", "number"], True), +] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class NetworksWirelessSsids(object): + def __init__(self, params, meraki): + self.meraki = meraki + self.new_object = dict( + name=params.get("name"), + enabled=params.get("enabled"), + authMode=params.get("authMode"), + enterpriseAdminAccess=params.get("enterpriseAdminAccess"), + encryptionMode=params.get("encryptionMode"), + psk=params.get("psk"), + wpaEncryptionMode=params.get("wpaEncryptionMode"), + dot11w=params.get("dot11w"), + dot11r=params.get("dot11r"), + splashPage=params.get("splashPage"), + splashGuestSponsorDomains=params.get("splashGuestSponsorDomains"), + oauth=params.get("oauth"), + localRadius=params.get("localRadius"), + ldap=params.get("ldap"), + activeDirectory=params.get("activeDirectory"), + radiusServers=params.get("radiusServers"), + radiusProxyEnabled=params.get("radiusProxyEnabled"), + radiusTestingEnabled=params.get("radiusTestingEnabled"), + radiusCalledStationId=params.get("radiusCalledStationId"), + radiusAuthenticationNasId=params.get("radiusAuthenticationNasId"), + radiusServerTimeout=params.get("radiusServerTimeout"), + radiusServerAttemptsLimit=params.get("radiusServerAttemptsLimit"), + radiusFallbackEnabled=params.get("radiusFallbackEnabled"), + radiusCoaEnabled=params.get("radiusCoaEnabled"), + radiusFailoverPolicy=params.get("radiusFailoverPolicy"), + radiusLoadBalancingPolicy=params.get("radiusLoadBalancingPolicy"), + radiusAccountingEnabled=params.get("radiusAccountingEnabled"), + radiusAccountingServers=params.get("radiusAccountingServers"), + radiusAccountingInterimInterval=params.get("radiusAccountingInterimInterval"), + radiusAttributeForGroupPolicies=params.get("radiusAttributeForGroupPolicies"), + ipAssignmentMode=params.get("ipAssignmentMode"), + useVlanTagging=params.get("useVlanTagging"), + concentratorNetworkId=params.get("concentratorNetworkId"), + secondaryConcentratorNetworkId=params.get("secondaryConcentratorNetworkId"), + disassociateClientsOnVpnFailover=params.get("disassociateClientsOnVpnFailover"), + vlanId=params.get("vlanId"), + defaultVlanId=params.get("defaultVlanId"), + apTagsAndVlanIds=params.get("apTagsAndVlanIds"), + walledGardenEnabled=params.get("walledGardenEnabled"), + walledGardenRanges=params.get("walledGardenRanges"), + gre=params.get("gre"), + radiusOverride=params.get("radiusOverride"), + radiusGuestVlanEnabled=params.get("radiusGuestVlanEnabled"), + radiusGuestVlanId=params.get("radiusGuestVlanId"), + minBitrate=params.get("minBitrate"), + bandSelection=params.get("bandSelection"), + perClientBandwidthLimitUp=params.get("perClientBandwidthLimitUp"), + perClientBandwidthLimitDown=params.get("perClientBandwidthLimitDown"), + perSsidBandwidthLimitUp=params.get("perSsidBandwidthLimitUp"), + perSsidBandwidthLimitDown=params.get("perSsidBandwidthLimitDown"), + lanIsolationEnabled=params.get("lanIsolationEnabled"), + visible=params.get("visible"), + availableOnAllAps=params.get("availableOnAllAps"), + availabilityTags=params.get("availabilityTags"), + mandatoryDhcpEnabled=params.get("mandatoryDhcpEnabled"), + adultContentFilteringEnabled=params.get("adultContentFilteringEnabled"), + dnsRewrite=params.get("dnsRewrite"), + speedBurst=params.get("speedBurst"), + network_id=params.get("networkId"), + number=params.get("number"), + ) + + def get_all_params(self, name=None, id=None): + new_object_params = {} + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + return new_object_params + + def get_params_by_id(self, name=None, id=None): + new_object_params = {} + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + if self.new_object.get('number') is not None or self.new_object.get('number') is not None: + new_object_params['number'] = self.new_object.get('number') + return new_object_params + + def update_by_id_params(self): + new_object_params = {} + if self.new_object.get('name') is not None or self.new_object.get('name') is not None: + new_object_params['name'] = self.new_object.get('name') or \ + self.new_object.get('name') + if self.new_object.get('enabled') is not None or self.new_object.get('enabled') is not None: + new_object_params['enabled'] = self.new_object.get('enabled') + if self.new_object.get('authMode') is not None or self.new_object.get('auth_mode') is not None: + new_object_params['authMode'] = self.new_object.get('authMode') or \ + self.new_object.get('auth_mode') + if self.new_object.get('enterpriseAdminAccess') is not None or self.new_object.get('enterprise_admin_access') is not None: + new_object_params['enterpriseAdminAccess'] = self.new_object.get('enterpriseAdminAccess') or \ + self.new_object.get('enterprise_admin_access') + if self.new_object.get('encryptionMode') is not None or self.new_object.get('encryption_mode') is not None: + new_object_params['encryptionMode'] = self.new_object.get('encryptionMode') or \ + self.new_object.get('encryption_mode') + if self.new_object.get('psk') is not None or self.new_object.get('psk') is not None: + new_object_params['psk'] = self.new_object.get('psk') or \ + self.new_object.get('psk') + if self.new_object.get('wpaEncryptionMode') is not None or self.new_object.get('wpa_encryption_mode') is not None: + new_object_params['wpaEncryptionMode'] = self.new_object.get('wpaEncryptionMode') or \ + self.new_object.get('wpa_encryption_mode') + if self.new_object.get('dot11w') is not None or self.new_object.get('dot11w') is not None: + new_object_params['dot11w'] = self.new_object.get('dot11w') or \ + self.new_object.get('dot11w') + if self.new_object.get('dot11r') is not None or self.new_object.get('dot11r') is not None: + new_object_params['dot11r'] = self.new_object.get('dot11r') or \ + self.new_object.get('dot11r') + if self.new_object.get('splashPage') is not None or self.new_object.get('splash_page') is not None: + new_object_params['splashPage'] = self.new_object.get('splashPage') or \ + self.new_object.get('splash_page') + if self.new_object.get('splashGuestSponsorDomains') is not None or self.new_object.get('splash_guest_sponsor_domains') is not None: + new_object_params['splashGuestSponsorDomains'] = self.new_object.get('splashGuestSponsorDomains') or \ + self.new_object.get('splash_guest_sponsor_domains') + if self.new_object.get('oauth') is not None or self.new_object.get('oauth') is not None: + new_object_params['oauth'] = self.new_object.get('oauth') or \ + self.new_object.get('oauth') + if self.new_object.get('localRadius') is not None or self.new_object.get('local_radius') is not None: + new_object_params['localRadius'] = self.new_object.get('localRadius') or \ + self.new_object.get('local_radius') + if self.new_object.get('ldap') is not None or self.new_object.get('ldap') is not None: + new_object_params['ldap'] = self.new_object.get('ldap') or \ + self.new_object.get('ldap') + if self.new_object.get('activeDirectory') is not None or self.new_object.get('active_directory') is not None: + new_object_params['activeDirectory'] = self.new_object.get('activeDirectory') or \ + self.new_object.get('active_directory') + if self.new_object.get('radiusServers') is not None or self.new_object.get('radius_servers') is not None: + new_object_params['radiusServers'] = self.new_object.get('radiusServers') or \ + self.new_object.get('radius_servers') + if self.new_object.get('radiusProxyEnabled') is not None or self.new_object.get('radius_proxy_enabled') is not None: + new_object_params['radiusProxyEnabled'] = self.new_object.get('radiusProxyEnabled') + if self.new_object.get('radiusTestingEnabled') is not None or self.new_object.get('radius_testing_enabled') is not None: + new_object_params['radiusTestingEnabled'] = self.new_object.get('radiusTestingEnabled') + if self.new_object.get('radiusCalledStationId') is not None or self.new_object.get('radius_called_station_id') is not None: + new_object_params['radiusCalledStationId'] = self.new_object.get('radiusCalledStationId') or \ + self.new_object.get('radius_called_station_id') + if self.new_object.get('radiusAuthenticationNasId') is not None or self.new_object.get('radius_authentication_nas_id') is not None: + new_object_params['radiusAuthenticationNasId'] = self.new_object.get('radiusAuthenticationNasId') or \ + self.new_object.get('radius_authentication_nas_id') + if self.new_object.get('radiusServerTimeout') is not None or self.new_object.get('radius_server_timeout') is not None: + new_object_params['radiusServerTimeout'] = self.new_object.get('radiusServerTimeout') or \ + self.new_object.get('radius_server_timeout') + if self.new_object.get('radiusServerAttemptsLimit') is not None or self.new_object.get('radius_server_attempts_limit') is not None: + new_object_params['radiusServerAttemptsLimit'] = self.new_object.get('radiusServerAttemptsLimit') or \ + self.new_object.get('radius_server_attempts_limit') + if self.new_object.get('radiusFallbackEnabled') is not None or self.new_object.get('radius_fallback_enabled') is not None: + new_object_params['radiusFallbackEnabled'] = self.new_object.get('radiusFallbackEnabled') + if self.new_object.get('radiusCoaEnabled') is not None or self.new_object.get('radius_coa_enabled') is not None: + new_object_params['radiusCoaEnabled'] = self.new_object.get('radiusCoaEnabled') + if self.new_object.get('radiusFailoverPolicy') is not None or self.new_object.get('radius_failover_policy') is not None: + new_object_params['radiusFailoverPolicy'] = self.new_object.get('radiusFailoverPolicy') or \ + self.new_object.get('radius_failover_policy') + if self.new_object.get('radiusLoadBalancingPolicy') is not None or self.new_object.get('radius_load_balancing_policy') is not None: + new_object_params['radiusLoadBalancingPolicy'] = self.new_object.get('radiusLoadBalancingPolicy') or \ + self.new_object.get('radius_load_balancing_policy') + if self.new_object.get('radiusAccountingEnabled') is not None or self.new_object.get('radius_accounting_enabled') is not None: + new_object_params['radiusAccountingEnabled'] = self.new_object.get('radiusAccountingEnabled') + if self.new_object.get('radiusAccountingServers') is not None or self.new_object.get('radius_accounting_servers') is not None: + new_object_params['radiusAccountingServers'] = self.new_object.get('radiusAccountingServers') or \ + self.new_object.get('radius_accounting_servers') + if self.new_object.get('radiusAccountingInterimInterval') is not None or self.new_object.get('radius_accounting_interim_interval') is not None: + new_object_params['radiusAccountingInterimInterval'] = self.new_object.get('radiusAccountingInterimInterval') or \ + self.new_object.get('radius_accounting_interim_interval') + if self.new_object.get('radiusAttributeForGroupPolicies') is not None or self.new_object.get('radius_attribute_for_group_policies') is not None: + new_object_params['radiusAttributeForGroupPolicies'] = self.new_object.get('radiusAttributeForGroupPolicies') or \ + self.new_object.get('radius_attribute_for_group_policies') + if self.new_object.get('ipAssignmentMode') is not None or self.new_object.get('ip_assignment_mode') is not None: + new_object_params['ipAssignmentMode'] = self.new_object.get('ipAssignmentMode') or \ + self.new_object.get('ip_assignment_mode') + if self.new_object.get('useVlanTagging') is not None or self.new_object.get('use_vlan_tagging') is not None: + new_object_params['useVlanTagging'] = self.new_object.get('useVlanTagging') + if self.new_object.get('concentratorNetworkId') is not None or self.new_object.get('concentrator_network_id') is not None: + new_object_params['concentratorNetworkId'] = self.new_object.get('concentratorNetworkId') or \ + self.new_object.get('concentrator_network_id') + if self.new_object.get('secondaryConcentratorNetworkId') is not None or self.new_object.get('secondary_concentrator_network_id') is not None: + new_object_params['secondaryConcentratorNetworkId'] = self.new_object.get('secondaryConcentratorNetworkId') or \ + self.new_object.get('secondary_concentrator_network_id') + if self.new_object.get('disassociateClientsOnVpnFailover') is not None or self.new_object.get('disassociate_clients_on_vpn_failover') is not None: + new_object_params['disassociateClientsOnVpnFailover'] = self.new_object.get('disassociateClientsOnVpnFailover') + if self.new_object.get('vlanId') is not None or self.new_object.get('vlan_id') is not None: + new_object_params['vlanId'] = self.new_object.get('vlanId') or \ + self.new_object.get('vlan_id') + if self.new_object.get('defaultVlanId') is not None or self.new_object.get('default_vlan_id') is not None: + new_object_params['defaultVlanId'] = self.new_object.get('defaultVlanId') or \ + self.new_object.get('default_vlan_id') + if self.new_object.get('apTagsAndVlanIds') is not None or self.new_object.get('ap_tags_and_vlan_ids') is not None: + new_object_params['apTagsAndVlanIds'] = self.new_object.get('apTagsAndVlanIds') or \ + self.new_object.get('ap_tags_and_vlan_ids') + if self.new_object.get('walledGardenEnabled') is not None or self.new_object.get('walled_garden_enabled') is not None: + new_object_params['walledGardenEnabled'] = self.new_object.get('walledGardenEnabled') + if self.new_object.get('walledGardenRanges') is not None or self.new_object.get('walled_garden_ranges') is not None: + new_object_params['walledGardenRanges'] = self.new_object.get('walledGardenRanges') or \ + self.new_object.get('walled_garden_ranges') + if self.new_object.get('gre') is not None or self.new_object.get('gre') is not None: + new_object_params['gre'] = self.new_object.get('gre') or \ + self.new_object.get('gre') + if self.new_object.get('radiusOverride') is not None or self.new_object.get('radius_override') is not None: + new_object_params['radiusOverride'] = self.new_object.get('radiusOverride') + if self.new_object.get('radiusGuestVlanEnabled') is not None or self.new_object.get('radius_guest_vlan_enabled') is not None: + new_object_params['radiusGuestVlanEnabled'] = self.new_object.get('radiusGuestVlanEnabled') + if self.new_object.get('radiusGuestVlanId') is not None or self.new_object.get('radius_guest_vlan_id') is not None: + new_object_params['radiusGuestVlanId'] = self.new_object.get('radiusGuestVlanId') or \ + self.new_object.get('radius_guest_vlan_id') + if self.new_object.get('minBitrate') is not None or self.new_object.get('min_bitrate') is not None: + new_object_params['minBitrate'] = self.new_object.get('minBitrate') or \ + self.new_object.get('min_bitrate') + if self.new_object.get('bandSelection') is not None or self.new_object.get('band_selection') is not None: + new_object_params['bandSelection'] = self.new_object.get('bandSelection') or \ + self.new_object.get('band_selection') + if self.new_object.get('perClientBandwidthLimitUp') is not None or self.new_object.get('per_client_bandwidth_limit_up') is not None: + new_object_params['perClientBandwidthLimitUp'] = self.new_object.get('perClientBandwidthLimitUp') or \ + self.new_object.get('per_client_bandwidth_limit_up') + if self.new_object.get('perClientBandwidthLimitDown') is not None or self.new_object.get('per_client_bandwidth_limit_down') is not None: + new_object_params['perClientBandwidthLimitDown'] = self.new_object.get('perClientBandwidthLimitDown') or \ + self.new_object.get('per_client_bandwidth_limit_down') + if self.new_object.get('perSsidBandwidthLimitUp') is not None or self.new_object.get('per_ssid_bandwidth_limit_up') is not None: + new_object_params['perSsidBandwidthLimitUp'] = self.new_object.get('perSsidBandwidthLimitUp') or \ + self.new_object.get('per_ssid_bandwidth_limit_up') + if self.new_object.get('perSsidBandwidthLimitDown') is not None or self.new_object.get('per_ssid_bandwidth_limit_down') is not None: + new_object_params['perSsidBandwidthLimitDown'] = self.new_object.get('perSsidBandwidthLimitDown') or \ + self.new_object.get('per_ssid_bandwidth_limit_down') + if self.new_object.get('lanIsolationEnabled') is not None or self.new_object.get('lan_isolation_enabled') is not None: + new_object_params['lanIsolationEnabled'] = self.new_object.get('lanIsolationEnabled') + if self.new_object.get('visible') is not None or self.new_object.get('visible') is not None: + new_object_params['visible'] = self.new_object.get('visible') + if self.new_object.get('availableOnAllAps') is not None or self.new_object.get('available_on_all_aps') is not None: + new_object_params['availableOnAllAps'] = self.new_object.get('availableOnAllAps') + if self.new_object.get('availabilityTags') is not None or self.new_object.get('availability_tags') is not None: + new_object_params['availabilityTags'] = self.new_object.get('availabilityTags') or \ + self.new_object.get('availability_tags') + if self.new_object.get('mandatoryDhcpEnabled') is not None or self.new_object.get('mandatory_dhcp_enabled') is not None: + new_object_params['mandatoryDhcpEnabled'] = self.new_object.get('mandatoryDhcpEnabled') + if self.new_object.get('adultContentFilteringEnabled') is not None or self.new_object.get('adult_content_filtering_enabled') is not None: + new_object_params['adultContentFilteringEnabled'] = self.new_object.get('adultContentFilteringEnabled') + if self.new_object.get('dnsRewrite') is not None or self.new_object.get('dns_rewrite') is not None: + new_object_params['dnsRewrite'] = self.new_object.get('dnsRewrite') or \ + self.new_object.get('dns_rewrite') + if self.new_object.get('speedBurst') is not None or self.new_object.get('speed_burst') is not None: + new_object_params['speedBurst'] = self.new_object.get('speedBurst') or \ + self.new_object.get('speed_burst') + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + if self.new_object.get('number') is not None or self.new_object.get('number') is not None: + new_object_params['number'] = self.new_object.get('number') or \ + self.new_object.get('number') + return new_object_params + + def get_object_by_name(self, name): + result = None + # NOTE: Does not have a get by name method, using get all + try: + items = self.meraki.exec_meraki( + family="wireless", + function="getNetworkWirelessSsids", + params=self.get_all_params(name=name), + ) + if isinstance(items, dict): + if 'response' in items: + items = items.get('response') + result = get_dict_result(items, 'name', name) + if result is None: + result = items + except Exception as e: + print("Error: ", e) + result = None + return result + + def get_object_by_id(self, id): + result = None + try: + items = self.meraki.exec_meraki( + family="wireless", + function="getNetworkWirelessSsid", + params=self.get_params_by_id() + ) + if isinstance(items, dict): + if 'response' in items: + items = items.get('response') + result = items + except Exception as e: + print("Error: ", e) + result = None + return result + + def exists(self): + prev_obj = None + id_exists = False + name_exists = False + o_id = self.new_object.get("networkId") or self.new_object.get("network_id") + o_id = o_id or self.new_object.get( + "number") or self.new_object.get("number") + name = o_id or self.new_object.get("name") + if o_id: + prev_obj = self.get_object_by_id(o_id) + id_exists = prev_obj is not None and isinstance(prev_obj, dict) + if not id_exists and name: + prev_obj = self.get_object_by_name(name) + name_exists = prev_obj is not None and isinstance(prev_obj, dict) + if name_exists: + _id = prev_obj.get("id") + _id = _id or prev_obj.get("number") + if id_exists and name_exists and o_id != _id: + raise InconsistentParameters( + "The 'id' and 'name' params don't refer to the same object") + if _id: + self.new_object.update(dict(id=_id)) + self.new_object.update(dict(number=_id)) + if _id: + prev_obj = self.get_object_by_id(_id) + it_exists = prev_obj is not None and isinstance(prev_obj, dict) + return (it_exists, prev_obj) + + def requires_update(self, current_obj): + requested_obj = self.new_object + + obj_params = [ + ("name", "name"), + ("enabled", "enabled"), + ("authMode", "authMode"), + ("enterpriseAdminAccess", "enterpriseAdminAccess"), + ("encryptionMode", "encryptionMode"), + ("psk", "psk"), + ("wpaEncryptionMode", "wpaEncryptionMode"), + ("dot11w", "dot11w"), + ("dot11r", "dot11r"), + ("splashPage", "splashPage"), + ("splashGuestSponsorDomains", "splashGuestSponsorDomains"), + ("oauth", "oauth"), + ("localRadius", "localRadius"), + ("ldap", "ldap"), + ("activeDirectory", "activeDirectory"), + ("radiusServers", "radiusServers"), + ("radiusProxyEnabled", "radiusProxyEnabled"), + ("radiusTestingEnabled", "radiusTestingEnabled"), + ("radiusCalledStationId", "radiusCalledStationId"), + ("radiusAuthenticationNasId", "radiusAuthenticationNasId"), + ("radiusServerTimeout", "radiusServerTimeout"), + ("radiusServerAttemptsLimit", "radiusServerAttemptsLimit"), + ("radiusFallbackEnabled", "radiusFallbackEnabled"), + ("radiusCoaEnabled", "radiusCoaEnabled"), + ("radiusFailoverPolicy", "radiusFailoverPolicy"), + ("radiusLoadBalancingPolicy", "radiusLoadBalancingPolicy"), + ("radiusAccountingEnabled", "radiusAccountingEnabled"), + ("radiusAccountingServers", "radiusAccountingServers"), + ("radiusAccountingInterimInterval", "radiusAccountingInterimInterval"), + ("radiusAttributeForGroupPolicies", "radiusAttributeForGroupPolicies"), + ("ipAssignmentMode", "ipAssignmentMode"), + ("useVlanTagging", "useVlanTagging"), + ("concentratorNetworkId", "concentratorNetworkId"), + ("secondaryConcentratorNetworkId", "secondaryConcentratorNetworkId"), + ("disassociateClientsOnVpnFailover", "disassociateClientsOnVpnFailover"), + ("vlanId", "vlanId"), + ("defaultVlanId", "defaultVlanId"), + ("apTagsAndVlanIds", "apTagsAndVlanIds"), + ("walledGardenEnabled", "walledGardenEnabled"), + ("walledGardenRanges", "walledGardenRanges"), + ("gre", "gre"), + ("radiusOverride", "radiusOverride"), + ("radiusGuestVlanEnabled", "radiusGuestVlanEnabled"), + ("radiusGuestVlanId", "radiusGuestVlanId"), + ("minBitrate", "minBitrate"), + ("bandSelection", "bandSelection"), + ("perClientBandwidthLimitUp", "perClientBandwidthLimitUp"), + ("perClientBandwidthLimitDown", "perClientBandwidthLimitDown"), + ("perSsidBandwidthLimitUp", "perSsidBandwidthLimitUp"), + ("perSsidBandwidthLimitDown", "perSsidBandwidthLimitDown"), + ("lanIsolationEnabled", "lanIsolationEnabled"), + ("visible", "visible"), + ("availableOnAllAps", "availableOnAllAps"), + ("availabilityTags", "availabilityTags"), + ("mandatoryDhcpEnabled", "mandatoryDhcpEnabled"), + ("adultContentFilteringEnabled", "adultContentFilteringEnabled"), + ("dnsRewrite", "dnsRewrite"), + ("speedBurst", "speedBurst"), + ("networkId", "networkId"), + ("number", "number"), + ] + # Method 1. Params present in request (Ansible) obj are the same as the current (ISE) params + # If any does not have eq params, it requires update + current_obj["number"] = str(current_obj.get("number")) + return any(not meraki_compare_equality(current_obj.get(meraki_param), + requested_obj.get(ansible_param)) + for (meraki_param, ansible_param) in obj_params) + + def update(self): + id = self.new_object.get("id") + id = id or self.new_object.get("number") + name = self.new_object.get("name") + result = None + if not id: + prev_obj_name = self.get_object_by_name(name) + id_ = None + if prev_obj_name: + id_ = prev_obj_name.get("id") + id_ = id_ or prev_obj_name.get("number") + if id_: + self.new_object.update(dict(number=id_)) + result = self.meraki.exec_meraki( + family="wireless", + function="updateNetworkWirelessSsid", + params=self.update_by_id_params(), + op_modifies=True, + ) + return result + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = False + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + meraki = MERAKI(self._task.args) + obj = NetworksWirelessSsids(self._task.args, meraki) + + state = self._task.args.get("state") + + response = None + if state == "present": + (obj_exists, prev_obj) = obj.exists() + if obj_exists: + if obj.requires_update(prev_obj): + response = obj.update() + meraki.object_updated() + else: + response = prev_obj + meraki.object_already_present() + else: + meraki.fail_json( + "Object does not exists, plugin only has update") + + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_wireless_ssids_bonjour_forwarding.py b/ansible_collections/cisco/meraki/plugins/action/networks_wireless_ssids_bonjour_forwarding.py new file mode 100644 index 000000000..43f69849a --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_wireless_ssids_bonjour_forwarding.py @@ -0,0 +1,213 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or +# https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, + meraki_compare_equality, + get_dict_result, +) +from ansible_collections.cisco.meraki.plugins.plugin_utils.exceptions import ( + InconsistentParameters, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + state=dict(type="str", default="present", choices=["present"]), + enabled=dict(type="bool"), + rules=dict(type="list"), + networkId=dict(type="str"), + number=dict(type="str"), +)) + +required_if = [ + ("state", "present", ["networkId", "number"], True), +] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class NetworksWirelessSsidsBonjourForwarding(object): + def __init__(self, params, meraki): + self.meraki = meraki + self.new_object = dict( + enabled=params.get("enabled"), + rules=params.get("rules"), + network_id=params.get("networkId"), + number=params.get("number"), + ) + + def get_all_params(self, name=None, id=None): + new_object_params = {} + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + if self.new_object.get('number') is not None or self.new_object.get('number') is not None: + new_object_params['number'] = self.new_object.get('number') + return new_object_params + + def update_all_params(self): + new_object_params = {} + if self.new_object.get('enabled') is not None or self.new_object.get('enabled') is not None: + new_object_params['enabled'] = self.new_object.get('enabled') + if self.new_object.get('rules') is not None or self.new_object.get('rules') is not None: + new_object_params['rules'] = self.new_object.get('rules') or \ + self.new_object.get('rules') + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + if self.new_object.get('number') is not None or self.new_object.get('number') is not None: + new_object_params['number'] = self.new_object.get('number') or \ + self.new_object.get('number') + return new_object_params + + def get_object_by_name(self, name): + result = None + # NOTE: Does not have a get by name method, using get all + try: + items = self.meraki.exec_meraki( + family="wireless", + function="getNetworkWirelessSsidBonjourForwarding", + params=self.get_all_params(name=name), + ) + if isinstance(items, dict): + if 'response' in items: + items = items.get('response') + result = get_dict_result(items, 'name', name) + if result is None: + result = items + except Exception as e: + print("Error: ", e) + result = None + return result + + def get_object_by_id(self, id): + result = None + # NOTE: Does not have a get by id method or it is in another action + return result + + def exists(self): + prev_obj = None + id_exists = False + name_exists = False + o_id = self.new_object.get("networkId") or self.new_object.get("network_id") + name = self.new_object.get("name") + if o_id: + prev_obj = self.get_object_by_name(o_id) + id_exists = prev_obj is not None and isinstance(prev_obj, dict) + if not id_exists and name: + prev_obj = self.get_object_by_name(name) + name_exists = prev_obj is not None and isinstance(prev_obj, dict) + if name_exists: + _id = prev_obj.get("id") + if id_exists and name_exists and o_id != _id: + raise InconsistentParameters( + "The 'id' and 'name' params don't refer to the same object") + if _id: + self.new_object.update(dict(id=_id)) + it_exists = prev_obj is not None and isinstance(prev_obj, dict) + return (it_exists, prev_obj) + + def requires_update(self, current_obj): + requested_obj = self.new_object + + obj_params = [ + ("enabled", "enabled"), + ("rules", "rules"), + ("networkId", "networkId"), + ("number", "number"), + ] + # Method 1. Params present in request (Ansible) obj are the same as the current (ISE) params + # If any does not have eq params, it requires update + return any(not meraki_compare_equality(current_obj.get(meraki_param), + requested_obj.get(ansible_param)) + for (meraki_param, ansible_param) in obj_params) + + def update(self): + id = self.new_object.get("id") + name = self.new_object.get("name") + result = None + result = self.meraki.exec_meraki( + family="wireless", + function="updateNetworkWirelessSsidBonjourForwarding", + params=self.update_all_params(), + op_modifies=True, + ) + return result + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = False + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + meraki = MERAKI(self._task.args) + obj = NetworksWirelessSsidsBonjourForwarding(self._task.args, meraki) + + state = self._task.args.get("state") + + response = None + if state == "present": + (obj_exists, prev_obj) = obj.exists() + if obj_exists: + if obj.requires_update(prev_obj): + response = obj.update() + meraki.object_updated() + else: + response = prev_obj + meraki.object_already_present() + else: + meraki.fail_json( + "Object does not exists, plugin only has update") + + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_wireless_ssids_bonjour_forwarding_info.py b/ansible_collections/cisco/meraki/plugins/action/networks_wireless_ssids_bonjour_forwarding_info.py new file mode 100644 index 000000000..e179abc98 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_wireless_ssids_bonjour_forwarding_info.py @@ -0,0 +1,94 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + networkId=dict(type="str"), + number=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_all(self, params): + new_object = {} + if params.get("networkId") is not None: + new_object["networkId"] = params.get( + "networkId") + if params.get("number") is not None: + new_object["number"] = params.get( + "number") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="wireless", + function='getNetworkWirelessSsidBonjourForwarding', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_wireless_ssids_device_type_group_policies.py b/ansible_collections/cisco/meraki/plugins/action/networks_wireless_ssids_device_type_group_policies.py new file mode 100644 index 000000000..7cc30fd3e --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_wireless_ssids_device_type_group_policies.py @@ -0,0 +1,213 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or +# https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, + meraki_compare_equality, + get_dict_result, +) +from ansible_collections.cisco.meraki.plugins.plugin_utils.exceptions import ( + InconsistentParameters, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + state=dict(type="str", default="present", choices=["present"]), + enabled=dict(type="bool"), + deviceTypePolicies=dict(type="list"), + networkId=dict(type="str"), + number=dict(type="str"), +)) + +required_if = [ + ("state", "present", ["networkId", "number"], True), +] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class NetworksWirelessSsidsDeviceTypeGroupPolicies(object): + def __init__(self, params, meraki): + self.meraki = meraki + self.new_object = dict( + enabled=params.get("enabled"), + deviceTypePolicies=params.get("deviceTypePolicies"), + network_id=params.get("networkId"), + number=params.get("number"), + ) + + def get_all_params(self, name=None, id=None): + new_object_params = {} + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + if self.new_object.get('number') is not None or self.new_object.get('number') is not None: + new_object_params['number'] = self.new_object.get('number') + return new_object_params + + def update_all_params(self): + new_object_params = {} + if self.new_object.get('enabled') is not None or self.new_object.get('enabled') is not None: + new_object_params['enabled'] = self.new_object.get('enabled') + if self.new_object.get('deviceTypePolicies') is not None or self.new_object.get('device_type_policies') is not None: + new_object_params['deviceTypePolicies'] = self.new_object.get('deviceTypePolicies') or \ + self.new_object.get('device_type_policies') + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + if self.new_object.get('number') is not None or self.new_object.get('number') is not None: + new_object_params['number'] = self.new_object.get('number') or \ + self.new_object.get('number') + return new_object_params + + def get_object_by_name(self, name): + result = None + # NOTE: Does not have a get by name method, using get all + try: + items = self.meraki.exec_meraki( + family="wireless", + function="getNetworkWirelessSsidDeviceTypeGroupPolicies", + params=self.get_all_params(name=name), + ) + if isinstance(items, dict): + if 'response' in items: + items = items.get('response') + result = get_dict_result(items, 'name', name) + if result is None: + result = items + except Exception as e: + print("Error: ", e) + result = None + return result + + def get_object_by_id(self, id): + result = None + # NOTE: Does not have a get by id method or it is in another action + return result + + def exists(self): + prev_obj = None + id_exists = False + name_exists = False + o_id = self.new_object.get("networkId") or self.new_object.get("network_id") + name = self.new_object.get("name") + if o_id: + prev_obj = self.get_object_by_name(o_id) + id_exists = prev_obj is not None and isinstance(prev_obj, dict) + if not id_exists and name: + prev_obj = self.get_object_by_name(name) + name_exists = prev_obj is not None and isinstance(prev_obj, dict) + if name_exists: + _id = prev_obj.get("id") + if id_exists and name_exists and o_id != _id: + raise InconsistentParameters( + "The 'id' and 'name' params don't refer to the same object") + if _id: + self.new_object.update(dict(id=_id)) + it_exists = prev_obj is not None and isinstance(prev_obj, dict) + return (it_exists, prev_obj) + + def requires_update(self, current_obj): + requested_obj = self.new_object + + obj_params = [ + ("enabled", "enabled"), + ("deviceTypePolicies", "deviceTypePolicies"), + ("networkId", "networkId"), + ("number", "number"), + ] + # Method 1. Params present in request (Ansible) obj are the same as the current (ISE) params + # If any does not have eq params, it requires update + return any(not meraki_compare_equality(current_obj.get(meraki_param), + requested_obj.get(ansible_param)) + for (meraki_param, ansible_param) in obj_params) + + def update(self): + id = self.new_object.get("id") + name = self.new_object.get("name") + result = None + result = self.meraki.exec_meraki( + family="wireless", + function="updateNetworkWirelessSsidDeviceTypeGroupPolicies", + params=self.update_all_params(), + op_modifies=True, + ) + return result + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = False + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + meraki = MERAKI(self._task.args) + obj = NetworksWirelessSsidsDeviceTypeGroupPolicies(self._task.args, meraki) + + state = self._task.args.get("state") + + response = None + if state == "present": + (obj_exists, prev_obj) = obj.exists() + if obj_exists: + if obj.requires_update(prev_obj): + response = obj.update() + meraki.object_updated() + else: + response = prev_obj + meraki.object_already_present() + else: + meraki.fail_json( + "Object does not exists, plugin only has update") + + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_wireless_ssids_device_type_group_policies_info.py b/ansible_collections/cisco/meraki/plugins/action/networks_wireless_ssids_device_type_group_policies_info.py new file mode 100644 index 000000000..fbc6c9b46 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_wireless_ssids_device_type_group_policies_info.py @@ -0,0 +1,94 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + networkId=dict(type="str"), + number=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_all(self, params): + new_object = {} + if params.get("networkId") is not None: + new_object["networkId"] = params.get( + "networkId") + if params.get("number") is not None: + new_object["number"] = params.get( + "number") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="wireless", + function='getNetworkWirelessSsidDeviceTypeGroupPolicies', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_wireless_ssids_eap_override.py b/ansible_collections/cisco/meraki/plugins/action/networks_wireless_ssids_eap_override.py new file mode 100644 index 000000000..d0e924aaa --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_wireless_ssids_eap_override.py @@ -0,0 +1,226 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or +# https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, + meraki_compare_equality, + get_dict_result, +) +from ansible_collections.cisco.meraki.plugins.plugin_utils.exceptions import ( + InconsistentParameters, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + state=dict(type="str", default="present", choices=["present"]), + timeout=dict(type="int"), + identity=dict(type="dict"), + maxRetries=dict(type="int"), + eapolKey=dict(type="dict"), + networkId=dict(type="str"), + number=dict(type="str"), +)) + +required_if = [ + ("state", "present", ["networkId", "number"], True), +] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class NetworksWirelessSsidsEapOverride(object): + def __init__(self, params, meraki): + self.meraki = meraki + self.new_object = dict( + timeout=params.get("timeout"), + identity=params.get("identity"), + maxRetries=params.get("maxRetries"), + eapolKey=params.get("eapolKey"), + network_id=params.get("networkId"), + number=params.get("number"), + ) + + def get_all_params(self, name=None, id=None): + new_object_params = {} + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + if self.new_object.get('number') is not None or self.new_object.get('number') is not None: + new_object_params['number'] = self.new_object.get('number') + return new_object_params + + def update_all_params(self): + new_object_params = {} + if self.new_object.get('timeout') is not None or self.new_object.get('timeout') is not None: + new_object_params['timeout'] = self.new_object.get('timeout') or \ + self.new_object.get('timeout') + if self.new_object.get('identity') is not None or self.new_object.get('identity') is not None: + new_object_params['identity'] = self.new_object.get('identity') or \ + self.new_object.get('identity') + if self.new_object.get('maxRetries') is not None or self.new_object.get('max_retries') is not None: + new_object_params['maxRetries'] = self.new_object.get('maxRetries') or \ + self.new_object.get('max_retries') + if self.new_object.get('eapolKey') is not None or self.new_object.get('eapol_key') is not None: + new_object_params['eapolKey'] = self.new_object.get('eapolKey') or \ + self.new_object.get('eapol_key') + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + if self.new_object.get('number') is not None or self.new_object.get('number') is not None: + new_object_params['number'] = self.new_object.get('number') or \ + self.new_object.get('number') + return new_object_params + + def get_object_by_name(self, name): + result = None + # NOTE: Does not have a get by name method, using get all + try: + items = self.meraki.exec_meraki( + family="wireless", + function="getNetworkWirelessSsidEapOverride", + params=self.get_all_params(name=name), + ) + if isinstance(items, dict): + if 'response' in items: + items = items.get('response') + result = get_dict_result(items, 'name', name) + if result is None: + result = items + except Exception as e: + print("Error: ", e) + result = None + return result + + def get_object_by_id(self, id): + result = None + # NOTE: Does not have a get by id method or it is in another action + return result + + def exists(self): + prev_obj = None + id_exists = False + name_exists = False + o_id = self.new_object.get("networkId") or self.new_object.get("network_id") + name = self.new_object.get("name") + if o_id: + prev_obj = self.get_object_by_name(o_id) + id_exists = prev_obj is not None and isinstance(prev_obj, dict) + if not id_exists and name: + prev_obj = self.get_object_by_name(name) + name_exists = prev_obj is not None and isinstance(prev_obj, dict) + if name_exists: + _id = prev_obj.get("id") + if id_exists and name_exists and o_id != _id: + raise InconsistentParameters( + "The 'id' and 'name' params don't refer to the same object") + if _id: + self.new_object.update(dict(id=_id)) + it_exists = prev_obj is not None and isinstance(prev_obj, dict) + return (it_exists, prev_obj) + + def requires_update(self, current_obj): + requested_obj = self.new_object + + obj_params = [ + ("timeout", "timeout"), + ("identity", "identity"), + ("maxRetries", "maxRetries"), + ("eapolKey", "eapolKey"), + ("networkId", "networkId"), + ("number", "number"), + ] + # Method 1. Params present in request (Ansible) obj are the same as the current (ISE) params + # If any does not have eq params, it requires update + return any(not meraki_compare_equality(current_obj.get(meraki_param), + requested_obj.get(ansible_param)) + for (meraki_param, ansible_param) in obj_params) + + def update(self): + id = self.new_object.get("id") + name = self.new_object.get("name") + result = None + result = self.meraki.exec_meraki( + family="wireless", + function="updateNetworkWirelessSsidEapOverride", + params=self.update_all_params(), + op_modifies=True, + ) + return result + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = False + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + meraki = MERAKI(self._task.args) + obj = NetworksWirelessSsidsEapOverride(self._task.args, meraki) + + state = self._task.args.get("state") + + response = None + if state == "present": + (obj_exists, prev_obj) = obj.exists() + if obj_exists: + if obj.requires_update(prev_obj): + response = obj.update() + meraki.object_updated() + else: + response = prev_obj + meraki.object_already_present() + else: + meraki.fail_json( + "Object does not exists, plugin only has update") + + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_wireless_ssids_eap_override_info.py b/ansible_collections/cisco/meraki/plugins/action/networks_wireless_ssids_eap_override_info.py new file mode 100644 index 000000000..9b4108989 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_wireless_ssids_eap_override_info.py @@ -0,0 +1,94 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + networkId=dict(type="str"), + number=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_all(self, params): + new_object = {} + if params.get("networkId") is not None: + new_object["networkId"] = params.get( + "networkId") + if params.get("number") is not None: + new_object["number"] = params.get( + "number") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="wireless", + function='getNetworkWirelessSsidEapOverride', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_wireless_ssids_firewall_l3_firewall_rules.py b/ansible_collections/cisco/meraki/plugins/action/networks_wireless_ssids_firewall_l3_firewall_rules.py new file mode 100644 index 000000000..178967038 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_wireless_ssids_firewall_l3_firewall_rules.py @@ -0,0 +1,213 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or +# https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, + meraki_compare_equality, + get_dict_result, +) +from ansible_collections.cisco.meraki.plugins.plugin_utils.exceptions import ( + InconsistentParameters, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + state=dict(type="str", default="present", choices=["present"]), + rules=dict(type="list"), + allowLanAccess=dict(type="bool"), + networkId=dict(type="str"), + number=dict(type="str"), +)) + +required_if = [ + ("state", "present", ["networkId", "number"], True), +] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class NetworksWirelessSsidsFirewallL3FirewallRules(object): + def __init__(self, params, meraki): + self.meraki = meraki + self.new_object = dict( + rules=params.get("rules"), + allowLanAccess=params.get("allowLanAccess"), + network_id=params.get("networkId"), + number=params.get("number"), + ) + + def get_all_params(self, name=None, id=None): + new_object_params = {} + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + if self.new_object.get('number') is not None or self.new_object.get('number') is not None: + new_object_params['number'] = self.new_object.get('number') + return new_object_params + + def update_all_params(self): + new_object_params = {} + if self.new_object.get('rules') is not None or self.new_object.get('rules') is not None: + new_object_params['rules'] = self.new_object.get('rules') or \ + self.new_object.get('rules') + if self.new_object.get('allowLanAccess') is not None or self.new_object.get('allow_lan_access') is not None: + new_object_params['allowLanAccess'] = self.new_object.get('allowLanAccess') + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + if self.new_object.get('number') is not None or self.new_object.get('number') is not None: + new_object_params['number'] = self.new_object.get('number') or \ + self.new_object.get('number') + return new_object_params + + def get_object_by_name(self, name): + result = None + # NOTE: Does not have a get by name method, using get all + try: + items = self.meraki.exec_meraki( + family="wireless", + function="getNetworkWirelessSsidFirewallL3FirewallRules", + params=self.get_all_params(name=name), + ) + if isinstance(items, dict): + if 'response' in items: + items = items.get('response') + result = get_dict_result(items, 'name', name) + if result is None: + result = items + except Exception as e: + print("Error: ", e) + result = None + return result + + def get_object_by_id(self, id): + result = None + # NOTE: Does not have a get by id method or it is in another action + return result + + def exists(self): + prev_obj = None + id_exists = False + name_exists = False + o_id = self.new_object.get("networkId") or self.new_object.get("network_id") + name = self.new_object.get("name") + if o_id: + prev_obj = self.get_object_by_name(o_id) + id_exists = prev_obj is not None and isinstance(prev_obj, dict) + if not id_exists and name: + prev_obj = self.get_object_by_name(name) + name_exists = prev_obj is not None and isinstance(prev_obj, dict) + if name_exists: + _id = prev_obj.get("id") + if id_exists and name_exists and o_id != _id: + raise InconsistentParameters( + "The 'id' and 'name' params don't refer to the same object") + if _id: + self.new_object.update(dict(id=_id)) + it_exists = prev_obj is not None and isinstance(prev_obj, dict) + return (it_exists, prev_obj) + + def requires_update(self, current_obj): + requested_obj = self.new_object + + obj_params = [ + ("rules", "rules"), + ("allowLanAccess", "allowLanAccess"), + ("networkId", "networkId"), + ("number", "number"), + ] + # Method 1. Params present in request (Ansible) obj are the same as the current (ISE) params + # If any does not have eq params, it requires update + return any(not meraki_compare_equality(current_obj.get(meraki_param), + requested_obj.get(ansible_param)) + for (meraki_param, ansible_param) in obj_params) + + def update(self): + id = self.new_object.get("id") + name = self.new_object.get("name") + result = None + result = self.meraki.exec_meraki( + family="wireless", + function="updateNetworkWirelessSsidFirewallL3FirewallRules", + params=self.update_all_params(), + op_modifies=True, + ) + return result + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = False + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + meraki = MERAKI(self._task.args) + obj = NetworksWirelessSsidsFirewallL3FirewallRules(self._task.args, meraki) + + state = self._task.args.get("state") + + response = None + if state == "present": + (obj_exists, prev_obj) = obj.exists() + if obj_exists: + if obj.requires_update(prev_obj): + response = obj.update() + meraki.object_updated() + else: + response = prev_obj + meraki.object_already_present() + else: + meraki.fail_json( + "Object does not exists, plugin only has update") + + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_wireless_ssids_firewall_l3_firewall_rules_info.py b/ansible_collections/cisco/meraki/plugins/action/networks_wireless_ssids_firewall_l3_firewall_rules_info.py new file mode 100644 index 000000000..c3533bd86 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_wireless_ssids_firewall_l3_firewall_rules_info.py @@ -0,0 +1,94 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + networkId=dict(type="str"), + number=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_all(self, params): + new_object = {} + if params.get("networkId") is not None: + new_object["networkId"] = params.get( + "networkId") + if params.get("number") is not None: + new_object["number"] = params.get( + "number") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="wireless", + function='getNetworkWirelessSsidFirewallL3FirewallRules', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_wireless_ssids_firewall_l7_firewall_rules.py b/ansible_collections/cisco/meraki/plugins/action/networks_wireless_ssids_firewall_l7_firewall_rules.py new file mode 100644 index 000000000..cdfe8174b --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_wireless_ssids_firewall_l7_firewall_rules.py @@ -0,0 +1,208 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or +# https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, + meraki_compare_equality, + get_dict_result, +) +from ansible_collections.cisco.meraki.plugins.plugin_utils.exceptions import ( + InconsistentParameters, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + state=dict(type="str", default="present", choices=["present"]), + rules=dict(type="list"), + networkId=dict(type="str"), + number=dict(type="str"), +)) + +required_if = [ + ("state", "present", ["networkId", "number"], True), +] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class NetworksWirelessSsidsFirewallL7FirewallRules(object): + def __init__(self, params, meraki): + self.meraki = meraki + self.new_object = dict( + rules=params.get("rules"), + network_id=params.get("networkId"), + number=params.get("number"), + ) + + def get_all_params(self, name=None, id=None): + new_object_params = {} + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + if self.new_object.get('number') is not None or self.new_object.get('number') is not None: + new_object_params['number'] = self.new_object.get('number') + return new_object_params + + def update_all_params(self): + new_object_params = {} + if self.new_object.get('rules') is not None or self.new_object.get('rules') is not None: + new_object_params['rules'] = self.new_object.get('rules') or \ + self.new_object.get('rules') + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + if self.new_object.get('number') is not None or self.new_object.get('number') is not None: + new_object_params['number'] = self.new_object.get('number') or \ + self.new_object.get('number') + return new_object_params + + def get_object_by_name(self, name): + result = None + # NOTE: Does not have a get by name method, using get all + try: + items = self.meraki.exec_meraki( + family="wireless", + function="getNetworkWirelessSsidFirewallL7FirewallRules", + params=self.get_all_params(name=name), + ) + if isinstance(items, dict): + if 'response' in items: + items = items.get('response') + result = get_dict_result(items, 'name', name) + if result is None: + result = items + except Exception as e: + print("Error: ", e) + result = None + return result + + def get_object_by_id(self, id): + result = None + # NOTE: Does not have a get by id method or it is in another action + return result + + def exists(self): + prev_obj = None + id_exists = False + name_exists = False + o_id = self.new_object.get("networkId") or self.new_object.get("network_id") + name = self.new_object.get("name") + if o_id: + prev_obj = self.get_object_by_name(o_id) + id_exists = prev_obj is not None and isinstance(prev_obj, dict) + if not id_exists and name: + prev_obj = self.get_object_by_name(name) + name_exists = prev_obj is not None and isinstance(prev_obj, dict) + if name_exists: + _id = prev_obj.get("id") + if id_exists and name_exists and o_id != _id: + raise InconsistentParameters( + "The 'id' and 'name' params don't refer to the same object") + if _id: + self.new_object.update(dict(id=_id)) + it_exists = prev_obj is not None and isinstance(prev_obj, dict) + return (it_exists, prev_obj) + + def requires_update(self, current_obj): + requested_obj = self.new_object + + obj_params = [ + ("rules", "rules"), + ("networkId", "networkId"), + ("number", "number"), + ] + # Method 1. Params present in request (Ansible) obj are the same as the current (ISE) params + # If any does not have eq params, it requires update + return any(not meraki_compare_equality(current_obj.get(meraki_param), + requested_obj.get(ansible_param)) + for (meraki_param, ansible_param) in obj_params) + + def update(self): + id = self.new_object.get("id") + name = self.new_object.get("name") + result = None + result = self.meraki.exec_meraki( + family="wireless", + function="updateNetworkWirelessSsidFirewallL7FirewallRules", + params=self.update_all_params(), + op_modifies=True, + ) + return result + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = False + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + meraki = MERAKI(self._task.args) + obj = NetworksWirelessSsidsFirewallL7FirewallRules(self._task.args, meraki) + + state = self._task.args.get("state") + + response = None + if state == "present": + (obj_exists, prev_obj) = obj.exists() + if obj_exists: + if obj.requires_update(prev_obj): + response = obj.update() + meraki.object_updated() + else: + response = prev_obj + meraki.object_already_present() + else: + meraki.fail_json( + "Object does not exists, plugin only has update") + + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_wireless_ssids_firewall_l7_firewall_rules_info.py b/ansible_collections/cisco/meraki/plugins/action/networks_wireless_ssids_firewall_l7_firewall_rules_info.py new file mode 100644 index 000000000..82b4d6518 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_wireless_ssids_firewall_l7_firewall_rules_info.py @@ -0,0 +1,94 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + networkId=dict(type="str"), + number=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_all(self, params): + new_object = {} + if params.get("networkId") is not None: + new_object["networkId"] = params.get( + "networkId") + if params.get("number") is not None: + new_object["number"] = params.get( + "number") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="wireless", + function='getNetworkWirelessSsidFirewallL7FirewallRules', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_wireless_ssids_hotspot20.py b/ansible_collections/cisco/meraki/plugins/action/networks_wireless_ssids_hotspot20.py new file mode 100644 index 000000000..553ea6544 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_wireless_ssids_hotspot20.py @@ -0,0 +1,249 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or +# https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, + meraki_compare_equality, + get_dict_result, +) +from ansible_collections.cisco.meraki.plugins.plugin_utils.exceptions import ( + InconsistentParameters, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + state=dict(type="str", default="present", choices=["present"]), + enabled=dict(type="bool"), + operator=dict(type="dict"), + venue=dict(type="dict"), + networkAccessType=dict(type="str"), + domains=dict(type="list"), + roamConsortOis=dict(type="list"), + mccMncs=dict(type="list"), + naiRealms=dict(type="list"), + networkId=dict(type="str"), + number=dict(type="str"), +)) + +required_if = [ + ("state", "present", ["networkId", "number"], True), +] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class NetworksWirelessSsidsHotspot20(object): + def __init__(self, params, meraki): + self.meraki = meraki + self.new_object = dict( + enabled=params.get("enabled"), + operator=params.get("operator"), + venue=params.get("venue"), + networkAccessType=params.get("networkAccessType"), + domains=params.get("domains"), + roamConsortOis=params.get("roamConsortOis"), + mccMncs=params.get("mccMncs"), + naiRealms=params.get("naiRealms"), + network_id=params.get("networkId"), + number=params.get("number"), + ) + + def get_all_params(self, name=None, id=None): + new_object_params = {} + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + if self.new_object.get('number') is not None or self.new_object.get('number') is not None: + new_object_params['number'] = self.new_object.get('number') + return new_object_params + + def update_all_params(self): + new_object_params = {} + if self.new_object.get('enabled') is not None or self.new_object.get('enabled') is not None: + new_object_params['enabled'] = self.new_object.get('enabled') + if self.new_object.get('operator') is not None or self.new_object.get('operator') is not None: + new_object_params['operator'] = self.new_object.get('operator') or \ + self.new_object.get('operator') + if self.new_object.get('venue') is not None or self.new_object.get('venue') is not None: + new_object_params['venue'] = self.new_object.get('venue') or \ + self.new_object.get('venue') + if self.new_object.get('networkAccessType') is not None or self.new_object.get('network_access_type') is not None: + new_object_params['networkAccessType'] = self.new_object.get('networkAccessType') or \ + self.new_object.get('network_access_type') + if self.new_object.get('domains') is not None or self.new_object.get('domains') is not None: + new_object_params['domains'] = self.new_object.get('domains') or \ + self.new_object.get('domains') + if self.new_object.get('roamConsortOis') is not None or self.new_object.get('roam_consort_ois') is not None: + new_object_params['roamConsortOis'] = self.new_object.get('roamConsortOis') or \ + self.new_object.get('roam_consort_ois') + if self.new_object.get('mccMncs') is not None or self.new_object.get('mcc_mncs') is not None: + new_object_params['mccMncs'] = self.new_object.get('mccMncs') or \ + self.new_object.get('mcc_mncs') + if self.new_object.get('naiRealms') is not None or self.new_object.get('nai_realms') is not None: + new_object_params['naiRealms'] = self.new_object.get('naiRealms') or \ + self.new_object.get('nai_realms') + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + if self.new_object.get('number') is not None or self.new_object.get('number') is not None: + new_object_params['number'] = self.new_object.get('number') or \ + self.new_object.get('number') + return new_object_params + + def get_object_by_name(self, name): + result = None + # NOTE: Does not have a get by name method, using get all + try: + items = self.meraki.exec_meraki( + family="wireless", + function="getNetworkWirelessSsidHotspot20", + params=self.get_all_params(name=name), + ) + if isinstance(items, dict): + if 'response' in items: + items = items.get('response') + result = get_dict_result(items, 'name', name) + if result is None: + result = items + except Exception as e: + print("Error: ", e) + result = None + return result + + def get_object_by_id(self, id): + result = None + # NOTE: Does not have a get by id method or it is in another action + return result + + def exists(self): + prev_obj = None + id_exists = False + name_exists = False + o_id = self.new_object.get("networkId") or self.new_object.get("network_id") + name = self.new_object.get("name") + if o_id: + prev_obj = self.get_object_by_name(o_id) + id_exists = prev_obj is not None and isinstance(prev_obj, dict) + if not id_exists and name: + prev_obj = self.get_object_by_name(name) + name_exists = prev_obj is not None and isinstance(prev_obj, dict) + if name_exists: + _id = prev_obj.get("id") + if id_exists and name_exists and o_id != _id: + raise InconsistentParameters( + "The 'id' and 'name' params don't refer to the same object") + if _id: + self.new_object.update(dict(id=_id)) + it_exists = prev_obj is not None and isinstance(prev_obj, dict) + return (it_exists, prev_obj) + + def requires_update(self, current_obj): + requested_obj = self.new_object + + obj_params = [ + ("enabled", "enabled"), + ("operator", "operator"), + ("venue", "venue"), + ("networkAccessType", "networkAccessType"), + ("domains", "domains"), + ("roamConsortOis", "roamConsortOis"), + ("mccMncs", "mccMncs"), + ("naiRealms", "naiRealms"), + ("networkId", "networkId"), + ("number", "number"), + ] + # Method 1. Params present in request (Ansible) obj are the same as the current (ISE) params + # If any does not have eq params, it requires update + return any(not meraki_compare_equality(current_obj.get(meraki_param), + requested_obj.get(ansible_param)) + for (meraki_param, ansible_param) in obj_params) + + def update(self): + id = self.new_object.get("id") + name = self.new_object.get("name") + result = None + result = self.meraki.exec_meraki( + family="wireless", + function="updateNetworkWirelessSsidHotspot20", + params=self.update_all_params(), + op_modifies=True, + ) + return result + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = False + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + meraki = MERAKI(self._task.args) + obj = NetworksWirelessSsidsHotspot20(self._task.args, meraki) + + state = self._task.args.get("state") + + response = None + if state == "present": + (obj_exists, prev_obj) = obj.exists() + if obj_exists: + if obj.requires_update(prev_obj): + response = obj.update() + meraki.object_updated() + else: + response = prev_obj + meraki.object_already_present() + else: + meraki.fail_json( + "Object does not exists, plugin only has update") + + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_wireless_ssids_hotspot20_info.py b/ansible_collections/cisco/meraki/plugins/action/networks_wireless_ssids_hotspot20_info.py new file mode 100644 index 000000000..ba9f6e805 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_wireless_ssids_hotspot20_info.py @@ -0,0 +1,94 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + networkId=dict(type="str"), + number=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_all(self, params): + new_object = {} + if params.get("networkId") is not None: + new_object["networkId"] = params.get( + "networkId") + if params.get("number") is not None: + new_object["number"] = params.get( + "number") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="wireless", + function='getNetworkWirelessSsidHotspot20', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_wireless_ssids_identity_psks.py b/ansible_collections/cisco/meraki/plugins/action/networks_wireless_ssids_identity_psks.py new file mode 100644 index 000000000..266306851 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_wireless_ssids_identity_psks.py @@ -0,0 +1,345 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or +# https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, + meraki_compare_equality, + get_dict_result, +) +from ansible_collections.cisco.meraki.plugins.plugin_utils.exceptions import ( + InconsistentParameters, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + state=dict(type="str", default="present", choices=["present", "absent"]), + name=dict(type="str"), + passphrase=dict(type="str"), + groupPolicyId=dict(type="str"), + expiresAt=dict(type="str"), + networkId=dict(type="str"), + number=dict(type="str"), + identityPskId=dict(type="str"), +)) + +required_if = [ + ("state", "present", ["identityPskId", "name", "networkId", "number"], True), + ("state", "absent", ["identityPskId", "name", "networkId", "number"], True), +] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class NetworksWirelessSsidsIdentityPsks(object): + def __init__(self, params, meraki): + self.meraki = meraki + self.new_object = dict( + name=params.get("name"), + passphrase=params.get("passphrase"), + groupPolicyId=params.get("groupPolicyId"), + expiresAt=params.get("expiresAt"), + networkId=params.get("networkId"), + number=params.get("number"), + identityPskId=params.get("identityPskId"), + ) + + def get_all_params(self, name=None, id=None): + new_object_params = {} + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + if self.new_object.get('number') is not None or self.new_object.get('number') is not None: + new_object_params['number'] = self.new_object.get('number') + return new_object_params + + def get_params_by_id(self, name=None, id=None): + new_object_params = {} + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + if self.new_object.get('number') is not None or self.new_object.get('number') is not None: + new_object_params['number'] = self.new_object.get('number') + if self.new_object.get('identityPskId') is not None or self.new_object.get('identity_psk_id') is not None: + new_object_params['identityPskId'] = self.new_object.get('identityPskId') or \ + self.new_object.get('identity_psk_id') + return new_object_params + + def create_params(self): + new_object_params = {} + if self.new_object.get('name') is not None or self.new_object.get('name') is not None: + new_object_params['name'] = self.new_object.get('name') or \ + self.new_object.get('name') + if self.new_object.get('passphrase') is not None or self.new_object.get('passphrase') is not None: + new_object_params['passphrase'] = self.new_object.get('passphrase') or \ + self.new_object.get('passphrase') + if self.new_object.get('groupPolicyId') is not None or self.new_object.get('group_policy_id') is not None: + new_object_params['groupPolicyId'] = self.new_object.get('groupPolicyId') or \ + self.new_object.get('group_policy_id') + if self.new_object.get('expiresAt') is not None or self.new_object.get('expires_at') is not None: + new_object_params['expiresAt'] = self.new_object.get('expiresAt') or \ + self.new_object.get('expires_at') + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + if self.new_object.get('number') is not None or self.new_object.get('number') is not None: + new_object_params['number'] = self.new_object.get('number') or \ + self.new_object.get('number') + return new_object_params + + def delete_by_id_params(self): + new_object_params = {} + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + if self.new_object.get('number') is not None or self.new_object.get('number') is not None: + new_object_params['number'] = self.new_object.get('number') or \ + self.new_object.get('number') + if self.new_object.get('identityPskId') is not None or self.new_object.get('identity_psk_id') is not None: + new_object_params['identityPskId'] = self.new_object.get('identityPskId') or \ + self.new_object.get('identity_psk_id') + return new_object_params + + def update_by_id_params(self): + new_object_params = {} + if self.new_object.get('name') is not None or self.new_object.get('name') is not None: + new_object_params['name'] = self.new_object.get('name') or \ + self.new_object.get('name') + if self.new_object.get('passphrase') is not None or self.new_object.get('passphrase') is not None: + new_object_params['passphrase'] = self.new_object.get('passphrase') or \ + self.new_object.get('passphrase') + if self.new_object.get('groupPolicyId') is not None or self.new_object.get('group_policy_id') is not None: + new_object_params['groupPolicyId'] = self.new_object.get('groupPolicyId') or \ + self.new_object.get('group_policy_id') + if self.new_object.get('expiresAt') is not None or self.new_object.get('expires_at') is not None: + new_object_params['expiresAt'] = self.new_object.get('expiresAt') or \ + self.new_object.get('expires_at') + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + if self.new_object.get('number') is not None or self.new_object.get('number') is not None: + new_object_params['number'] = self.new_object.get('number') or \ + self.new_object.get('number') + if self.new_object.get('identityPskId') is not None or self.new_object.get('identity_psk_id') is not None: + new_object_params['identityPskId'] = self.new_object.get('identityPskId') or \ + self.new_object.get('identity_psk_id') + return new_object_params + + def get_object_by_name(self, name): + result = None + # NOTE: Does not have a get by name method or it is in another action + try: + items = self.meraki.exec_meraki( + family="wireless", + function="getNetworkWirelessSsidIdentityPsks", + params=self.get_all_params(name=name), + ) + if isinstance(items, dict): + if 'response' in items: + items = items.get('response') + result = get_dict_result(items, 'name', name) + if result is None: + result = items + except Exception as e: + print("Error: ", e) + result = None + return result + + def get_object_by_id(self, id): + result = None + try: + items = self.meraki.exec_meraki( + family="wireless", + function="getNetworkWirelessSsidIdentityPsk", + params=self.get_params_by_id() + ) + if isinstance(items, dict): + if 'response' in items: + items = items.get('response') + result = get_dict_result(items, 'identityPskId', id) + except Exception as e: + print("Error: ", e) + result = None + return result + + def exists(self): + id_exists = False + name_exists = False + prev_obj = None + o_id = self.new_object.get("id") + o_id = o_id or self.new_object.get( + "identity_psk_id") or self.new_object.get("identityPskId") + name = self.new_object.get("name") + if o_id: + prev_obj = self.get_object_by_id(o_id) + id_exists = prev_obj is not None and isinstance(prev_obj, dict) + if not id_exists and name: + prev_obj = self.get_object_by_name(name) + name_exists = prev_obj is not None and isinstance(prev_obj, dict) + if name_exists: + _id = prev_obj.get("id") + _id = _id or prev_obj.get("identityPskId") + if id_exists and name_exists and o_id != _id: + raise InconsistentParameters( + "The 'id' and 'name' params don't refer to the same object") + if _id: + self.new_object.update(dict(id=_id)) + self.new_object.update(dict(identityPskId=_id)) + if _id: + prev_obj = self.get_object_by_id(_id) + it_exists = prev_obj is not None and isinstance(prev_obj, dict) + return (it_exists, prev_obj) + + def requires_update(self, current_obj): + requested_obj = self.new_object + + obj_params = [ + ("name", "name"), + ("passphrase", "passphrase"), + ("groupPolicyId", "groupPolicyId"), + ("expiresAt", "expiresAt"), + ("networkId", "networkId"), + ("number", "number"), + ("identityPskId", "identityPskId"), + ] + # Method 1. Params present in request (Ansible) obj are the same as the current (DNAC) params + # If any does not have eq params, it requires update + return any(not meraki_compare_equality(current_obj.get(meraki_param), + requested_obj.get(ansible_param)) + for (meraki_param, ansible_param) in obj_params) + + def create(self): + result = self.meraki.exec_meraki( + family="wireless", + function="createNetworkWirelessSsidIdentityPsk", + params=self.create_params(), + op_modifies=True, + ) + return result + + def update(self): + id = self.new_object.get("id") + id = id or self.new_object.get("identityPskId") + name = self.new_object.get("name") + result = None + if not id: + prev_obj_name = self.get_object_by_name(name) + id_ = None + if prev_obj_name: + id_ = prev_obj_name.get("id") + id_ = id_ or prev_obj_name.get("identityPskId") + if id_: + self.new_object.update(dict(identityPskId=id_)) + result = self.meraki.exec_meraki( + family="wireless", + function="updateNetworkWirelessSsidIdentityPsk", + params=self.update_by_id_params(), + op_modifies=True, + ) + return result + + def delete(self): + id = self.new_object.get("id") + id = id or self.new_object.get("identityPskId") + name = self.new_object.get("name") + result = None + if not id: + prev_obj_name = self.get_object_by_name(name) + id_ = None + if prev_obj_name: + id_ = prev_obj_name.get("id") + id_ = id_ or prev_obj_name.get("identityPskId") + if id_: + self.new_object.update(dict(identityPskId=id_)) + result = self.meraki.exec_meraki( + family="wireless", + function="deleteNetworkWirelessSsidIdentityPsk", + params=self.delete_by_id_params(), + ) + return result + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = False + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + meraki = MERAKI(self._task.args) + obj = NetworksWirelessSsidsIdentityPsks(self._task.args, meraki) + + state = self._task.args.get("state") + + response = None + + if state == "present": + (obj_exists, prev_obj) = obj.exists() + if obj_exists: + if obj.requires_update(prev_obj): + response = obj.update() + meraki.object_updated() + else: + response = prev_obj + meraki.object_already_present() + else: + response = obj.create() + meraki.object_created() + + elif state == "absent": + (obj_exists, prev_obj) = obj.exists() + if obj_exists: + response = obj.delete() + meraki.object_deleted() + else: + meraki.object_already_absent() + + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_wireless_ssids_identity_psks_info.py b/ansible_collections/cisco/meraki/plugins/action/networks_wireless_ssids_identity_psks_info.py new file mode 100644 index 000000000..9ff5341fa --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_wireless_ssids_identity_psks_info.py @@ -0,0 +1,119 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + networkId=dict(type="str"), + number=dict(type="str"), + identityPskId=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_object(self, params): + new_object = {} + if params.get("networkId") is not None: + new_object["networkId"] = params.get( + "networkId") + if params.get("number") is not None: + new_object["number"] = params.get( + "number") + if params.get("identityPskId") is not None: + new_object["identityPskId"] = params.get( + "identityPskId") + return new_object + + def get_all(self, params): + new_object = {} + if params.get("networkId") is not None: + new_object["networkId"] = params.get( + "networkId") + if params.get("number") is not None: + new_object["number"] = params.get( + "number") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + id = self._task.args.get("identityPskId") + if id: + response = meraki.exec_meraki( + family="wireless", + function='getNetworkWirelessSsidIdentityPsk', + params=self.get_object(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result + if not id: + response = meraki.exec_meraki( + family="wireless", + function='getNetworkWirelessSsidIdentityPsks', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_wireless_ssids_info.py b/ansible_collections/cisco/meraki/plugins/action/networks_wireless_ssids_info.py new file mode 100644 index 000000000..c75f4a5cc --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_wireless_ssids_info.py @@ -0,0 +1,112 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + networkId=dict(type="str"), + number=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_object(self, params): + new_object = {} + if params.get("networkId") is not None: + new_object["networkId"] = params.get( + "networkId") + if params.get("number") is not None: + new_object["number"] = params.get( + "number") + return new_object + + def get_all(self, params): + new_object = {} + if params.get("networkId") is not None: + new_object["networkId"] = params.get( + "networkId") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + id = self._task.args.get("number") + if id: + response = meraki.exec_meraki( + family="wireless", + function='getNetworkWirelessSsid', + params=self.get_object(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result + if not id: + response = meraki.exec_meraki( + family="wireless", + function='getNetworkWirelessSsids', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_wireless_ssids_schedules.py b/ansible_collections/cisco/meraki/plugins/action/networks_wireless_ssids_schedules.py new file mode 100644 index 000000000..c37530db3 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_wireless_ssids_schedules.py @@ -0,0 +1,219 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or +# https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, + meraki_compare_equality, + get_dict_result, +) +from ansible_collections.cisco.meraki.plugins.plugin_utils.exceptions import ( + InconsistentParameters, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + state=dict(type="str", default="present", choices=["present"]), + enabled=dict(type="bool"), + ranges=dict(type="list"), + rangesInSeconds=dict(type="list"), + networkId=dict(type="str"), + number=dict(type="str"), +)) + +required_if = [ + ("state", "present", ["networkId", "number"], True), +] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class NetworksWirelessSsidsSchedules(object): + def __init__(self, params, meraki): + self.meraki = meraki + self.new_object = dict( + enabled=params.get("enabled"), + ranges=params.get("ranges"), + rangesInSeconds=params.get("rangesInSeconds"), + network_id=params.get("networkId"), + number=params.get("number"), + ) + + def get_all_params(self, name=None, id=None): + new_object_params = {} + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + if self.new_object.get('number') is not None or self.new_object.get('number') is not None: + new_object_params['number'] = self.new_object.get('number') + return new_object_params + + def update_all_params(self): + new_object_params = {} + if self.new_object.get('enabled') is not None or self.new_object.get('enabled') is not None: + new_object_params['enabled'] = self.new_object.get('enabled') + if self.new_object.get('ranges') is not None or self.new_object.get('ranges') is not None: + new_object_params['ranges'] = self.new_object.get('ranges') or \ + self.new_object.get('ranges') + if self.new_object.get('rangesInSeconds') is not None or self.new_object.get('ranges_in_seconds') is not None: + new_object_params['rangesInSeconds'] = self.new_object.get('rangesInSeconds') or \ + self.new_object.get('ranges_in_seconds') + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + if self.new_object.get('number') is not None or self.new_object.get('number') is not None: + new_object_params['number'] = self.new_object.get('number') or \ + self.new_object.get('number') + return new_object_params + + def get_object_by_name(self, name): + result = None + # NOTE: Does not have a get by name method, using get all + try: + items = self.meraki.exec_meraki( + family="wireless", + function="getNetworkWirelessSsidSchedules", + params=self.get_all_params(name=name), + ) + if isinstance(items, dict): + if 'response' in items: + items = items.get('response') + result = get_dict_result(items, 'name', name) + if result is None: + result = items + except Exception as e: + print("Error: ", e) + result = None + return result + + def get_object_by_id(self, id): + result = None + # NOTE: Does not have a get by id method or it is in another action + return result + + def exists(self): + prev_obj = None + id_exists = False + name_exists = False + o_id = self.new_object.get("networkId") or self.new_object.get("network_id") + name = self.new_object.get("name") + if o_id: + prev_obj = self.get_object_by_name(o_id) + id_exists = prev_obj is not None and isinstance(prev_obj, dict) + if not id_exists and name: + prev_obj = self.get_object_by_name(name) + name_exists = prev_obj is not None and isinstance(prev_obj, dict) + if name_exists: + _id = prev_obj.get("id") + if id_exists and name_exists and o_id != _id: + raise InconsistentParameters( + "The 'id' and 'name' params don't refer to the same object") + if _id: + self.new_object.update(dict(id=_id)) + it_exists = prev_obj is not None and isinstance(prev_obj, dict) + return (it_exists, prev_obj) + + def requires_update(self, current_obj): + requested_obj = self.new_object + + obj_params = [ + ("enabled", "enabled"), + ("ranges", "ranges"), + ("rangesInSeconds", "rangesInSeconds"), + ("networkId", "networkId"), + ("number", "number"), + ] + # Method 1. Params present in request (Ansible) obj are the same as the current (ISE) params + # If any does not have eq params, it requires update + return any(not meraki_compare_equality(current_obj.get(meraki_param), + requested_obj.get(ansible_param)) + for (meraki_param, ansible_param) in obj_params) + + def update(self): + id = self.new_object.get("id") + name = self.new_object.get("name") + result = None + result = self.meraki.exec_meraki( + family="wireless", + function="updateNetworkWirelessSsidSchedules", + params=self.update_all_params(), + op_modifies=True, + ) + return result + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = False + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + meraki = MERAKI(self._task.args) + obj = NetworksWirelessSsidsSchedules(self._task.args, meraki) + + state = self._task.args.get("state") + + response = None + if state == "present": + (obj_exists, prev_obj) = obj.exists() + if obj_exists: + if obj.requires_update(prev_obj): + response = obj.update() + meraki.object_updated() + else: + response = prev_obj + meraki.object_already_present() + else: + meraki.fail_json( + "Object does not exists, plugin only has update") + + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_wireless_ssids_schedules_info.py b/ansible_collections/cisco/meraki/plugins/action/networks_wireless_ssids_schedules_info.py new file mode 100644 index 000000000..67e4a6c1c --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_wireless_ssids_schedules_info.py @@ -0,0 +1,94 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + networkId=dict(type="str"), + number=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_all(self, params): + new_object = {} + if params.get("networkId") is not None: + new_object["networkId"] = params.get( + "networkId") + if params.get("number") is not None: + new_object["number"] = params.get( + "number") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="wireless", + function='getNetworkWirelessSsidSchedules', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_wireless_ssids_splash_settings.py b/ansible_collections/cisco/meraki/plugins/action/networks_wireless_ssids_splash_settings.py new file mode 100644 index 000000000..71989ade2 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_wireless_ssids_splash_settings.py @@ -0,0 +1,288 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or +# https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, + meraki_compare_equality, + get_dict_result, +) +from ansible_collections.cisco.meraki.plugins.plugin_utils.exceptions import ( + InconsistentParameters, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + state=dict(type="str", default="present", choices=["present"]), + splashUrl=dict(type="str"), + useSplashUrl=dict(type="bool"), + splashTimeout=dict(type="int"), + redirectUrl=dict(type="str"), + useRedirectUrl=dict(type="bool"), + welcomeMessage=dict(type="str"), + splashLogo=dict(type="dict"), + splashImage=dict(type="dict"), + splashPrepaidFront=dict(type="dict"), + blockAllTrafficBeforeSignOn=dict(type="bool"), + controllerDisconnectionBehavior=dict(type="str"), + allowSimultaneousLogins=dict(type="bool"), + guestSponsorship=dict(type="dict"), + billing=dict(type="dict"), + sentryEnrollment=dict(type="dict"), + networkId=dict(type="str"), + number=dict(type="str"), +)) + +required_if = [ + ("state", "present", ["networkId", "number"], True), +] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class NetworksWirelessSsidsSplashSettings(object): + def __init__(self, params, meraki): + self.meraki = meraki + self.new_object = dict( + splashUrl=params.get("splashUrl"), + useSplashUrl=params.get("useSplashUrl"), + splashTimeout=params.get("splashTimeout"), + redirectUrl=params.get("redirectUrl"), + useRedirectUrl=params.get("useRedirectUrl"), + welcomeMessage=params.get("welcomeMessage"), + splashLogo=params.get("splashLogo"), + splashImage=params.get("splashImage"), + splashPrepaidFront=params.get("splashPrepaidFront"), + blockAllTrafficBeforeSignOn=params.get("blockAllTrafficBeforeSignOn"), + controllerDisconnectionBehavior=params.get("controllerDisconnectionBehavior"), + allowSimultaneousLogins=params.get("allowSimultaneousLogins"), + guestSponsorship=params.get("guestSponsorship"), + billing=params.get("billing"), + sentryEnrollment=params.get("sentryEnrollment"), + network_id=params.get("networkId"), + number=params.get("number"), + ) + + def get_all_params(self, name=None, id=None): + new_object_params = {} + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + if self.new_object.get('number') is not None or self.new_object.get('number') is not None: + new_object_params['number'] = self.new_object.get('number') + return new_object_params + + def update_all_params(self): + new_object_params = {} + if self.new_object.get('splashUrl') is not None or self.new_object.get('splash_url') is not None: + new_object_params['splashUrl'] = self.new_object.get('splashUrl') or \ + self.new_object.get('splash_url') + if self.new_object.get('useSplashUrl') is not None or self.new_object.get('use_splash_url') is not None: + new_object_params['useSplashUrl'] = self.new_object.get('useSplashUrl') + if self.new_object.get('splashTimeout') is not None or self.new_object.get('splash_timeout') is not None: + new_object_params['splashTimeout'] = self.new_object.get('splashTimeout') or \ + self.new_object.get('splash_timeout') + if self.new_object.get('redirectUrl') is not None or self.new_object.get('redirect_url') is not None: + new_object_params['redirectUrl'] = self.new_object.get('redirectUrl') or \ + self.new_object.get('redirect_url') + if self.new_object.get('useRedirectUrl') is not None or self.new_object.get('use_redirect_url') is not None: + new_object_params['useRedirectUrl'] = self.new_object.get('useRedirectUrl') + if self.new_object.get('welcomeMessage') is not None or self.new_object.get('welcome_message') is not None: + new_object_params['welcomeMessage'] = self.new_object.get('welcomeMessage') or \ + self.new_object.get('welcome_message') + if self.new_object.get('splashLogo') is not None or self.new_object.get('splash_logo') is not None: + new_object_params['splashLogo'] = self.new_object.get('splashLogo') or \ + self.new_object.get('splash_logo') + if self.new_object.get('splashImage') is not None or self.new_object.get('splash_image') is not None: + new_object_params['splashImage'] = self.new_object.get('splashImage') or \ + self.new_object.get('splash_image') + if self.new_object.get('splashPrepaidFront') is not None or self.new_object.get('splash_prepaid_front') is not None: + new_object_params['splashPrepaidFront'] = self.new_object.get('splashPrepaidFront') or \ + self.new_object.get('splash_prepaid_front') + if self.new_object.get('blockAllTrafficBeforeSignOn') is not None or self.new_object.get('block_all_traffic_before_sign_on') is not None: + new_object_params['blockAllTrafficBeforeSignOn'] = self.new_object.get('blockAllTrafficBeforeSignOn') + if self.new_object.get('controllerDisconnectionBehavior') is not None or self.new_object.get('controller_disconnection_behavior') is not None: + new_object_params['controllerDisconnectionBehavior'] = self.new_object.get('controllerDisconnectionBehavior') or \ + self.new_object.get('controller_disconnection_behavior') + if self.new_object.get('allowSimultaneousLogins') is not None or self.new_object.get('allow_simultaneous_logins') is not None: + new_object_params['allowSimultaneousLogins'] = self.new_object.get('allowSimultaneousLogins') + if self.new_object.get('guestSponsorship') is not None or self.new_object.get('guest_sponsorship') is not None: + new_object_params['guestSponsorship'] = self.new_object.get('guestSponsorship') or \ + self.new_object.get('guest_sponsorship') + if self.new_object.get('billing') is not None or self.new_object.get('billing') is not None: + new_object_params['billing'] = self.new_object.get('billing') or \ + self.new_object.get('billing') + if self.new_object.get('sentryEnrollment') is not None or self.new_object.get('sentry_enrollment') is not None: + new_object_params['sentryEnrollment'] = self.new_object.get('sentryEnrollment') or \ + self.new_object.get('sentry_enrollment') + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + if self.new_object.get('number') is not None or self.new_object.get('number') is not None: + new_object_params['number'] = self.new_object.get('number') or \ + self.new_object.get('number') + return new_object_params + + def get_object_by_name(self, name): + result = None + # NOTE: Does not have a get by name method, using get all + try: + items = self.meraki.exec_meraki( + family="wireless", + function="getNetworkWirelessSsidSplashSettings", + params=self.get_all_params(name=name), + ) + if isinstance(items, dict): + if 'response' in items: + items = items.get('response') + result = get_dict_result(items, 'name', name) + if result is None: + result = items + except Exception as e: + print("Error: ", e) + result = None + return result + + def get_object_by_id(self, id): + result = None + # NOTE: Does not have a get by id method or it is in another action + return result + + def exists(self): + prev_obj = None + id_exists = False + name_exists = False + o_id = self.new_object.get("networkId") or self.new_object.get("network_id") + name = self.new_object.get("name") + if o_id: + prev_obj = self.get_object_by_name(o_id) + id_exists = prev_obj is not None and isinstance(prev_obj, dict) + if not id_exists and name: + prev_obj = self.get_object_by_name(name) + name_exists = prev_obj is not None and isinstance(prev_obj, dict) + if name_exists: + _id = prev_obj.get("id") + if id_exists and name_exists and o_id != _id: + raise InconsistentParameters( + "The 'id' and 'name' params don't refer to the same object") + if _id: + self.new_object.update(dict(id=_id)) + it_exists = prev_obj is not None and isinstance(prev_obj, dict) + return (it_exists, prev_obj) + + def requires_update(self, current_obj): + requested_obj = self.new_object + + obj_params = [ + ("splashUrl", "splashUrl"), + ("useSplashUrl", "useSplashUrl"), + ("splashTimeout", "splashTimeout"), + ("redirectUrl", "redirectUrl"), + ("useRedirectUrl", "useRedirectUrl"), + ("welcomeMessage", "welcomeMessage"), + ("splashLogo", "splashLogo"), + ("splashImage", "splashImage"), + ("splashPrepaidFront", "splashPrepaidFront"), + ("blockAllTrafficBeforeSignOn", "blockAllTrafficBeforeSignOn"), + ("controllerDisconnectionBehavior", "controllerDisconnectionBehavior"), + ("allowSimultaneousLogins", "allowSimultaneousLogins"), + ("guestSponsorship", "guestSponsorship"), + ("billing", "billing"), + ("sentryEnrollment", "sentryEnrollment"), + ("networkId", "networkId"), + ("number", "number"), + ] + # Method 1. Params present in request (Ansible) obj are the same as the current (ISE) params + # If any does not have eq params, it requires update + return any(not meraki_compare_equality(current_obj.get(meraki_param), + requested_obj.get(ansible_param)) + for (meraki_param, ansible_param) in obj_params) + + def update(self): + id = self.new_object.get("id") + name = self.new_object.get("name") + result = None + result = self.meraki.exec_meraki( + family="wireless", + function="updateNetworkWirelessSsidSplashSettings", + params=self.update_all_params(), + op_modifies=True, + ) + return result + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = False + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + meraki = MERAKI(self._task.args) + obj = NetworksWirelessSsidsSplashSettings(self._task.args, meraki) + + state = self._task.args.get("state") + + response = None + if state == "present": + (obj_exists, prev_obj) = obj.exists() + if obj_exists: + if obj.requires_update(prev_obj): + response = obj.update() + meraki.object_updated() + else: + response = prev_obj + meraki.object_already_present() + else: + meraki.fail_json( + "Object does not exists, plugin only has update") + + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_wireless_ssids_splash_settings_info.py b/ansible_collections/cisco/meraki/plugins/action/networks_wireless_ssids_splash_settings_info.py new file mode 100644 index 000000000..69f7b2824 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_wireless_ssids_splash_settings_info.py @@ -0,0 +1,94 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + networkId=dict(type="str"), + number=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_all(self, params): + new_object = {} + if params.get("networkId") is not None: + new_object["networkId"] = params.get( + "networkId") + if params.get("number") is not None: + new_object["number"] = params.get( + "number") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="wireless", + function='getNetworkWirelessSsidSplashSettings', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_wireless_ssids_traffic_shaping_rules.py b/ansible_collections/cisco/meraki/plugins/action/networks_wireless_ssids_traffic_shaping_rules.py new file mode 100644 index 000000000..de13a0d80 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_wireless_ssids_traffic_shaping_rules.py @@ -0,0 +1,218 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or +# https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, + meraki_compare_equality, + get_dict_result, +) +from ansible_collections.cisco.meraki.plugins.plugin_utils.exceptions import ( + InconsistentParameters, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + state=dict(type="str", default="present", choices=["present"]), + trafficShapingEnabled=dict(type="bool"), + defaultRulesEnabled=dict(type="bool"), + rules=dict(type="list"), + networkId=dict(type="str"), + number=dict(type="str"), +)) + +required_if = [ + ("state", "present", ["networkId", "number"], True), +] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class NetworksWirelessSsidsTrafficShapingRules(object): + def __init__(self, params, meraki): + self.meraki = meraki + self.new_object = dict( + trafficShapingEnabled=params.get("trafficShapingEnabled"), + defaultRulesEnabled=params.get("defaultRulesEnabled"), + rules=params.get("rules"), + network_id=params.get("networkId"), + number=params.get("number"), + ) + + def get_all_params(self, name=None, id=None): + new_object_params = {} + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + if self.new_object.get('number') is not None or self.new_object.get('number') is not None: + new_object_params['number'] = self.new_object.get('number') + return new_object_params + + def update_all_params(self): + new_object_params = {} + if self.new_object.get('trafficShapingEnabled') is not None or self.new_object.get('traffic_shaping_enabled') is not None: + new_object_params['trafficShapingEnabled'] = self.new_object.get('trafficShapingEnabled') + if self.new_object.get('defaultRulesEnabled') is not None or self.new_object.get('default_rules_enabled') is not None: + new_object_params['defaultRulesEnabled'] = self.new_object.get('defaultRulesEnabled') + if self.new_object.get('rules') is not None or self.new_object.get('rules') is not None: + new_object_params['rules'] = self.new_object.get('rules') or \ + self.new_object.get('rules') + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + if self.new_object.get('number') is not None or self.new_object.get('number') is not None: + new_object_params['number'] = self.new_object.get('number') or \ + self.new_object.get('number') + return new_object_params + + def get_object_by_name(self, name): + result = None + # NOTE: Does not have a get by name method, using get all + try: + items = self.meraki.exec_meraki( + family="wireless", + function="getNetworkWirelessSsidTrafficShapingRules", + params=self.get_all_params(name=name), + ) + if isinstance(items, dict): + if 'response' in items: + items = items.get('response') + result = get_dict_result(items, 'name', name) + if result is None: + result = items + except Exception as e: + print("Error: ", e) + result = None + return result + + def get_object_by_id(self, id): + result = None + # NOTE: Does not have a get by id method or it is in another action + return result + + def exists(self): + prev_obj = None + id_exists = False + name_exists = False + o_id = self.new_object.get("networkId") or self.new_object.get("network_id") + name = self.new_object.get("name") + if o_id: + prev_obj = self.get_object_by_name(o_id) + id_exists = prev_obj is not None and isinstance(prev_obj, dict) + if not id_exists and name: + prev_obj = self.get_object_by_name(name) + name_exists = prev_obj is not None and isinstance(prev_obj, dict) + if name_exists: + _id = prev_obj.get("id") + if id_exists and name_exists and o_id != _id: + raise InconsistentParameters( + "The 'id' and 'name' params don't refer to the same object") + if _id: + self.new_object.update(dict(id=_id)) + it_exists = prev_obj is not None and isinstance(prev_obj, dict) + return (it_exists, prev_obj) + + def requires_update(self, current_obj): + requested_obj = self.new_object + + obj_params = [ + ("trafficShapingEnabled", "trafficShapingEnabled"), + ("defaultRulesEnabled", "defaultRulesEnabled"), + ("rules", "rules"), + ("networkId", "networkId"), + ("number", "number"), + ] + # Method 1. Params present in request (Ansible) obj are the same as the current (ISE) params + # If any does not have eq params, it requires update + return any(not meraki_compare_equality(current_obj.get(meraki_param), + requested_obj.get(ansible_param)) + for (meraki_param, ansible_param) in obj_params) + + def update(self): + id = self.new_object.get("id") + name = self.new_object.get("name") + result = None + result = self.meraki.exec_meraki( + family="wireless", + function="updateNetworkWirelessSsidTrafficShapingRules", + params=self.update_all_params(), + op_modifies=True, + ) + return result + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = False + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + meraki = MERAKI(self._task.args) + obj = NetworksWirelessSsidsTrafficShapingRules(self._task.args, meraki) + + state = self._task.args.get("state") + + response = None + if state == "present": + (obj_exists, prev_obj) = obj.exists() + if obj_exists: + if obj.requires_update(prev_obj): + response = obj.update() + meraki.object_updated() + else: + response = prev_obj + meraki.object_already_present() + else: + meraki.fail_json( + "Object does not exists, plugin only has update") + + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_wireless_ssids_traffic_shaping_rules_info.py b/ansible_collections/cisco/meraki/plugins/action/networks_wireless_ssids_traffic_shaping_rules_info.py new file mode 100644 index 000000000..c0f2ffdba --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_wireless_ssids_traffic_shaping_rules_info.py @@ -0,0 +1,94 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + networkId=dict(type="str"), + number=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_all(self, params): + new_object = {} + if params.get("networkId") is not None: + new_object["networkId"] = params.get( + "networkId") + if params.get("number") is not None: + new_object["number"] = params.get( + "number") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="wireless", + function='getNetworkWirelessSsidTrafficShapingRules', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_wireless_ssids_vpn.py b/ansible_collections/cisco/meraki/plugins/action/networks_wireless_ssids_vpn.py new file mode 100644 index 000000000..cc3836353 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_wireless_ssids_vpn.py @@ -0,0 +1,220 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or +# https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, + meraki_compare_equality, + get_dict_result, +) +from ansible_collections.cisco.meraki.plugins.plugin_utils.exceptions import ( + InconsistentParameters, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + state=dict(type="str", default="present", choices=["present"]), + concentrator=dict(type="dict"), + splitTunnel=dict(type="dict"), + failover=dict(type="dict"), + networkId=dict(type="str"), + number=dict(type="str"), +)) + +required_if = [ + ("state", "present", ["networkId", "number"], True), +] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class NetworksWirelessSsidsVpn(object): + def __init__(self, params, meraki): + self.meraki = meraki + self.new_object = dict( + concentrator=params.get("concentrator"), + splitTunnel=params.get("splitTunnel"), + failover=params.get("failover"), + network_id=params.get("networkId"), + number=params.get("number"), + ) + + def get_all_params(self, name=None, id=None): + new_object_params = {} + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + if self.new_object.get('number') is not None or self.new_object.get('number') is not None: + new_object_params['number'] = self.new_object.get('number') + return new_object_params + + def update_all_params(self): + new_object_params = {} + if self.new_object.get('concentrator') is not None or self.new_object.get('concentrator') is not None: + new_object_params['concentrator'] = self.new_object.get('concentrator') or \ + self.new_object.get('concentrator') + if self.new_object.get('splitTunnel') is not None or self.new_object.get('split_tunnel') is not None: + new_object_params['splitTunnel'] = self.new_object.get('splitTunnel') or \ + self.new_object.get('split_tunnel') + if self.new_object.get('failover') is not None or self.new_object.get('failover') is not None: + new_object_params['failover'] = self.new_object.get('failover') or \ + self.new_object.get('failover') + if self.new_object.get('networkId') is not None or self.new_object.get('network_id') is not None: + new_object_params['networkId'] = self.new_object.get('networkId') or \ + self.new_object.get('network_id') + if self.new_object.get('number') is not None or self.new_object.get('number') is not None: + new_object_params['number'] = self.new_object.get('number') or \ + self.new_object.get('number') + return new_object_params + + def get_object_by_name(self, name): + result = None + # NOTE: Does not have a get by name method, using get all + try: + items = self.meraki.exec_meraki( + family="wireless", + function="getNetworkWirelessSsidVpn", + params=self.get_all_params(name=name), + ) + if isinstance(items, dict): + if 'response' in items: + items = items.get('response') + result = get_dict_result(items, 'name', name) + if result is None: + result = items + except Exception as e: + print("Error: ", e) + result = None + return result + + def get_object_by_id(self, id): + result = None + # NOTE: Does not have a get by id method or it is in another action + return result + + def exists(self): + prev_obj = None + id_exists = False + name_exists = False + o_id = self.new_object.get("networkId") or self.new_object.get("network_id") + name = self.new_object.get("name") + if o_id: + prev_obj = self.get_object_by_name(o_id) + id_exists = prev_obj is not None and isinstance(prev_obj, dict) + if not id_exists and name: + prev_obj = self.get_object_by_name(name) + name_exists = prev_obj is not None and isinstance(prev_obj, dict) + if name_exists: + _id = prev_obj.get("id") + if id_exists and name_exists and o_id != _id: + raise InconsistentParameters( + "The 'id' and 'name' params don't refer to the same object") + if _id: + self.new_object.update(dict(id=_id)) + it_exists = prev_obj is not None and isinstance(prev_obj, dict) + return (it_exists, prev_obj) + + def requires_update(self, current_obj): + requested_obj = self.new_object + + obj_params = [ + ("concentrator", "concentrator"), + ("splitTunnel", "splitTunnel"), + ("failover", "failover"), + ("networkId", "networkId"), + ("number", "number"), + ] + # Method 1. Params present in request (Ansible) obj are the same as the current (ISE) params + # If any does not have eq params, it requires update + return any(not meraki_compare_equality(current_obj.get(meraki_param), + requested_obj.get(ansible_param)) + for (meraki_param, ansible_param) in obj_params) + + def update(self): + id = self.new_object.get("id") + name = self.new_object.get("name") + result = None + result = self.meraki.exec_meraki( + family="wireless", + function="updateNetworkWirelessSsidVpn", + params=self.update_all_params(), + op_modifies=True, + ) + return result + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = False + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + meraki = MERAKI(self._task.args) + obj = NetworksWirelessSsidsVpn(self._task.args, meraki) + + state = self._task.args.get("state") + + response = None + if state == "present": + (obj_exists, prev_obj) = obj.exists() + if obj_exists: + if obj.requires_update(prev_obj): + response = obj.update() + meraki.object_updated() + else: + response = prev_obj + meraki.object_already_present() + else: + meraki.fail_json( + "Object does not exists, plugin only has update") + + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_wireless_ssids_vpn_info.py b/ansible_collections/cisco/meraki/plugins/action/networks_wireless_ssids_vpn_info.py new file mode 100644 index 000000000..789f54117 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_wireless_ssids_vpn_info.py @@ -0,0 +1,94 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + networkId=dict(type="str"), + number=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_all(self, params): + new_object = {} + if params.get("networkId") is not None: + new_object["networkId"] = params.get( + "networkId") + if params.get("number") is not None: + new_object["number"] = params.get( + "number") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="wireless", + function='getNetworkWirelessSsidVpn', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/networks_wireless_usage_history_info.py b/ansible_collections/cisco/meraki/plugins/action/networks_wireless_usage_history_info.py new file mode 100644 index 000000000..b6cf91617 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/networks_wireless_usage_history_info.py @@ -0,0 +1,130 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + networkId=dict(type="str"), + t0=dict(type="str"), + t1=dict(type="str"), + timespan=dict(type="float"), + resolution=dict(type="int"), + autoResolution=dict(type="bool"), + clientId=dict(type="str"), + deviceSerial=dict(type="str"), + apTag=dict(type="str"), + band=dict(type="str"), + ssid=dict(type="int"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_all(self, params): + new_object = {} + if params.get("networkId") is not None: + new_object["networkId"] = params.get( + "networkId") + if params.get("t0") is not None: + new_object["t0"] = params.get( + "t0") + if params.get("t1") is not None: + new_object["t1"] = params.get( + "t1") + if params.get("timespan") is not None: + new_object["timespan"] = params.get( + "timespan") + if params.get("resolution") is not None: + new_object["resolution"] = params.get( + "resolution") + if params.get("autoResolution") is not None: + new_object["autoResolution"] = params.get( + "autoResolution") + if params.get("clientId") is not None: + new_object["clientId"] = params.get( + "clientId") + if params.get("deviceSerial") is not None: + new_object["deviceSerial"] = params.get( + "deviceSerial") + if params.get("apTag") is not None: + new_object["apTag"] = params.get( + "apTag") + if params.get("band") is not None: + new_object["band"] = params.get( + "band") + if params.get("ssid") is not None: + new_object["ssid"] = params.get( + "ssid") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="wireless", + function='getNetworkWirelessUsageHistory', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/organizations.py b/ansible_collections/cisco/meraki/plugins/action/organizations.py new file mode 100644 index 000000000..0cb1670ef --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/organizations.py @@ -0,0 +1,299 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or +# https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, + meraki_compare_equality, + get_dict_result, +) +from ansible_collections.cisco.meraki.plugins.plugin_utils.exceptions import ( + InconsistentParameters, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + state=dict(type="str", default="present", choices=["present", "absent"]), + name=dict(type="str"), + management=dict(type="dict"), + organizationId=dict(type="str"), + api=dict(type="dict"), +)) + +required_if = [ + ("state", "present", ["name", "organizationId"], True), + ("state", "absent", ["name", "organizationId"], True), +] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class Organizations(object): + def __init__(self, params, meraki): + self.meraki = meraki + self.new_object = dict( + name=params.get("name"), + management=params.get("management"), + organizationId=params.get("organizationId"), + api=params.get("api"), + ) + + def get_all_params(self, name=None, id=None): + new_object_params = {} + return new_object_params + + def get_params_by_id(self, name=None, id=None): + new_object_params = {} + if self.new_object.get('organizationId') is not None or self.new_object.get('organization_id') is not None: + new_object_params['organizationId'] = self.new_object.get('organizationId') or \ + self.new_object.get('organization_id') + return new_object_params + + def create_params(self): + new_object_params = {} + if self.new_object.get('name') is not None or self.new_object.get('name') is not None: + new_object_params['name'] = self.new_object.get('name') or \ + self.new_object.get('name') + if self.new_object.get('management') is not None or self.new_object.get('management') is not None: + new_object_params['management'] = self.new_object.get('management') or \ + self.new_object.get('management') + return new_object_params + + def delete_by_id_params(self): + new_object_params = {} + if self.new_object.get('organizationId') is not None or self.new_object.get('organization_id') is not None: + new_object_params['organizationId'] = self.new_object.get('organizationId') or \ + self.new_object.get('organization_id') + return new_object_params + + def update_by_id_params(self): + new_object_params = {} + if self.new_object.get('name') is not None or self.new_object.get('name') is not None: + new_object_params['name'] = self.new_object.get('name') or \ + self.new_object.get('name') + if self.new_object.get('management') is not None or self.new_object.get('management') is not None: + new_object_params['management'] = self.new_object.get('management') or \ + self.new_object.get('management') + if self.new_object.get('api') is not None or self.new_object.get('api') is not None: + new_object_params['api'] = self.new_object.get('api') or \ + self.new_object.get('api') + if self.new_object.get('organizationId') is not None or self.new_object.get('organization_id') is not None: + new_object_params['organizationId'] = self.new_object.get('organizationId') or \ + self.new_object.get('organization_id') + return new_object_params + + def get_object_by_name(self, name): + result = None + # NOTE: Does not have a get by name method or it is in another action + try: + items = self.meraki.exec_meraki( + family="organizations", + function="getOrganizations", + params=self.get_all_params(name=name), + ) + if isinstance(items, dict): + if 'response' in items: + items = items.get('response') + result = get_dict_result(items, 'name', name) + if result is None: + result = items + except Exception as e: + print("Error: ", e) + result = None + return result + + def get_object_by_id(self, id): + result = None + try: + items = self.meraki.exec_meraki( + family="organizations", + function="getOrganization", + params=self.get_params_by_id() + ) + if isinstance(items, dict): + if 'response' in items: + items = items.get('response') + result = get_dict_result(items, 'organizationId', id) + except Exception as e: + print("Error: ", e) + result = None + return result + + def exists(self): + id_exists = False + name_exists = False + prev_obj = None + o_id = self.new_object.get("id") + o_id = o_id or self.new_object.get( + "organization_id") or self.new_object.get("organizationId") + name = self.new_object.get("name") + if o_id: + prev_obj = self.get_object_by_id(o_id) + id_exists = prev_obj is not None and isinstance(prev_obj, dict) + if not id_exists and name: + prev_obj = self.get_object_by_name(name) + name_exists = prev_obj is not None and isinstance(prev_obj, dict) + if name_exists: + _id = prev_obj.get("id") + _id = _id or prev_obj.get("organizationId") + if id_exists and name_exists and o_id != _id: + raise InconsistentParameters( + "The 'id' and 'name' params don't refer to the same object") + if _id: + self.new_object.update(dict(id=_id)) + self.new_object.update(dict(organizationId=_id)) + if _id: + prev_obj = self.get_object_by_id(_id) + it_exists = prev_obj is not None and isinstance(prev_obj, dict) + return (it_exists, prev_obj) + + def requires_update(self, current_obj): + requested_obj = self.new_object + + obj_params = [ + ("name", "name"), + ("management", "management"), + ("organizationId", "organizationId"), + ("api", "api"), + ] + # Method 1. Params present in request (Ansible) obj are the same as the current (DNAC) params + # If any does not have eq params, it requires update + return any(not meraki_compare_equality(current_obj.get(meraki_param), + requested_obj.get(ansible_param)) + for (meraki_param, ansible_param) in obj_params) + + def create(self): + result = self.meraki.exec_meraki( + family="organizations", + function="createOrganization", + params=self.create_params(), + op_modifies=True, + ) + return result + + def update(self): + id = self.new_object.get("id") + id = id or self.new_object.get("organizationId") + name = self.new_object.get("name") + result = None + if not id: + prev_obj_name = self.get_object_by_name(name) + id_ = None + if prev_obj_name: + id_ = prev_obj_name.get("id") + id_ = id_ or prev_obj_name.get("organizationId") + if id_: + self.new_object.update(dict(organizationId=id_)) + result = self.meraki.exec_meraki( + family="organizations", + function="updateOrganization", + params=self.update_by_id_params(), + op_modifies=True, + ) + return result + + def delete(self): + id = self.new_object.get("id") + id = id or self.new_object.get("organizationId") + name = self.new_object.get("name") + result = None + if not id: + prev_obj_name = self.get_object_by_name(name) + id_ = None + if prev_obj_name: + id_ = prev_obj_name.get("id") + id_ = id_ or prev_obj_name.get("organizationId") + if id_: + self.new_object.update(dict(organizationId=id_)) + result = self.meraki.exec_meraki( + family="organizations", + function="deleteOrganization", + params=self.delete_by_id_params(), + ) + return result + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = False + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + meraki = MERAKI(self._task.args) + obj = Organizations(self._task.args, meraki) + + state = self._task.args.get("state") + + response = None + + if state == "present": + (obj_exists, prev_obj) = obj.exists() + if obj_exists: + if obj.requires_update(prev_obj): + response = obj.update() + meraki.object_updated() + else: + response = prev_obj + meraki.object_already_present() + else: + response = obj.create() + meraki.object_created() + + elif state == "absent": + (obj_exists, prev_obj) = obj.exists() + if obj_exists: + response = obj.delete() + meraki.object_deleted() + else: + meraki.object_already_absent() + + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/organizations_action_batches.py b/ansible_collections/cisco/meraki/plugins/action/organizations_action_batches.py new file mode 100644 index 000000000..8780b3e82 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/organizations_action_batches.py @@ -0,0 +1,315 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or +# https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, + meraki_compare_equality, + get_dict_result, +) +from ansible_collections.cisco.meraki.plugins.plugin_utils.exceptions import ( + InconsistentParameters, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + state=dict(type="str", default="present", choices=["present", "absent"]), + confirmed=dict(type="bool"), + synchronous=dict(type="bool"), + actions=dict(type="list"), + organizationId=dict(type="str"), + actionBatchId=dict(type="str"), +)) + +required_if = [ + ("state", "present", ["actionBatchId", "organizationId"], True), + ("state", "absent", ["actionBatchId", "organizationId"], True), +] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class OrganizationsActionBatches(object): + def __init__(self, params, meraki): + self.meraki = meraki + self.new_object = dict( + confirmed=params.get("confirmed"), + synchronous=params.get("synchronous"), + actions=params.get("actions"), + organizationId=params.get("organizationId"), + actionBatchId=params.get("actionBatchId"), + ) + + def get_all_params(self, name=None, id=None): + new_object_params = {} + if self.new_object.get('status') is not None or self.new_object.get('status') is not None: + new_object_params['status'] = self.new_object.get('status') + if self.new_object.get('organizationId') is not None or self.new_object.get('organization_id') is not None: + new_object_params['organizationId'] = self.new_object.get('organizationId') or \ + self.new_object.get('organization_id') + return new_object_params + + def get_params_by_id(self, name=None, id=None): + new_object_params = {} + if self.new_object.get('organizationId') is not None or self.new_object.get('organization_id') is not None: + new_object_params['organizationId'] = self.new_object.get('organizationId') or \ + self.new_object.get('organization_id') + if self.new_object.get('actionBatchId') is not None or self.new_object.get('action_batch_id') is not None: + new_object_params['actionBatchId'] = self.new_object.get('actionBatchId') or \ + self.new_object.get('action_batch_id') + return new_object_params + + def create_params(self): + new_object_params = {} + if self.new_object.get('confirmed') is not None or self.new_object.get('confirmed') is not None: + new_object_params['confirmed'] = self.new_object.get('confirmed') + if self.new_object.get('synchronous') is not None or self.new_object.get('synchronous') is not None: + new_object_params['synchronous'] = self.new_object.get('synchronous') + if self.new_object.get('actions') is not None or self.new_object.get('actions') is not None: + new_object_params['actions'] = self.new_object.get('actions') or \ + self.new_object.get('actions') + if self.new_object.get('organizationId') is not None or self.new_object.get('organization_id') is not None: + new_object_params['organizationId'] = self.new_object.get('organizationId') or \ + self.new_object.get('organization_id') + return new_object_params + + def delete_by_id_params(self): + new_object_params = {} + if self.new_object.get('organizationId') is not None or self.new_object.get('organization_id') is not None: + new_object_params['organizationId'] = self.new_object.get('organizationId') or \ + self.new_object.get('organization_id') + if self.new_object.get('actionBatchId') is not None or self.new_object.get('action_batch_id') is not None: + new_object_params['actionBatchId'] = self.new_object.get('actionBatchId') or \ + self.new_object.get('action_batch_id') + return new_object_params + + def update_by_id_params(self): + new_object_params = {} + if self.new_object.get('confirmed') is not None or self.new_object.get('confirmed') is not None: + new_object_params['confirmed'] = self.new_object.get('confirmed') + if self.new_object.get('synchronous') is not None or self.new_object.get('synchronous') is not None: + new_object_params['synchronous'] = self.new_object.get('synchronous') + if self.new_object.get('organizationId') is not None or self.new_object.get('organization_id') is not None: + new_object_params['organizationId'] = self.new_object.get('organizationId') or \ + self.new_object.get('organization_id') + if self.new_object.get('actionBatchId') is not None or self.new_object.get('action_batch_id') is not None: + new_object_params['actionBatchId'] = self.new_object.get('actionBatchId') or \ + self.new_object.get('action_batch_id') + return new_object_params + + def get_object_by_name(self, name): + result = None + # NOTE: Does not have a get by name method or it is in another action + try: + items = self.meraki.exec_meraki( + family="organizations", + function="getOrganizationActionBatches", + params=self.get_all_params(name=name), + ) + if isinstance(items, dict): + if 'response' in items: + items = items.get('response') + result = get_dict_result(items, 'name', name) + if result is None: + result = items + except Exception as e: + print("Error: ", e) + result = None + return result + + def get_object_by_id(self, id): + result = None + try: + items = self.meraki.exec_meraki( + family="organizations", + function="getOrganizationActionBatch", + params=self.get_params_by_id() + ) + if isinstance(items, dict): + if 'response' in items: + items = items.get('response') + result = get_dict_result(items, 'actionBatchId', id) + except Exception as e: + print("Error: ", e) + result = None + return result + + def exists(self): + id_exists = False + name_exists = False + prev_obj = None + o_id = self.new_object.get("id") + o_id = o_id or self.new_object.get( + "action_batch_id") or self.new_object.get("actionBatchId") + name = self.new_object.get("name") + if o_id: + prev_obj = self.get_object_by_id(o_id) + id_exists = prev_obj is not None and isinstance(prev_obj, dict) + if not id_exists and name: + prev_obj = self.get_object_by_name(name) + name_exists = prev_obj is not None and isinstance(prev_obj, dict) + if name_exists: + _id = prev_obj.get("id") + _id = _id or prev_obj.get("actionBatchId") + if id_exists and name_exists and o_id != _id: + raise InconsistentParameters( + "The 'id' and 'name' params don't refer to the same object") + if _id: + self.new_object.update(dict(id=_id)) + self.new_object.update(dict(actionBatchId=_id)) + if _id: + prev_obj = self.get_object_by_id(_id) + it_exists = prev_obj is not None and isinstance(prev_obj, dict) + return (it_exists, prev_obj) + + def requires_update(self, current_obj): + requested_obj = self.new_object + + obj_params = [ + ("confirmed", "confirmed"), + ("synchronous", "synchronous"), + ("actions", "actions"), + ("organizationId", "organizationId"), + ("actionBatchId", "actionBatchId"), + ] + # Method 1. Params present in request (Ansible) obj are the same as the current (DNAC) params + # If any does not have eq params, it requires update + return any(not meraki_compare_equality(current_obj.get(meraki_param), + requested_obj.get(ansible_param)) + for (meraki_param, ansible_param) in obj_params) + + def create(self): + result = self.meraki.exec_meraki( + family="organizations", + function="createOrganizationActionBatch", + params=self.create_params(), + op_modifies=True, + ) + return result + + def update(self): + id = self.new_object.get("id") + id = id or self.new_object.get("actionBatchId") + name = self.new_object.get("name") + result = None + if not id: + prev_obj_name = self.get_object_by_name(name) + id_ = None + if prev_obj_name: + id_ = prev_obj_name.get("id") + id_ = id_ or prev_obj_name.get("actionBatchId") + if id_: + self.new_object.update(dict(actionBatchId=id_)) + result = self.meraki.exec_meraki( + family="organizations", + function="updateOrganizationActionBatch", + params=self.update_by_id_params(), + op_modifies=True, + ) + return result + + def delete(self): + id = self.new_object.get("id") + id = id or self.new_object.get("actionBatchId") + name = self.new_object.get("name") + result = None + if not id: + prev_obj_name = self.get_object_by_name(name) + id_ = None + if prev_obj_name: + id_ = prev_obj_name.get("id") + id_ = id_ or prev_obj_name.get("actionBatchId") + if id_: + self.new_object.update(dict(actionBatchId=id_)) + result = self.meraki.exec_meraki( + family="organizations", + function="deleteOrganizationActionBatch", + params=self.delete_by_id_params(), + ) + return result + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = False + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + meraki = MERAKI(self._task.args) + obj = OrganizationsActionBatches(self._task.args, meraki) + + state = self._task.args.get("state") + + response = None + + if state == "present": + (obj_exists, prev_obj) = obj.exists() + if obj_exists: + if obj.requires_update(prev_obj): + response = obj.update() + meraki.object_updated() + else: + response = prev_obj + meraki.object_already_present() + else: + response = obj.create() + meraki.object_created() + + elif state == "absent": + (obj_exists, prev_obj) = obj.exists() + if obj_exists: + response = obj.delete() + meraki.object_deleted() + else: + meraki.object_already_absent() + + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/organizations_action_batches_info.py b/ansible_collections/cisco/meraki/plugins/action/organizations_action_batches_info.py new file mode 100644 index 000000000..605ef538e --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/organizations_action_batches_info.py @@ -0,0 +1,116 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + organizationId=dict(type="str"), + status=dict(type="str"), + actionBatchId=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_object(self, params): + new_object = {} + if params.get("organizationId") is not None: + new_object["organizationId"] = params.get( + "organizationId") + if params.get("actionBatchId") is not None: + new_object["actionBatchId"] = params.get( + "actionBatchId") + return new_object + + def get_all(self, params): + new_object = {} + if params.get("organizationId") is not None: + new_object["organizationId"] = params.get( + "organizationId") + if params.get("status") is not None: + new_object["status"] = params.get( + "status") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + id = self._task.args.get("actionBatchId") + if id: + response = meraki.exec_meraki( + family="organizations", + function='getOrganizationActionBatch', + params=self.get_object(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result + if not id: + response = meraki.exec_meraki( + family="organizations", + function='getOrganizationActionBatches', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/organizations_adaptive_policy_acls.py b/ansible_collections/cisco/meraki/plugins/action/organizations_adaptive_policy_acls.py new file mode 100644 index 000000000..cc445e11f --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/organizations_adaptive_policy_acls.py @@ -0,0 +1,329 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or +# https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, + meraki_compare_equality, + get_dict_result, +) +from ansible_collections.cisco.meraki.plugins.plugin_utils.exceptions import ( + InconsistentParameters, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + state=dict(type="str", default="present", choices=["present", "absent"]), + name=dict(type="str"), + description=dict(type="str"), + rules=dict(type="list"), + ipVersion=dict(type="str"), + organizationId=dict(type="str"), + aclId=dict(type="str"), +)) + +required_if = [ + ("state", "present", ["aclId", "name", "organizationId"], True), + ("state", "absent", ["aclId", "name", "organizationId"], True), +] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class OrganizationsAdaptivePolicyAcls(object): + def __init__(self, params, meraki): + self.meraki = meraki + self.new_object = dict( + name=params.get("name"), + description=params.get("description"), + rules=params.get("rules"), + ipVersion=params.get("ipVersion"), + organizationId=params.get("organizationId"), + aclId=params.get("aclId"), + ) + + def get_all_params(self, name=None, id=None): + new_object_params = {} + if self.new_object.get('organizationId') is not None or self.new_object.get('organization_id') is not None: + new_object_params['organizationId'] = self.new_object.get('organizationId') or \ + self.new_object.get('organization_id') + return new_object_params + + def get_params_by_id(self, name=None, id=None): + new_object_params = {} + if self.new_object.get('organizationId') is not None or self.new_object.get('organization_id') is not None: + new_object_params['organizationId'] = self.new_object.get('organizationId') or \ + self.new_object.get('organization_id') + if self.new_object.get('aclId') is not None or self.new_object.get('acl_id') is not None: + new_object_params['aclId'] = self.new_object.get('aclId') or \ + self.new_object.get('acl_id') + return new_object_params + + def create_params(self): + new_object_params = {} + if self.new_object.get('name') is not None or self.new_object.get('name') is not None: + new_object_params['name'] = self.new_object.get('name') or \ + self.new_object.get('name') + if self.new_object.get('description') is not None or self.new_object.get('description') is not None: + new_object_params['description'] = self.new_object.get('description') or \ + self.new_object.get('description') + if self.new_object.get('rules') is not None or self.new_object.get('rules') is not None: + new_object_params['rules'] = self.new_object.get('rules') or \ + self.new_object.get('rules') + if self.new_object.get('ipVersion') is not None or self.new_object.get('ip_version') is not None: + new_object_params['ipVersion'] = self.new_object.get('ipVersion') or \ + self.new_object.get('ip_version') + if self.new_object.get('organizationId') is not None or self.new_object.get('organization_id') is not None: + new_object_params['organizationId'] = self.new_object.get('organizationId') or \ + self.new_object.get('organization_id') + return new_object_params + + def delete_by_id_params(self): + new_object_params = {} + if self.new_object.get('organizationId') is not None or self.new_object.get('organization_id') is not None: + new_object_params['organizationId'] = self.new_object.get('organizationId') or \ + self.new_object.get('organization_id') + if self.new_object.get('aclId') is not None or self.new_object.get('acl_id') is not None: + new_object_params['aclId'] = self.new_object.get('aclId') or \ + self.new_object.get('acl_id') + return new_object_params + + def update_by_id_params(self): + new_object_params = {} + if self.new_object.get('name') is not None or self.new_object.get('name') is not None: + new_object_params['name'] = self.new_object.get('name') or \ + self.new_object.get('name') + if self.new_object.get('description') is not None or self.new_object.get('description') is not None: + new_object_params['description'] = self.new_object.get('description') or \ + self.new_object.get('description') + if self.new_object.get('rules') is not None or self.new_object.get('rules') is not None: + new_object_params['rules'] = self.new_object.get('rules') or \ + self.new_object.get('rules') + if self.new_object.get('ipVersion') is not None or self.new_object.get('ip_version') is not None: + new_object_params['ipVersion'] = self.new_object.get('ipVersion') or \ + self.new_object.get('ip_version') + if self.new_object.get('organizationId') is not None or self.new_object.get('organization_id') is not None: + new_object_params['organizationId'] = self.new_object.get('organizationId') or \ + self.new_object.get('organization_id') + if self.new_object.get('aclId') is not None or self.new_object.get('acl_id') is not None: + new_object_params['aclId'] = self.new_object.get('aclId') or \ + self.new_object.get('acl_id') + return new_object_params + + def get_object_by_name(self, name): + result = None + # NOTE: Does not have a get by name method or it is in another action + try: + items = self.meraki.exec_meraki( + family="organizations", + function="getOrganizationAdaptivePolicyAcls", + params=self.get_all_params(name=name), + ) + if isinstance(items, dict): + if 'response' in items: + items = items.get('response') + result = get_dict_result(items, 'name', name) + if result is None: + result = items + except Exception as e: + print("Error: ", e) + result = None + return result + + def get_object_by_id(self, id): + result = None + try: + items = self.meraki.exec_meraki( + family="organizations", + function="getOrganizationAdaptivePolicyAcl", + params=self.get_params_by_id() + ) + if isinstance(items, dict): + if 'response' in items: + items = items.get('response') + result = get_dict_result(items, 'aclId', id) + except Exception as e: + print("Error: ", e) + result = None + return result + + def exists(self): + id_exists = False + name_exists = False + prev_obj = None + o_id = self.new_object.get("id") + o_id = o_id or self.new_object.get( + "acl_id") or self.new_object.get("aclId") + name = self.new_object.get("name") + if o_id: + prev_obj = self.get_object_by_id(o_id) + id_exists = prev_obj is not None and isinstance(prev_obj, dict) + if not id_exists and name: + prev_obj = self.get_object_by_name(name) + name_exists = prev_obj is not None and isinstance(prev_obj, dict) + if name_exists: + _id = prev_obj.get("id") + _id = _id or prev_obj.get("aclId") + if id_exists and name_exists and o_id != _id: + raise InconsistentParameters( + "The 'id' and 'name' params don't refer to the same object") + if _id: + self.new_object.update(dict(id=_id)) + self.new_object.update(dict(aclId=_id)) + if _id: + prev_obj = self.get_object_by_id(_id) + it_exists = prev_obj is not None and isinstance(prev_obj, dict) + return (it_exists, prev_obj) + + def requires_update(self, current_obj): + requested_obj = self.new_object + + obj_params = [ + ("name", "name"), + ("description", "description"), + ("rules", "rules"), + ("ipVersion", "ipVersion"), + ("organizationId", "organizationId"), + ("aclId", "aclId"), + ] + # Method 1. Params present in request (Ansible) obj are the same as the current (DNAC) params + # If any does not have eq params, it requires update + return any(not meraki_compare_equality(current_obj.get(meraki_param), + requested_obj.get(ansible_param)) + for (meraki_param, ansible_param) in obj_params) + + def create(self): + result = self.meraki.exec_meraki( + family="organizations", + function="createOrganizationAdaptivePolicyAcl", + params=self.create_params(), + op_modifies=True, + ) + return result + + def update(self): + id = self.new_object.get("id") + id = id or self.new_object.get("aclId") + name = self.new_object.get("name") + result = None + if not id: + prev_obj_name = self.get_object_by_name(name) + id_ = None + if prev_obj_name: + id_ = prev_obj_name.get("id") + id_ = id_ or prev_obj_name.get("aclId") + if id_: + self.new_object.update(dict(aclId=id_)) + result = self.meraki.exec_meraki( + family="organizations", + function="updateOrganizationAdaptivePolicyAcl", + params=self.update_by_id_params(), + op_modifies=True, + ) + return result + + def delete(self): + id = self.new_object.get("id") + id = id or self.new_object.get("aclId") + name = self.new_object.get("name") + result = None + if not id: + prev_obj_name = self.get_object_by_name(name) + id_ = None + if prev_obj_name: + id_ = prev_obj_name.get("id") + id_ = id_ or prev_obj_name.get("aclId") + if id_: + self.new_object.update(dict(aclId=id_)) + result = self.meraki.exec_meraki( + family="organizations", + function="deleteOrganizationAdaptivePolicyAcl", + params=self.delete_by_id_params(), + ) + return result + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = False + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + meraki = MERAKI(self._task.args) + obj = OrganizationsAdaptivePolicyAcls(self._task.args, meraki) + + state = self._task.args.get("state") + + response = None + + if state == "present": + (obj_exists, prev_obj) = obj.exists() + if obj_exists: + if obj.requires_update(prev_obj): + response = obj.update() + meraki.object_updated() + else: + response = prev_obj + meraki.object_already_present() + else: + response = obj.create() + meraki.object_created() + + elif state == "absent": + (obj_exists, prev_obj) = obj.exists() + if obj_exists: + response = obj.delete() + meraki.object_deleted() + else: + meraki.object_already_absent() + + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/organizations_adaptive_policy_acls_info.py b/ansible_collections/cisco/meraki/plugins/action/organizations_adaptive_policy_acls_info.py new file mode 100644 index 000000000..d956b3a66 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/organizations_adaptive_policy_acls_info.py @@ -0,0 +1,112 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + organizationId=dict(type="str"), + aclId=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_object(self, params): + new_object = {} + if params.get("organizationId") is not None: + new_object["organizationId"] = params.get( + "organizationId") + if params.get("aclId") is not None: + new_object["aclId"] = params.get( + "aclId") + return new_object + + def get_all(self, params): + new_object = {} + if params.get("organizationId") is not None: + new_object["organizationId"] = params.get( + "organizationId") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + id = self._task.args.get("aclId") + if id: + response = meraki.exec_meraki( + family="organizations", + function='getOrganizationAdaptivePolicyAcl', + params=self.get_object(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result + if not id: + response = meraki.exec_meraki( + family="organizations", + function='getOrganizationAdaptivePolicyAcls', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/organizations_adaptive_policy_groups.py b/ansible_collections/cisco/meraki/plugins/action/organizations_adaptive_policy_groups.py new file mode 100644 index 000000000..f170a7ad0 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/organizations_adaptive_policy_groups.py @@ -0,0 +1,320 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or +# https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, + meraki_compare_equality, + get_dict_result, +) +from ansible_collections.cisco.meraki.plugins.plugin_utils.exceptions import ( + InconsistentParameters, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + state=dict(type="str", default="present", choices=["present", "absent"]), + name=dict(type="str"), + sgt=dict(type="int"), + description=dict(type="str"), + policyObjects=dict(type="list"), + organizationId=dict(type="str"), + id=dict(type="str"), +)) + +required_if = [ + ("state", "present", ["id", "name", "organizationId"], True), + ("state", "absent", ["id", "name", "organizationId"], True), +] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class OrganizationsAdaptivePolicyGroups(object): + def __init__(self, params, meraki): + self.meraki = meraki + self.new_object = dict( + name=params.get("name"), + sgt=params.get("sgt"), + description=params.get("description"), + policyObjects=params.get("policyObjects"), + organizationId=params.get("organizationId"), + id=params.get("id"), + ) + + def get_all_params(self, name=None, id=None): + new_object_params = {} + if self.new_object.get('organizationId') is not None or self.new_object.get('organization_id') is not None: + new_object_params['organizationId'] = self.new_object.get('organizationId') or \ + self.new_object.get('organization_id') + return new_object_params + + def get_params_by_id(self, name=None, id=None): + new_object_params = {} + if self.new_object.get('organizationId') is not None or self.new_object.get('organization_id') is not None: + new_object_params['organizationId'] = self.new_object.get('organizationId') or \ + self.new_object.get('organization_id') + if self.new_object.get('id') is not None or self.new_object.get('id') is not None: + new_object_params['id'] = self.new_object.get('id') + return new_object_params + + def create_params(self): + new_object_params = {} + if self.new_object.get('name') is not None or self.new_object.get('name') is not None: + new_object_params['name'] = self.new_object.get('name') or \ + self.new_object.get('name') + if self.new_object.get('sgt') is not None or self.new_object.get('sgt') is not None: + new_object_params['sgt'] = self.new_object.get('sgt') or \ + self.new_object.get('sgt') + if self.new_object.get('description') is not None or self.new_object.get('description') is not None: + new_object_params['description'] = self.new_object.get('description') or \ + self.new_object.get('description') + if self.new_object.get('policyObjects') is not None or self.new_object.get('policy_objects') is not None: + new_object_params['policyObjects'] = self.new_object.get('policyObjects') or \ + self.new_object.get('policy_objects') + if self.new_object.get('organizationId') is not None or self.new_object.get('organization_id') is not None: + new_object_params['organizationId'] = self.new_object.get('organizationId') or \ + self.new_object.get('organization_id') + return new_object_params + + def delete_by_id_params(self): + new_object_params = {} + if self.new_object.get('organizationId') is not None or self.new_object.get('organization_id') is not None: + new_object_params['organizationId'] = self.new_object.get('organizationId') or \ + self.new_object.get('organization_id') + if self.new_object.get('id') is not None or self.new_object.get('id') is not None: + new_object_params['id'] = self.new_object.get('id') or \ + self.new_object.get('id') + return new_object_params + + def update_by_id_params(self): + new_object_params = {} + if self.new_object.get('name') is not None or self.new_object.get('name') is not None: + new_object_params['name'] = self.new_object.get('name') or \ + self.new_object.get('name') + if self.new_object.get('sgt') is not None or self.new_object.get('sgt') is not None: + new_object_params['sgt'] = self.new_object.get('sgt') or \ + self.new_object.get('sgt') + if self.new_object.get('description') is not None or self.new_object.get('description') is not None: + new_object_params['description'] = self.new_object.get('description') or \ + self.new_object.get('description') + if self.new_object.get('policyObjects') is not None or self.new_object.get('policy_objects') is not None: + new_object_params['policyObjects'] = self.new_object.get('policyObjects') or \ + self.new_object.get('policy_objects') + if self.new_object.get('organizationId') is not None or self.new_object.get('organization_id') is not None: + new_object_params['organizationId'] = self.new_object.get('organizationId') or \ + self.new_object.get('organization_id') + if self.new_object.get('id') is not None or self.new_object.get('id') is not None: + new_object_params['id'] = self.new_object.get('id') or \ + self.new_object.get('id') + return new_object_params + + def get_object_by_name(self, name): + result = None + # NOTE: Does not have a get by name method or it is in another action + try: + items = self.meraki.exec_meraki( + family="organizations", + function="getOrganizationAdaptivePolicyGroups", + params=self.get_all_params(name=name), + ) + if isinstance(items, dict): + if 'response' in items: + items = items.get('response') + result = get_dict_result(items, 'name', name) + if result is None: + result = items + except Exception as e: + print("Error: ", e) + result = None + return result + + def get_object_by_id(self, id): + result = None + try: + items = self.meraki.exec_meraki( + family="organizations", + function="getOrganizationAdaptivePolicyGroup", + params={"id": id} + ) + if isinstance(items, dict): + if 'response' in items: + items = items.get('response') + result = get_dict_result(items, 'id', id) + except Exception as e: + print("Error: ", e) + result = None + return result + + def exists(self): + id_exists = False + name_exists = False + prev_obj = None + o_id = self.new_object.get("id") + name = self.new_object.get("name") + if o_id: + prev_obj = self.get_object_by_id(o_id) + id_exists = prev_obj is not None and isinstance(prev_obj, dict) + if not id_exists and name: + prev_obj = self.get_object_by_name(name) + name_exists = prev_obj is not None and isinstance(prev_obj, dict) + if name_exists: + _id = prev_obj.get("id") + if id_exists and name_exists and o_id != _id: + raise InconsistentParameters( + "The 'id' and 'name' params don't refer to the same object") + if _id: + self.new_object.update(dict(id=_id)) + if _id: + prev_obj = self.get_object_by_id(_id) + it_exists = prev_obj is not None and isinstance(prev_obj, dict) + return (it_exists, prev_obj) + + def requires_update(self, current_obj): + requested_obj = self.new_object + + obj_params = [ + ("name", "name"), + ("sgt", "sgt"), + ("description", "description"), + ("policyObjects", "policyObjects"), + ("organizationId", "organizationId"), + ("id", "id"), + ] + # Method 1. Params present in request (Ansible) obj are the same as the current (DNAC) params + # If any does not have eq params, it requires update + return any(not meraki_compare_equality(current_obj.get(meraki_param), + requested_obj.get(ansible_param)) + for (meraki_param, ansible_param) in obj_params) + + def create(self): + result = self.meraki.exec_meraki( + family="organizations", + function="createOrganizationAdaptivePolicyGroup", + params=self.create_params(), + op_modifies=True, + ) + return result + + def update(self): + id = self.new_object.get("id") + name = self.new_object.get("name") + result = None + if not id: + prev_obj_name = self.get_object_by_name(name) + id_ = None + if prev_obj_name: + id_ = prev_obj_name.get("groupId") + if id_: + self.new_object.update(dict(id=id_)) + result = self.meraki.exec_meraki( + family="organizations", + function="updateOrganizationAdaptivePolicyGroup", + params=self.update_by_id_params(), + op_modifies=True, + ) + return result + + def delete(self): + id = self.new_object.get("id") + name = self.new_object.get("name") + result = None + if not id: + prev_obj_name = self.get_object_by_name(name) + id_ = None + if prev_obj_name: + id_ = prev_obj_name.get("groupId") + if id_: + self.new_object.update(dict(id=id_)) + result = self.meraki.exec_meraki( + family="organizations", + function="deleteOrganizationAdaptivePolicyGroup", + params=self.delete_by_id_params(), + ) + return result + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = False + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + meraki = MERAKI(self._task.args) + obj = OrganizationsAdaptivePolicyGroups(self._task.args, meraki) + + state = self._task.args.get("state") + + response = None + + if state == "present": + (obj_exists, prev_obj) = obj.exists() + if obj_exists: + if obj.requires_update(prev_obj): + response = obj.update() + meraki.object_updated() + else: + response = prev_obj + meraki.object_already_present() + else: + response = obj.create() + meraki.object_created() + + elif state == "absent": + (obj_exists, prev_obj) = obj.exists() + if obj_exists: + response = obj.delete() + meraki.object_deleted() + else: + meraki.object_already_absent() + + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/organizations_adaptive_policy_groups_info.py b/ansible_collections/cisco/meraki/plugins/action/organizations_adaptive_policy_groups_info.py new file mode 100644 index 000000000..b76243f7c --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/organizations_adaptive_policy_groups_info.py @@ -0,0 +1,112 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + organizationId=dict(type="str"), + id=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_object(self, params): + new_object = {} + if params.get("organizationId") is not None: + new_object["organizationId"] = params.get( + "organizationId") + if params.get("id") is not None: + new_object["id"] = params.get( + "id") + return new_object + + def get_all(self, params): + new_object = {} + if params.get("organizationId") is not None: + new_object["organizationId"] = params.get( + "organizationId") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + id = self._task.args.get("id") + if id: + response = meraki.exec_meraki( + family="organizations", + function='getOrganizationAdaptivePolicyGroup', + params=self.get_object(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result + if not id: + response = meraki.exec_meraki( + family="organizations", + function='getOrganizationAdaptivePolicyGroups', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/organizations_adaptive_policy_overview_info.py b/ansible_collections/cisco/meraki/plugins/action/organizations_adaptive_policy_overview_info.py new file mode 100644 index 000000000..30d7dfbfa --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/organizations_adaptive_policy_overview_info.py @@ -0,0 +1,90 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + organizationId=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_all(self, params): + new_object = {} + if params.get("organizationId") is not None: + new_object["organizationId"] = params.get( + "organizationId") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="organizations", + function='getOrganizationAdaptivePolicyOverview', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/organizations_adaptive_policy_policies.py b/ansible_collections/cisco/meraki/plugins/action/organizations_adaptive_policy_policies.py new file mode 100644 index 000000000..9717b4aef --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/organizations_adaptive_policy_policies.py @@ -0,0 +1,320 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or +# https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, + meraki_compare_equality, + get_dict_result, +) +from ansible_collections.cisco.meraki.plugins.plugin_utils.exceptions import ( + InconsistentParameters, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + state=dict(type="str", default="present", choices=["present", "absent"]), + sourceGroup=dict(type="dict"), + destinationGroup=dict(type="dict"), + acls=dict(type="list"), + lastEntryRule=dict(type="str"), + organizationId=dict(type="str"), + id=dict(type="str"), +)) + +required_if = [ + ("state", "present", ["id", "organizationId"], True), + ("state", "absent", ["id", "organizationId"], True), +] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class OrganizationsAdaptivePolicyPolicies(object): + def __init__(self, params, meraki): + self.meraki = meraki + self.new_object = dict( + sourceGroup=params.get("sourceGroup"), + destinationGroup=params.get("destinationGroup"), + acls=params.get("acls"), + lastEntryRule=params.get("lastEntryRule"), + organizationId=params.get("organizationId"), + id=params.get("id"), + ) + + def get_all_params(self, name=None, id=None): + new_object_params = {} + if self.new_object.get('organizationId') is not None or self.new_object.get('organization_id') is not None: + new_object_params['organizationId'] = self.new_object.get('organizationId') or \ + self.new_object.get('organization_id') + return new_object_params + + def get_params_by_id(self, name=None, id=None): + new_object_params = {} + if self.new_object.get('organizationId') is not None or self.new_object.get('organization_id') is not None: + new_object_params['organizationId'] = self.new_object.get('organizationId') or \ + self.new_object.get('organization_id') + if self.new_object.get('id') is not None or self.new_object.get('id') is not None: + new_object_params['id'] = self.new_object.get('id') + return new_object_params + + def create_params(self): + new_object_params = {} + if self.new_object.get('sourceGroup') is not None or self.new_object.get('source_group') is not None: + new_object_params['sourceGroup'] = self.new_object.get('sourceGroup') or \ + self.new_object.get('source_group') + if self.new_object.get('destinationGroup') is not None or self.new_object.get('destination_group') is not None: + new_object_params['destinationGroup'] = self.new_object.get('destinationGroup') or \ + self.new_object.get('destination_group') + if self.new_object.get('acls') is not None or self.new_object.get('acls') is not None: + new_object_params['acls'] = self.new_object.get('acls') or \ + self.new_object.get('acls') + if self.new_object.get('lastEntryRule') is not None or self.new_object.get('last_entry_rule') is not None: + new_object_params['lastEntryRule'] = self.new_object.get('lastEntryRule') or \ + self.new_object.get('last_entry_rule') + if self.new_object.get('organizationId') is not None or self.new_object.get('organization_id') is not None: + new_object_params['organizationId'] = self.new_object.get('organizationId') or \ + self.new_object.get('organization_id') + return new_object_params + + def delete_by_id_params(self): + new_object_params = {} + if self.new_object.get('organizationId') is not None or self.new_object.get('organization_id') is not None: + new_object_params['organizationId'] = self.new_object.get('organizationId') or \ + self.new_object.get('organization_id') + if self.new_object.get('id') is not None or self.new_object.get('id') is not None: + new_object_params['id'] = self.new_object.get('id') or \ + self.new_object.get('id') + return new_object_params + + def update_by_id_params(self): + new_object_params = {} + if self.new_object.get('sourceGroup') is not None or self.new_object.get('source_group') is not None: + new_object_params['sourceGroup'] = self.new_object.get('sourceGroup') or \ + self.new_object.get('source_group') + if self.new_object.get('destinationGroup') is not None or self.new_object.get('destination_group') is not None: + new_object_params['destinationGroup'] = self.new_object.get('destinationGroup') or \ + self.new_object.get('destination_group') + if self.new_object.get('acls') is not None or self.new_object.get('acls') is not None: + new_object_params['acls'] = self.new_object.get('acls') or \ + self.new_object.get('acls') + if self.new_object.get('lastEntryRule') is not None or self.new_object.get('last_entry_rule') is not None: + new_object_params['lastEntryRule'] = self.new_object.get('lastEntryRule') or \ + self.new_object.get('last_entry_rule') + if self.new_object.get('organizationId') is not None or self.new_object.get('organization_id') is not None: + new_object_params['organizationId'] = self.new_object.get('organizationId') or \ + self.new_object.get('organization_id') + if self.new_object.get('id') is not None or self.new_object.get('id') is not None: + new_object_params['id'] = self.new_object.get('id') or \ + self.new_object.get('id') + return new_object_params + + def get_object_by_name(self, name): + result = None + # NOTE: Does not have a get by name method or it is in another action + try: + items = self.meraki.exec_meraki( + family="organizations", + function="getOrganizationAdaptivePolicyPolicies", + params=self.get_all_params(name=name), + ) + if isinstance(items, dict): + if 'response' in items: + items = items.get('response') + result = get_dict_result(items, 'name', name) + if result is None: + result = items + except Exception as e: + print("Error: ", e) + result = None + return result + + def get_object_by_id(self, id): + result = None + try: + items = self.meraki.exec_meraki( + family="organizations", + function="getOrganizationAdaptivePolicyPolicy", + params={"id": id} + ) + if isinstance(items, dict): + if 'response' in items: + items = items.get('response') + result = get_dict_result(items, 'id', id) + except Exception as e: + print("Error: ", e) + result = None + return result + + def exists(self): + id_exists = False + name_exists = False + prev_obj = None + o_id = self.new_object.get("id") + name = self.new_object.get("name") + if o_id: + prev_obj = self.get_object_by_id(o_id) + id_exists = prev_obj is not None and isinstance(prev_obj, dict) + if not id_exists and name: + prev_obj = self.get_object_by_name(name) + name_exists = prev_obj is not None and isinstance(prev_obj, dict) + if name_exists: + _id = prev_obj.get("id") + if id_exists and name_exists and o_id != _id: + raise InconsistentParameters( + "The 'id' and 'name' params don't refer to the same object") + if _id: + self.new_object.update(dict(id=_id)) + if _id: + prev_obj = self.get_object_by_id(_id) + it_exists = prev_obj is not None and isinstance(prev_obj, dict) + return (it_exists, prev_obj) + + def requires_update(self, current_obj): + requested_obj = self.new_object + + obj_params = [ + ("sourceGroup", "sourceGroup"), + ("destinationGroup", "destinationGroup"), + ("acls", "acls"), + ("lastEntryRule", "lastEntryRule"), + ("organizationId", "organizationId"), + ("id", "id"), + ] + # Method 1. Params present in request (Ansible) obj are the same as the current (DNAC) params + # If any does not have eq params, it requires update + return any(not meraki_compare_equality(current_obj.get(meraki_param), + requested_obj.get(ansible_param)) + for (meraki_param, ansible_param) in obj_params) + + def create(self): + result = self.meraki.exec_meraki( + family="organizations", + function="createOrganizationAdaptivePolicyPolicy", + params=self.create_params(), + op_modifies=True, + ) + return result + + def update(self): + id = self.new_object.get("id") + name = self.new_object.get("name") + result = None + if not id: + prev_obj_name = self.get_object_by_name(name) + id_ = None + if prev_obj_name: + id_ = prev_obj_name.get("id") + if id_: + self.new_object.update(dict(id=id_)) + result = self.meraki.exec_meraki( + family="organizations", + function="updateOrganizationAdaptivePolicyPolicy", + params=self.update_by_id_params(), + op_modifies=True, + ) + return result + + def delete(self): + id = self.new_object.get("id") + name = self.new_object.get("name") + result = None + if not id: + prev_obj_name = self.get_object_by_name(name) + id_ = None + if prev_obj_name: + id_ = prev_obj_name.get("id") + if id_: + self.new_object.update(dict(id=id_)) + result = self.meraki.exec_meraki( + family="organizations", + function="deleteOrganizationAdaptivePolicyPolicy", + params=self.delete_by_id_params(), + ) + return result + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = False + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + meraki = MERAKI(self._task.args) + obj = OrganizationsAdaptivePolicyPolicies(self._task.args, meraki) + + state = self._task.args.get("state") + + response = None + + if state == "present": + (obj_exists, prev_obj) = obj.exists() + if obj_exists: + if obj.requires_update(prev_obj): + response = obj.update() + meraki.object_updated() + else: + response = prev_obj + meraki.object_already_present() + else: + response = obj.create() + meraki.object_created() + + elif state == "absent": + (obj_exists, prev_obj) = obj.exists() + if obj_exists: + response = obj.delete() + meraki.object_deleted() + else: + meraki.object_already_absent() + + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/organizations_adaptive_policy_policies_info.py b/ansible_collections/cisco/meraki/plugins/action/organizations_adaptive_policy_policies_info.py new file mode 100644 index 000000000..260a8d812 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/organizations_adaptive_policy_policies_info.py @@ -0,0 +1,112 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + organizationId=dict(type="str"), + id=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_object(self, params): + new_object = {} + if params.get("organizationId") is not None: + new_object["organizationId"] = params.get( + "organizationId") + if params.get("id") is not None: + new_object["id"] = params.get( + "id") + return new_object + + def get_all(self, params): + new_object = {} + if params.get("organizationId") is not None: + new_object["organizationId"] = params.get( + "organizationId") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + id = self._task.args.get("id") + if id: + response = meraki.exec_meraki( + family="organizations", + function='getOrganizationAdaptivePolicyPolicy', + params=self.get_object(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result + if not id: + response = meraki.exec_meraki( + family="organizations", + function='getOrganizationAdaptivePolicyPolicies', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/organizations_adaptive_policy_settings.py b/ansible_collections/cisco/meraki/plugins/action/organizations_adaptive_policy_settings.py new file mode 100644 index 000000000..0c2eea1a0 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/organizations_adaptive_policy_settings.py @@ -0,0 +1,200 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or +# https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, + meraki_compare_equality, + get_dict_result, +) +from ansible_collections.cisco.meraki.plugins.plugin_utils.exceptions import ( + InconsistentParameters, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + state=dict(type="str", default="present", choices=["present"]), + enabledNetworks=dict(type="list"), + organizationId=dict(type="str"), +)) + +required_if = [ + ("state", "present", ["organizationId"], True), +] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class OrganizationsAdaptivePolicySettings(object): + def __init__(self, params, meraki): + self.meraki = meraki + self.new_object = dict( + enabledNetworks=params.get("enabledNetworks"), + organization_id=params.get("organizationId"), + ) + + def get_all_params(self, name=None, id=None): + new_object_params = {} + if self.new_object.get('organizationId') is not None or self.new_object.get('organization_id') is not None: + new_object_params['organizationId'] = self.new_object.get('organizationId') or \ + self.new_object.get('organization_id') + return new_object_params + + def update_all_params(self): + new_object_params = {} + if self.new_object.get('enabledNetworks') is not None or self.new_object.get('enabled_networks') is not None: + new_object_params['enabledNetworks'] = self.new_object.get('enabledNetworks') or \ + self.new_object.get('enabled_networks') + if self.new_object.get('organizationId') is not None or self.new_object.get('organization_id') is not None: + new_object_params['organizationId'] = self.new_object.get('organizationId') or \ + self.new_object.get('organization_id') + return new_object_params + + def get_object_by_name(self, name): + result = None + # NOTE: Does not have a get by name method, using get all + try: + items = self.meraki.exec_meraki( + family="organizations", + function="getOrganizationAdaptivePolicySettings", + params=self.get_all_params(name=name), + ) + if isinstance(items, dict): + if 'response' in items: + items = items.get('response') + result = get_dict_result(items, 'name', name) + if result is None: + result = items + except Exception as e: + print("Error: ", e) + result = None + return result + + def get_object_by_id(self, id): + result = None + # NOTE: Does not have a get by id method or it is in another action + return result + + def exists(self): + prev_obj = None + id_exists = False + name_exists = False + o_id = self.new_object.get("organizationId") or self.new_object.get("organization_id") + name = self.new_object.get("name") + if o_id: + prev_obj = self.get_object_by_name(o_id) + id_exists = prev_obj is not None and isinstance(prev_obj, dict) + if not id_exists and name: + prev_obj = self.get_object_by_name(name) + name_exists = prev_obj is not None and isinstance(prev_obj, dict) + if name_exists: + _id = prev_obj.get("id") + if id_exists and name_exists and o_id != _id: + raise InconsistentParameters( + "The 'id' and 'name' params don't refer to the same object") + if _id: + self.new_object.update(dict(id=_id)) + it_exists = prev_obj is not None and isinstance(prev_obj, dict) + return (it_exists, prev_obj) + + def requires_update(self, current_obj): + requested_obj = self.new_object + + obj_params = [ + ("enabledNetworks", "enabledNetworks"), + ("organizationId", "organizationId"), + ] + # Method 1. Params present in request (Ansible) obj are the same as the current (ISE) params + # If any does not have eq params, it requires update + return any(not meraki_compare_equality(current_obj.get(meraki_param), + requested_obj.get(ansible_param)) + for (meraki_param, ansible_param) in obj_params) + + def update(self): + id = self.new_object.get("id") + name = self.new_object.get("name") + result = None + result = self.meraki.exec_meraki( + family="organizations", + function="updateOrganizationAdaptivePolicySettings", + params=self.update_all_params(), + op_modifies=True, + ) + return result + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = False + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + meraki = MERAKI(self._task.args) + obj = OrganizationsAdaptivePolicySettings(self._task.args, meraki) + + state = self._task.args.get("state") + + response = None + if state == "present": + (obj_exists, prev_obj) = obj.exists() + if obj_exists: + if obj.requires_update(prev_obj): + response = obj.update() + meraki.object_updated() + else: + response = prev_obj + meraki.object_already_present() + else: + meraki.fail_json( + "Object does not exists, plugin only has update") + + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/organizations_adaptive_policy_settings_info.py b/ansible_collections/cisco/meraki/plugins/action/organizations_adaptive_policy_settings_info.py new file mode 100644 index 000000000..340408f8a --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/organizations_adaptive_policy_settings_info.py @@ -0,0 +1,90 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + organizationId=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_all(self, params): + new_object = {} + if params.get("organizationId") is not None: + new_object["organizationId"] = params.get( + "organizationId") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="organizations", + function='getOrganizationAdaptivePolicySettings', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/organizations_admins.py b/ansible_collections/cisco/meraki/plugins/action/organizations_admins.py new file mode 100644 index 000000000..a9b2140ef --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/organizations_admins.py @@ -0,0 +1,328 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or +# https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, + meraki_compare_equality, + get_dict_result, +) +from ansible_collections.cisco.meraki.plugins.plugin_utils.exceptions import ( + InconsistentParameters, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + state=dict(type="str", default="present", choices=["present", "absent"]), + email=dict(type="str"), + name=dict(type="str"), + orgAccess=dict(type="str"), + tags=dict(type="list"), + networks=dict(type="list"), + authenticationMethod=dict(type="str"), + organizationId=dict(type="str"), + adminId=dict(type="str"), +)) + +required_if = [ + ("state", "present", ["adminId", "name", "organizationId", "email"], True), + ("state", "absent", ["adminId", "name", "organizationId", "email"], True), +] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class OrganizationsAdmins(object): + def __init__(self, params, meraki): + self.meraki = meraki + self.new_object = dict( + email=params.get("email"), + name=params.get("name"), + orgAccess=params.get("orgAccess"), + tags=params.get("tags"), + networks=params.get("networks"), + authenticationMethod=params.get("authenticationMethod"), + organizationId=params.get("organizationId"), + adminId=params.get("adminId"), + ) + + def get_all_params(self, name=None, id=None): + new_object_params = {} + if self.new_object.get('organizationId') is not None or self.new_object.get('organization_id') is not None: + new_object_params['organizationId'] = self.new_object.get('organizationId') or \ + self.new_object.get('organization_id') + return new_object_params + + def create_params(self): + new_object_params = {} + if self.new_object.get('email') is not None or self.new_object.get('email') is not None: + new_object_params['email'] = self.new_object.get('email') or \ + self.new_object.get('email') + if self.new_object.get('name') is not None or self.new_object.get('name') is not None: + new_object_params['name'] = self.new_object.get('name') or \ + self.new_object.get('name') + if self.new_object.get('orgAccess') is not None or self.new_object.get('org_access') is not None: + new_object_params['orgAccess'] = self.new_object.get('orgAccess') or \ + self.new_object.get('org_access') + if self.new_object.get('tags') is not None or self.new_object.get('tags') is not None: + new_object_params['tags'] = self.new_object.get('tags') or \ + self.new_object.get('tags') + if self.new_object.get('networks') is not None or self.new_object.get('networks') is not None: + new_object_params['networks'] = self.new_object.get('networks') or \ + self.new_object.get('networks') + if self.new_object.get('authenticationMethod') is not None or self.new_object.get('authentication_method') is not None: + new_object_params['authenticationMethod'] = self.new_object.get('authenticationMethod') or \ + self.new_object.get('authentication_method') + if self.new_object.get('organizationId') is not None or self.new_object.get('organization_id') is not None: + new_object_params['organizationId'] = self.new_object.get('organizationId') or \ + self.new_object.get('organization_id') + return new_object_params + + def delete_by_id_params(self): + new_object_params = {} + if self.new_object.get('organizationId') is not None or self.new_object.get('organization_id') is not None: + new_object_params['organizationId'] = self.new_object.get('organizationId') or \ + self.new_object.get('organization_id') + if self.new_object.get('adminId') is not None or self.new_object.get('admin_id') is not None: + new_object_params['adminId'] = self.new_object.get('adminId') or \ + self.new_object.get('admin_id') + return new_object_params + + def update_by_id_params(self): + new_object_params = {} + if self.new_object.get('name') is not None or self.new_object.get('name') is not None: + new_object_params['name'] = self.new_object.get('name') or \ + self.new_object.get('name') + if self.new_object.get('orgAccess') is not None or self.new_object.get('org_access') is not None: + new_object_params['orgAccess'] = self.new_object.get('orgAccess') or \ + self.new_object.get('org_access') + if self.new_object.get('tags') is not None or self.new_object.get('tags') is not None: + new_object_params['tags'] = self.new_object.get('tags') or \ + self.new_object.get('tags') + if self.new_object.get('networks') is not None or self.new_object.get('networks') is not None: + new_object_params['networks'] = self.new_object.get('networks') or \ + self.new_object.get('networks') + if self.new_object.get('organizationId') is not None or self.new_object.get('organization_id') is not None: + new_object_params['organizationId'] = self.new_object.get('organizationId') or \ + self.new_object.get('organization_id') + if self.new_object.get('adminId') is not None or self.new_object.get('admin_id') is not None: + new_object_params['adminId'] = self.new_object.get('adminId') or \ + self.new_object.get('admin_id') + return new_object_params + + def get_object_by_name(self, name): + result = None + # NOTE: Does not have a get by name method or it is in another action + try: + items = self.meraki.exec_meraki( + family="organizations", + function="getOrganizationAdmins", + params=self.get_all_params(name=name), + ) + if isinstance(items, dict): + if 'response' in items: + items = items.get('response') + result = get_dict_result(items, 'email', name) + except Exception as e: + print("Error: ", e) + result = None + return result + + def get_object_by_id(self, id): + result = None + # NOTE: Does not have a get by id method or it is in another action + try: + items = self.meraki.exec_meraki( + family="organizations", + function="getOrganizationAdmins", + params=self.get_all_params(id=id), + ) + if isinstance(items, dict): + if 'response' in items: + items = items.get('response') + result = get_dict_result(items, 'id', id) + except Exception as e: + print("Error: ", e) + result = None + return result + + def exists(self): + id_exists = False + name_exists = False + prev_obj = None + o_id = self.new_object.get("id") + o_id = o_id or self.new_object.get( + "admin_id") or self.new_object.get("adminId") + name = self.new_object.get("email") + if o_id: + prev_obj = self.get_object_by_id(o_id) + id_exists = prev_obj is not None and isinstance(prev_obj, dict) + if not id_exists and name: + prev_obj = self.get_object_by_name(name) + name_exists = prev_obj is not None and isinstance(prev_obj, dict) + if name_exists: + _id = prev_obj.get("id") + _id = _id or prev_obj.get("adminId") + if id_exists and name_exists and o_id != _id: + raise InconsistentParameters( + "The 'id' and 'name' params don't refer to the same object") + if _id: + self.new_object.update(dict(id=_id)) + self.new_object.update(dict(adminId=_id)) + it_exists = prev_obj is not None and isinstance(prev_obj, dict) + return (it_exists, prev_obj) + + def requires_update(self, current_obj): + requested_obj = self.new_object + + obj_params = [ + ("email", "email"), + ("name", "name"), + ("orgAccess", "orgAccess"), + ("tags", "tags"), + ("networks", "networks"), + ("authenticationMethod", "authenticationMethod"), + ("organizationId", "organizationId"), + ("adminId", "adminId"), + ] + # Method 1. Params present in request (Ansible) obj are the same as the current (DNAC) params + # If any does not have eq params, it requires update + return any(not meraki_compare_equality(current_obj.get(meraki_param), + requested_obj.get(ansible_param)) + for (meraki_param, ansible_param) in obj_params) + + def create(self): + result = self.meraki.exec_meraki( + family="organizations", + function="createOrganizationAdmin", + params=self.create_params(), + op_modifies=True, + ) + return result + + def update(self): + id = self.new_object.get("id") + id = id or self.new_object.get("adminId") + name = self.new_object.get("email") + result = None + if not id: + prev_obj_name = self.get_object_by_name(name) + id_ = None + if prev_obj_name: + id_ = prev_obj_name.get("id") + id_ = id_ or prev_obj_name.get("adminId") + if id_: + self.new_object.update(dict(adminId=id_)) + result = self.meraki.exec_meraki( + family="organizations", + function="updateOrganizationAdmin", + params=self.update_by_id_params(), + op_modifies=True, + ) + return result + + def delete(self): + id = self.new_object.get("id") + id = id or self.new_object.get("adminId") + name = self.new_object.get("email") + result = None + if not id: + prev_obj_name = self.get_object_by_name(name) + id_ = None + if prev_obj_name: + id_ = prev_obj_name.get("id") + id_ = id_ or prev_obj_name.get("adminId") + if id_: + self.new_object.update(dict(adminId=id_)) + result = self.meraki.exec_meraki( + family="organizations", + function="deleteOrganizationAdmin", + params=self.delete_by_id_params(), + ) + return result + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = False + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + meraki = MERAKI(self._task.args) + obj = OrganizationsAdmins(self._task.args, meraki) + + state = self._task.args.get("state") + + response = None + + if state == "present": + (obj_exists, prev_obj) = obj.exists() + if obj_exists: + if obj.requires_update(prev_obj): + response = obj.update() + meraki.object_updated() + else: + response = prev_obj + meraki.object_already_present() + else: + response = obj.create() + meraki.object_created() + + elif state == "absent": + (obj_exists, prev_obj) = obj.exists() + if obj_exists: + response = obj.delete() + meraki.object_deleted() + else: + meraki.object_already_absent() + + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/organizations_admins_info.py b/ansible_collections/cisco/meraki/plugins/action/organizations_admins_info.py new file mode 100644 index 000000000..ff9b3bb71 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/organizations_admins_info.py @@ -0,0 +1,90 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + organizationId=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_all(self, params): + new_object = {} + if params.get("organizationId") is not None: + new_object["organizationId"] = params.get( + "organizationId") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="organizations", + function='getOrganizationAdmins', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/organizations_alerts_profiles.py b/ansible_collections/cisco/meraki/plugins/action/organizations_alerts_profiles.py new file mode 100644 index 000000000..cc046ea86 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/organizations_alerts_profiles.py @@ -0,0 +1,294 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or +# https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, + meraki_compare_equality, +) +from ansible_collections.cisco.meraki.plugins.plugin_utils.exceptions import ( + InconsistentParameters, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + state=dict(type="str", default="present", choices=["present", "absent"]), + type=dict(type="str"), + alertCondition=dict(type="dict"), + recipients=dict(type="dict"), + networkTags=dict(type="list"), + description=dict(type="str"), + organizationId=dict(type="str"), + enabled=dict(type="bool"), + alertConfigId=dict(type="str"), +)) + +required_if = [ + ("state", "present", ["alertConfigId", "organizationId"], True), + ("state", "absent", ["alertConfigId", "organizationId"], True), +] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class OrganizationsAlertsProfiles(object): + def __init__(self, params, meraki): + self.meraki = meraki + self.new_object = dict( + type=params.get("type"), + alertCondition=params.get("alertCondition"), + recipients=params.get("recipients"), + networkTags=params.get("networkTags"), + description=params.get("description"), + organization_id=params.get("organizationId"), + enabled=params.get("enabled"), + alert_config_id=params.get("alertConfigId"), + ) + + def create_params(self): + new_object_params = {} + if self.new_object.get('type') is not None or self.new_object.get('type') is not None: + new_object_params['type'] = self.new_object.get('type') or \ + self.new_object.get('type') + if self.new_object.get('alertCondition') is not None or self.new_object.get('alert_condition') is not None: + new_object_params['alertCondition'] = self.new_object.get('alertCondition') or \ + self.new_object.get('alert_condition') + if self.new_object.get('recipients') is not None or self.new_object.get('recipients') is not None: + new_object_params['recipients'] = self.new_object.get('recipients') or \ + self.new_object.get('recipients') + if self.new_object.get('networkTags') is not None or self.new_object.get('network_tags') is not None: + new_object_params['networkTags'] = self.new_object.get('networkTags') or \ + self.new_object.get('network_tags') + if self.new_object.get('description') is not None or self.new_object.get('description') is not None: + new_object_params['description'] = self.new_object.get('description') or \ + self.new_object.get('description') + if self.new_object.get('organizationId') is not None or self.new_object.get('organization_id') is not None: + new_object_params['organizationId'] = self.new_object.get('organizationId') or \ + self.new_object.get('organization_id') + return new_object_params + + def delete_by_id_params(self): + new_object_params = {} + if self.new_object.get('organizationId') is not None or self.new_object.get('organization_id') is not None: + new_object_params['organizationId'] = self.new_object.get('organizationId') or \ + self.new_object.get('organization_id') + if self.new_object.get('alertConfigId') is not None or self.new_object.get('alert_config_id') is not None: + new_object_params['alertConfigId'] = self.new_object.get('alertConfigId') or \ + self.new_object.get('alert_config_id') + return new_object_params + + def update_by_id_params(self): + new_object_params = {} + if self.new_object.get('enabled') is not None or self.new_object.get('enabled') is not None: + new_object_params['enabled'] = self.new_object.get('enabled') + if self.new_object.get('type') is not None or self.new_object.get('type') is not None: + new_object_params['type'] = self.new_object.get('type') or \ + self.new_object.get('type') + if self.new_object.get('alertCondition') is not None or self.new_object.get('alert_condition') is not None: + new_object_params['alertCondition'] = self.new_object.get('alertCondition') or \ + self.new_object.get('alert_condition') + if self.new_object.get('recipients') is not None or self.new_object.get('recipients') is not None: + new_object_params['recipients'] = self.new_object.get('recipients') or \ + self.new_object.get('recipients') + if self.new_object.get('networkTags') is not None or self.new_object.get('network_tags') is not None: + new_object_params['networkTags'] = self.new_object.get('networkTags') or \ + self.new_object.get('network_tags') + if self.new_object.get('description') is not None or self.new_object.get('description') is not None: + new_object_params['description'] = self.new_object.get('description') or \ + self.new_object.get('description') + if self.new_object.get('organizationId') is not None or self.new_object.get('organization_id') is not None: + new_object_params['organizationId'] = self.new_object.get('organizationId') or \ + self.new_object.get('organization_id') + if self.new_object.get('alertConfigId') is not None or self.new_object.get('alert_config_id') is not None: + new_object_params['alertConfigId'] = self.new_object.get('alertConfigId') or \ + self.new_object.get('alert_config_id') + return new_object_params + + def get_object_by_name(self, name): + result = None + # NOTE: Does not have a get by name and get all + return result + + def get_object_by_id(self, id): + result = None + # NOTE: Does not have a get by id method or it is in another action + return result + + def exists(self): + prev_obj = None + id_exists = False + name_exists = False + o_id = self.new_object.get("id") + o_id = o_id or self.new_object.get( + "alert_config_id") or self.new_object.get("alertConfigId") + name = self.new_object.get("name") + if o_id: + prev_obj = self.get_object_by_name(o_id) + id_exists = prev_obj is not None and isinstance(prev_obj, dict) + if not id_exists and name: + prev_obj = self.get_object_by_name(name) + name_exists = prev_obj is not None and isinstance(prev_obj, dict) + if name_exists: + _id = prev_obj.get("id") + _id = _id or prev_obj.get("alertConfigId") + if id_exists and name_exists and o_id != _id: + raise InconsistentParameters( + "The 'id' and 'name' params don't refer to the same object") + if _id: + self.new_object.update(dict(id=_id)) + self.new_object.update(dict(alertConfigId=_id)) + it_exists = prev_obj is not None and isinstance(prev_obj, dict) + return (it_exists, prev_obj) + + def requires_update(self, current_obj): + requested_obj = self.new_object + + obj_params = [ + ("type", "type"), + ("alertCondition", "alertCondition"), + ("recipients", "recipients"), + ("networkTags", "networkTags"), + ("description", "description"), + ("organizationId", "organizationId"), + ("enabled", "enabled"), + ("alertConfigId", "alertConfigId"), + ] + # Method 1. Params present in request (Ansible) obj are the same as the current (ISE) params + # If any does not have eq params, it requires update + return any(not meraki_compare_equality(current_obj.get(meraki_param), + requested_obj.get(ansible_param)) + for (meraki_param, ansible_param) in obj_params) + + def create(self): + result = self.meraki.exec_meraki( + family="organizations", + function="createOrganizationAlertsProfile", + params=self.create_params(), + op_modifies=True, + ) + return result + + def update(self): + id = self.new_object.get("id") + id = id or self.new_object.get("alertConfigId") + name = self.new_object.get("name") + result = None + if not id: + prev_obj_name = self.get_object_by_name(name) + id_ = None + if prev_obj_name: + id_ = prev_obj_name.get("id") + id_ = id_ or prev_obj_name.get("alertConfigId") + if id_: + self.new_object.update(dict(alertconfigid=id_)) + result = self.meraki.exec_meraki( + family="organizations", + function="updateOrganizationAlertsProfile", + params=self.update_by_id_params(), + op_modifies=True, + ) + return result + + def delete(self): + id = self.new_object.get("id") + id = id or self.new_object.get("alertConfigId") + name = self.new_object.get("name") + result = None + if not id: + prev_obj_name = self.get_object_by_name(name) + id_ = None + if prev_obj_name: + id_ = prev_obj_name.get("id") + id_ = id_ or prev_obj_name.get("alertConfigId") + if id_: + self.new_object.update(dict(alertconfigid=id_)) + result = self.meraki.exec_meraki( + family="organizations", + function="deleteOrganizationAlertsProfile", + params=self.delete_by_id_params(), + ) + return result + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = False + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + meraki = MERAKI(self._task.args) + obj = OrganizationsAlertsProfiles(self._task.args, meraki) + + state = self._task.args.get("state") + + response = None + if state == "present": + (obj_exists, prev_obj) = obj.exists() + if obj_exists: + if obj.requires_update(prev_obj): + response = obj.update() + meraki.object_updated() + else: + response = prev_obj + meraki.object_already_present() + else: + response = obj.create() + meraki.object_created() + elif state == "absent": + (obj_exists, prev_obj) = obj.exists() + if obj_exists: + response = obj.delete() + meraki.object_deleted() + else: + meraki.object_already_absent() + + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/organizations_api_requests_info.py b/ansible_collections/cisco/meraki/plugins/action/organizations_api_requests_info.py new file mode 100644 index 000000000..a68ef4b2e --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/organizations_api_requests_info.py @@ -0,0 +1,152 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + organizationId=dict(type="str"), + t0=dict(type="str"), + t1=dict(type="str"), + timespan=dict(type="float"), + perPage=dict(type="int"), + total_pages=dict(type="int"), + direction=dict(type="str"), + startingAfter=dict(type="str"), + endingBefore=dict(type="str"), + adminId=dict(type="str"), + path=dict(type="str"), + method=dict(type="str"), + responseCode=dict(type="int"), + sourceIp=dict(type="str"), + userAgent=dict(type="str"), + version=dict(type="int"), + operationIds=dict(type="list"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_all(self, params): + new_object = {} + if params.get("organizationId") is not None: + new_object["organizationId"] = params.get( + "organizationId") + if params.get("t0") is not None: + new_object["t0"] = params.get( + "t0") + if params.get("t1") is not None: + new_object["t1"] = params.get( + "t1") + if params.get("timespan") is not None: + new_object["timespan"] = params.get( + "timespan") + if params.get("perPage") is not None: + new_object["perPage"] = params.get( + "perPage") + new_object['total_pages'] = params.get( + "total_pages") or 1 + new_object['direction'] = params.get( + "direction") or "next" + if params.get("startingAfter") is not None: + new_object["startingAfter"] = params.get( + "startingAfter") + if params.get("endingBefore") is not None: + new_object["endingBefore"] = params.get( + "endingBefore") + if params.get("adminId") is not None: + new_object["adminId"] = params.get( + "adminId") + if params.get("path") is not None: + new_object["path"] = params.get( + "path") + if params.get("method") is not None: + new_object["method"] = params.get( + "method") + if params.get("responseCode") is not None: + new_object["responseCode"] = params.get( + "responseCode") + if params.get("sourceIp") is not None: + new_object["sourceIp"] = params.get( + "sourceIp") + if params.get("userAgent") is not None: + new_object["userAgent"] = params.get( + "userAgent") + if params.get("version") is not None: + new_object["version"] = params.get( + "version") + if params.get("operationIds") is not None: + new_object["operationIds"] = params.get( + "operationIds") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="organizations", + function='getOrganizationApiRequests', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/organizations_api_requests_overview_info.py b/ansible_collections/cisco/meraki/plugins/action/organizations_api_requests_overview_info.py new file mode 100644 index 000000000..7e4ea1f14 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/organizations_api_requests_overview_info.py @@ -0,0 +1,102 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + organizationId=dict(type="str"), + t0=dict(type="str"), + t1=dict(type="str"), + timespan=dict(type="float"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_all(self, params): + new_object = {} + if params.get("organizationId") is not None: + new_object["organizationId"] = params.get( + "organizationId") + if params.get("t0") is not None: + new_object["t0"] = params.get( + "t0") + if params.get("t1") is not None: + new_object["t1"] = params.get( + "t1") + if params.get("timespan") is not None: + new_object["timespan"] = params.get( + "timespan") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="organizations", + function='getOrganizationApiRequestsOverview', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/organizations_api_requests_overview_response_codes_by_interval_info.py b/ansible_collections/cisco/meraki/plugins/action/organizations_api_requests_overview_response_codes_by_interval_info.py new file mode 100644 index 000000000..f8a0c624d --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/organizations_api_requests_overview_response_codes_by_interval_info.py @@ -0,0 +1,126 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + organizationId=dict(type="str"), + t0=dict(type="str"), + t1=dict(type="str"), + timespan=dict(type="float"), + interval=dict(type="int"), + version=dict(type="int"), + operationIds=dict(type="list"), + sourceIps=dict(type="list"), + adminIds=dict(type="list"), + userAgent=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_all(self, params): + new_object = {} + if params.get("organizationId") is not None: + new_object["organizationId"] = params.get( + "organizationId") + if params.get("t0") is not None: + new_object["t0"] = params.get( + "t0") + if params.get("t1") is not None: + new_object["t1"] = params.get( + "t1") + if params.get("timespan") is not None: + new_object["timespan"] = params.get( + "timespan") + if params.get("interval") is not None: + new_object["interval"] = params.get( + "interval") + if params.get("version") is not None: + new_object["version"] = params.get( + "version") + if params.get("operationIds") is not None: + new_object["operationIds"] = params.get( + "operationIds") + if params.get("sourceIps") is not None: + new_object["sourceIps"] = params.get( + "sourceIps") + if params.get("adminIds") is not None: + new_object["adminIds"] = params.get( + "adminIds") + if params.get("userAgent") is not None: + new_object["userAgent"] = params.get( + "userAgent") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="organizations", + function='getOrganizationApiRequestsOverviewResponseCodesByInterval', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/organizations_appliance_security_intrusion.py b/ansible_collections/cisco/meraki/plugins/action/organizations_appliance_security_intrusion.py new file mode 100644 index 000000000..708c371d2 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/organizations_appliance_security_intrusion.py @@ -0,0 +1,200 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or +# https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, + meraki_compare_equality, + get_dict_result, +) +from ansible_collections.cisco.meraki.plugins.plugin_utils.exceptions import ( + InconsistentParameters, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + state=dict(type="str", default="present", choices=["present"]), + allowedRules=dict(type="list"), + organizationId=dict(type="str"), +)) + +required_if = [ + ("state", "present", ["organizationId"], True), +] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class OrganizationsApplianceSecurityIntrusion(object): + def __init__(self, params, meraki): + self.meraki = meraki + self.new_object = dict( + allowedRules=params.get("allowedRules"), + organization_id=params.get("organizationId"), + ) + + def get_all_params(self, name=None, id=None): + new_object_params = {} + if self.new_object.get('organizationId') is not None or self.new_object.get('organization_id') is not None: + new_object_params['organizationId'] = self.new_object.get('organizationId') or \ + self.new_object.get('organization_id') + return new_object_params + + def update_all_params(self): + new_object_params = {} + if self.new_object.get('allowedRules') is not None or self.new_object.get('allowed_rules') is not None: + new_object_params['allowedRules'] = self.new_object.get('allowedRules') or \ + self.new_object.get('allowed_rules') + if self.new_object.get('organizationId') is not None or self.new_object.get('organization_id') is not None: + new_object_params['organizationId'] = self.new_object.get('organizationId') or \ + self.new_object.get('organization_id') + return new_object_params + + def get_object_by_name(self, name): + result = None + # NOTE: Does not have a get by name method, using get all + try: + items = self.meraki.exec_meraki( + family="appliance", + function="getOrganizationApplianceSecurityIntrusion", + params=self.get_all_params(name=name), + ) + if isinstance(items, dict): + if 'response' in items: + items = items.get('response') + result = get_dict_result(items, 'name', name) + if result is None: + result = items + except Exception as e: + print("Error: ", e) + result = None + return result + + def get_object_by_id(self, id): + result = None + # NOTE: Does not have a get by id method or it is in another action + return result + + def exists(self): + prev_obj = None + id_exists = False + name_exists = False + o_id = self.new_object.get("id") + name = self.new_object.get("name") + if o_id: + prev_obj = self.get_object_by_name(o_id) + id_exists = prev_obj is not None and isinstance(prev_obj, dict) + if not id_exists and name: + prev_obj = self.get_object_by_name(name) + name_exists = prev_obj is not None and isinstance(prev_obj, dict) + if name_exists: + _id = prev_obj.get("id") + if id_exists and name_exists and o_id != _id: + raise InconsistentParameters( + "The 'id' and 'name' params don't refer to the same object") + if _id: + self.new_object.update(dict(id=_id)) + it_exists = prev_obj is not None and isinstance(prev_obj, dict) + return (it_exists, prev_obj) + + def requires_update(self, current_obj): + requested_obj = self.new_object + + obj_params = [ + ("allowedRules", "allowedRules"), + ("organizationId", "organizationId"), + ] + # Method 1. Params present in request (Ansible) obj are the same as the current (ISE) params + # If any does not have eq params, it requires update + return any(not meraki_compare_equality(current_obj.get(meraki_param), + requested_obj.get(ansible_param)) + for (meraki_param, ansible_param) in obj_params) + + def update(self): + id = self.new_object.get("id") + name = self.new_object.get("name") + result = None + result = self.meraki.exec_meraki( + family="appliance", + function="updateOrganizationApplianceSecurityIntrusion", + params=self.update_all_params(), + op_modifies=True, + ) + return result + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = False + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + meraki = MERAKI(self._task.args) + obj = OrganizationsApplianceSecurityIntrusion(self._task.args, meraki) + + state = self._task.args.get("state") + + response = None + if state == "present": + (obj_exists, prev_obj) = obj.exists() + if obj_exists: + if obj.requires_update(prev_obj): + response = obj.update() + meraki.object_updated() + else: + response = prev_obj + meraki.object_already_present() + else: + meraki.fail_json( + "Object does not exists, plugin only has update") + + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/organizations_appliance_security_intrusion_info.py b/ansible_collections/cisco/meraki/plugins/action/organizations_appliance_security_intrusion_info.py new file mode 100644 index 000000000..216d7b562 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/organizations_appliance_security_intrusion_info.py @@ -0,0 +1,90 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + organizationId=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_all(self, params): + new_object = {} + if params.get("organizationId") is not None: + new_object["organizationId"] = params.get( + "organizationId") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="appliance", + function='getOrganizationApplianceSecurityIntrusion', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/organizations_appliance_vpn_third_party_vpnpeers.py b/ansible_collections/cisco/meraki/plugins/action/organizations_appliance_vpn_third_party_vpnpeers.py new file mode 100644 index 000000000..a6f63c5a4 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/organizations_appliance_vpn_third_party_vpnpeers.py @@ -0,0 +1,200 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or +# https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, + meraki_compare_equality, + get_dict_result, +) +from ansible_collections.cisco.meraki.plugins.plugin_utils.exceptions import ( + InconsistentParameters, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + state=dict(type="str", default="present", choices=["present"]), + peers=dict(type="list"), + organizationId=dict(type="str"), +)) + +required_if = [ + ("state", "present", ["organizationId"], True), +] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class OrganizationsApplianceVpnThirdPartyVpnpeers(object): + def __init__(self, params, meraki): + self.meraki = meraki + self.new_object = dict( + peers=params.get("peers"), + organization_id=params.get("organizationId"), + ) + + def get_all_params(self, name=None, id=None): + new_object_params = {} + if self.new_object.get('organizationId') is not None or self.new_object.get('organization_id') is not None: + new_object_params['organizationId'] = self.new_object.get('organizationId') or \ + self.new_object.get('organization_id') + return new_object_params + + def update_all_params(self): + new_object_params = {} + if self.new_object.get('peers') is not None or self.new_object.get('peers') is not None: + new_object_params['peers'] = self.new_object.get('peers') or \ + self.new_object.get('peers') + if self.new_object.get('organizationId') is not None or self.new_object.get('organization_id') is not None: + new_object_params['organizationId'] = self.new_object.get('organizationId') or \ + self.new_object.get('organization_id') + return new_object_params + + def get_object_by_name(self, name): + result = None + # NOTE: Does not have a get by name method, using get all + try: + items = self.meraki.exec_meraki( + family="appliance", + function="getOrganizationApplianceVpnThirdPartyVpnpeers", + params=self.get_all_params(name=name), + ) + if isinstance(items, dict): + if 'peers' in items: + items = items.get('peers') + result = get_dict_result(items, 'name', name) + if result is None: + result = items + except Exception as e: + print("Error: ", e) + result = None + return result + + def get_object_by_id(self, id): + result = None + # NOTE: Does not have a get by id method or it is in another action + return result + + def exists(self): + prev_obj = None + id_exists = False + name_exists = False + o_id = self.new_object.get("id") + name = self.new_object.get("name") + if o_id: + prev_obj = self.get_object_by_name(o_id) + id_exists = prev_obj is not None and isinstance(prev_obj, dict) + if not id_exists and name: + prev_obj = self.get_object_by_name(name) + name_exists = prev_obj is not None and isinstance(prev_obj, dict) + if name_exists: + _id = prev_obj.get("id") + if id_exists and name_exists and o_id != _id: + raise InconsistentParameters( + "The 'id' and 'name' params don't refer to the same object") + if _id: + self.new_object.update(dict(id=_id)) + it_exists = prev_obj is not None and isinstance(prev_obj, dict) + return (it_exists, prev_obj) + + def requires_update(self, current_obj): + requested_obj = self.new_object + + obj_params = [ + ("peers", "peers"), + ("organizationId", "organizationId"), + ] + # Method 1. Params present in request (Ansible) obj are the same as the current (ISE) params + # If any does not have eq params, it requires update + return any(not meraki_compare_equality(current_obj.get(meraki_param), + requested_obj.get(ansible_param)) + for (meraki_param, ansible_param) in obj_params) + + def update(self): + id = self.new_object.get("id") + name = self.new_object.get("name") + result = None + result = self.meraki.exec_meraki( + family="appliance", + function="updateOrganizationApplianceVpnThirdPartyVpnpeers", + params=self.update_all_params(), + op_modifies=True, + ) + return result + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = False + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + meraki = MERAKI(self._task.args) + obj = OrganizationsApplianceVpnThirdPartyVpnpeers(self._task.args, meraki) + + state = self._task.args.get("state") + + response = None + if state == "present": + (obj_exists, prev_obj) = obj.exists() + if obj_exists: + if obj.requires_update(prev_obj): + response = obj.update() + meraki.object_updated() + else: + response = prev_obj + meraki.object_already_present() + else: + meraki.fail_json( + "Object does not exists, plugin only has update") + + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/organizations_appliance_vpn_third_party_vpnpeers_info.py b/ansible_collections/cisco/meraki/plugins/action/organizations_appliance_vpn_third_party_vpnpeers_info.py new file mode 100644 index 000000000..69f7bd061 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/organizations_appliance_vpn_third_party_vpnpeers_info.py @@ -0,0 +1,90 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + organizationId=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_all(self, params): + new_object = {} + if params.get("organizationId") is not None: + new_object["organizationId"] = params.get( + "organizationId") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="appliance", + function='getOrganizationApplianceVpnThirdPartyVpnpeers', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/organizations_appliance_vpn_vpn_firewall_rules.py b/ansible_collections/cisco/meraki/plugins/action/organizations_appliance_vpn_vpn_firewall_rules.py new file mode 100644 index 000000000..90a36ac64 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/organizations_appliance_vpn_vpn_firewall_rules.py @@ -0,0 +1,205 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or +# https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, + meraki_compare_equality, + get_dict_result, +) +from ansible_collections.cisco.meraki.plugins.plugin_utils.exceptions import ( + InconsistentParameters, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + state=dict(type="str", default="present", choices=["present"]), + rules=dict(type="list"), + syslogDefaultRule=dict(type="bool"), + organizationId=dict(type="str"), +)) + +required_if = [ + ("state", "present", ["organizationId"], True), +] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class OrganizationsApplianceVpnVpnFirewallRules(object): + def __init__(self, params, meraki): + self.meraki = meraki + self.new_object = dict( + rules=params.get("rules"), + syslogDefaultRule=params.get("syslogDefaultRule"), + organization_id=params.get("organizationId"), + ) + + def get_all_params(self, name=None, id=None): + new_object_params = {} + if self.new_object.get('organizationId') is not None or self.new_object.get('organization_id') is not None: + new_object_params['organizationId'] = self.new_object.get('organizationId') or \ + self.new_object.get('organization_id') + return new_object_params + + def update_all_params(self): + new_object_params = {} + if self.new_object.get('rules') is not None or self.new_object.get('rules') is not None: + new_object_params['rules'] = self.new_object.get('rules') or \ + self.new_object.get('rules') + if self.new_object.get('syslogDefaultRule') is not None or self.new_object.get('syslog_default_rule') is not None: + new_object_params['syslogDefaultRule'] = self.new_object.get('syslogDefaultRule') + if self.new_object.get('organizationId') is not None or self.new_object.get('organization_id') is not None: + new_object_params['organizationId'] = self.new_object.get('organizationId') or \ + self.new_object.get('organization_id') + return new_object_params + + def get_object_by_name(self, name): + result = None + # NOTE: Does not have a get by name method, using get all + try: + items = self.meraki.exec_meraki( + family="appliance", + function="getOrganizationApplianceVpnVpnFirewallRules", + params=self.get_all_params(name=name), + ) + if isinstance(items, dict): + if 'response' in items: + items = items.get('response') + result = get_dict_result(items, 'name', name) + if result is None: + result = items + except Exception as e: + print("Error: ", e) + result = None + return result + + def get_object_by_id(self, id): + result = None + # NOTE: Does not have a get by id method or it is in another action + return result + + def exists(self): + prev_obj = None + id_exists = False + name_exists = False + o_id = self.new_object.get("organizationId") or self.new_object.get("organization_id") + name = self.new_object.get("name") + if o_id: + prev_obj = self.get_object_by_name(o_id) + id_exists = prev_obj is not None and isinstance(prev_obj, dict) + if not id_exists and name: + prev_obj = self.get_object_by_name(name) + name_exists = prev_obj is not None and isinstance(prev_obj, dict) + if name_exists: + _id = prev_obj.get("id") + if id_exists and name_exists and o_id != _id: + raise InconsistentParameters( + "The 'id' and 'name' params don't refer to the same object") + if _id: + self.new_object.update(dict(id=_id)) + it_exists = prev_obj is not None and isinstance(prev_obj, dict) + return (it_exists, prev_obj) + + def requires_update(self, current_obj): + requested_obj = self.new_object + + obj_params = [ + ("rules", "rules"), + ("syslogDefaultRule", "syslogDefaultRule"), + ("organizationId", "organizationId"), + ] + # Method 1. Params present in request (Ansible) obj are the same as the current (ISE) params + # If any does not have eq params, it requires update + return any(not meraki_compare_equality(current_obj.get(meraki_param), + requested_obj.get(ansible_param)) + for (meraki_param, ansible_param) in obj_params) + + def update(self): + id = self.new_object.get("id") + name = self.new_object.get("name") + result = None + result = self.meraki.exec_meraki( + family="appliance", + function="updateOrganizationApplianceVpnVpnFirewallRules", + params=self.update_all_params(), + op_modifies=True, + ) + return result + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = False + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + meraki = MERAKI(self._task.args) + obj = OrganizationsApplianceVpnVpnFirewallRules(self._task.args, meraki) + + state = self._task.args.get("state") + + response = None + if state == "present": + (obj_exists, prev_obj) = obj.exists() + if obj_exists: + if obj.requires_update(prev_obj): + response = obj.update() + meraki.object_updated() + else: + response = prev_obj + meraki.object_already_present() + else: + meraki.fail_json( + "Object does not exists, plugin only has update") + + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/organizations_appliance_vpn_vpn_firewall_rules_info.py b/ansible_collections/cisco/meraki/plugins/action/organizations_appliance_vpn_vpn_firewall_rules_info.py new file mode 100644 index 000000000..b9eea19d3 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/organizations_appliance_vpn_vpn_firewall_rules_info.py @@ -0,0 +1,90 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + organizationId=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_all(self, params): + new_object = {} + if params.get("organizationId") is not None: + new_object["organizationId"] = params.get( + "organizationId") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="appliance", + function='getOrganizationApplianceVpnVpnFirewallRules', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/organizations_branding_policies.py b/ansible_collections/cisco/meraki/plugins/action/organizations_branding_policies.py new file mode 100644 index 000000000..870c0370e --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/organizations_branding_policies.py @@ -0,0 +1,336 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or +# https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, + meraki_compare_equality, + get_dict_result, +) +from ansible_collections.cisco.meraki.plugins.plugin_utils.exceptions import ( + InconsistentParameters, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + state=dict(type="str", default="present", choices=["present", "absent"]), + name=dict(type="str"), + enabled=dict(type="bool"), + adminSettings=dict(type="dict"), + helpSettings=dict(type="dict"), + customLogo=dict(type="dict"), + organizationId=dict(type="str"), + brandingPolicyId=dict(type="str"), +)) + +required_if = [ + ("state", "present", ["brandingPolicyId", "name", "organizationId"], True), + ("state", "absent", ["brandingPolicyId", "name", "organizationId"], True), +] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class OrganizationsBrandingPolicies(object): + def __init__(self, params, meraki): + self.meraki = meraki + self.new_object = dict( + name=params.get("name"), + enabled=params.get("enabled"), + adminSettings=params.get("adminSettings"), + helpSettings=params.get("helpSettings"), + customLogo=params.get("customLogo"), + organizationId=params.get("organizationId"), + brandingPolicyId=params.get("brandingPolicyId"), + ) + + def get_all_params(self, name=None, id=None): + new_object_params = {} + if self.new_object.get('organizationId') is not None or self.new_object.get('organization_id') is not None: + new_object_params['organizationId'] = self.new_object.get('organizationId') or \ + self.new_object.get('organization_id') + return new_object_params + + def get_params_by_id(self, name=None, id=None): + new_object_params = {} + if self.new_object.get('organizationId') is not None or self.new_object.get('organization_id') is not None: + new_object_params['organizationId'] = self.new_object.get('organizationId') or \ + self.new_object.get('organization_id') + if self.new_object.get('brandingPolicyId') is not None or self.new_object.get('branding_policy_id') is not None: + new_object_params['brandingPolicyId'] = self.new_object.get('brandingPolicyId') or \ + self.new_object.get('branding_policy_id') + return new_object_params + + def create_params(self): + new_object_params = {} + if self.new_object.get('name') is not None or self.new_object.get('name') is not None: + new_object_params['name'] = self.new_object.get('name') or \ + self.new_object.get('name') + if self.new_object.get('enabled') is not None or self.new_object.get('enabled') is not None: + new_object_params['enabled'] = self.new_object.get('enabled') + if self.new_object.get('adminSettings') is not None or self.new_object.get('admin_settings') is not None: + new_object_params['adminSettings'] = self.new_object.get('adminSettings') or \ + self.new_object.get('admin_settings') + if self.new_object.get('helpSettings') is not None or self.new_object.get('help_settings') is not None: + new_object_params['helpSettings'] = self.new_object.get('helpSettings') or \ + self.new_object.get('help_settings') + if self.new_object.get('customLogo') is not None or self.new_object.get('custom_logo') is not None: + new_object_params['customLogo'] = self.new_object.get('customLogo') or \ + self.new_object.get('custom_logo') + if self.new_object.get('organizationId') is not None or self.new_object.get('organization_id') is not None: + new_object_params['organizationId'] = self.new_object.get('organizationId') or \ + self.new_object.get('organization_id') + return new_object_params + + def delete_by_id_params(self): + new_object_params = {} + if self.new_object.get('organizationId') is not None or self.new_object.get('organization_id') is not None: + new_object_params['organizationId'] = self.new_object.get('organizationId') or \ + self.new_object.get('organization_id') + if self.new_object.get('brandingPolicyId') is not None or self.new_object.get('branding_policy_id') is not None: + new_object_params['brandingPolicyId'] = self.new_object.get('brandingPolicyId') or \ + self.new_object.get('branding_policy_id') + return new_object_params + + def update_by_id_params(self): + new_object_params = {} + if self.new_object.get('name') is not None or self.new_object.get('name') is not None: + new_object_params['name'] = self.new_object.get('name') or \ + self.new_object.get('name') + if self.new_object.get('enabled') is not None or self.new_object.get('enabled') is not None: + new_object_params['enabled'] = self.new_object.get('enabled') + if self.new_object.get('adminSettings') is not None or self.new_object.get('admin_settings') is not None: + new_object_params['adminSettings'] = self.new_object.get('adminSettings') or \ + self.new_object.get('admin_settings') + if self.new_object.get('helpSettings') is not None or self.new_object.get('help_settings') is not None: + new_object_params['helpSettings'] = self.new_object.get('helpSettings') or \ + self.new_object.get('help_settings') + if self.new_object.get('customLogo') is not None or self.new_object.get('custom_logo') is not None: + new_object_params['customLogo'] = self.new_object.get('customLogo') or \ + self.new_object.get('custom_logo') + if self.new_object.get('organizationId') is not None or self.new_object.get('organization_id') is not None: + new_object_params['organizationId'] = self.new_object.get('organizationId') or \ + self.new_object.get('organization_id') + if self.new_object.get('brandingPolicyId') is not None or self.new_object.get('branding_policy_id') is not None: + new_object_params['brandingPolicyId'] = self.new_object.get('brandingPolicyId') or \ + self.new_object.get('branding_policy_id') + return new_object_params + + def get_object_by_name(self, name): + result = None + # NOTE: Does not have a get by name method or it is in another action + try: + items = self.meraki.exec_meraki( + family="organizations", + function="getOrganizationBrandingPolicies", + params=self.get_all_params(name=name), + ) + if isinstance(items, dict): + if 'response' in items: + items = items.get('response') + result = get_dict_result(items, 'name', name) + if result is None: + result = items + except Exception as e: + print("Error: ", e) + result = None + return result + + def get_object_by_id(self, id): + result = None + try: + items = self.meraki.exec_meraki( + family="organizations", + function="getOrganizationBrandingPolicy", + params=self.get_params_by_id() + ) + if isinstance(items, dict): + if 'response' in items: + items = items.get('response') + result = get_dict_result(items, 'brandingPolicyId', id) + except Exception as e: + print("Error: ", e) + result = None + return result + + def exists(self): + id_exists = False + name_exists = False + prev_obj = None + o_id = self.new_object.get("id") + o_id = o_id or self.new_object.get( + "branding_policy_id") or self.new_object.get("brandingPolicyId") + name = self.new_object.get("name") + if o_id: + prev_obj = self.get_object_by_id(o_id) + id_exists = prev_obj is not None and isinstance(prev_obj, dict) + if not id_exists and name: + prev_obj = self.get_object_by_name(name) + name_exists = prev_obj is not None and isinstance(prev_obj, dict) + if name_exists: + _id = prev_obj.get("id") + _id = _id or prev_obj.get("brandingPolicyId") + if id_exists and name_exists and o_id != _id: + raise InconsistentParameters( + "The 'id' and 'name' params don't refer to the same object") + if _id: + self.new_object.update(dict(id=_id)) + self.new_object.update(dict(brandingPolicyId=_id)) + if _id: + prev_obj = self.get_object_by_id(_id) + it_exists = prev_obj is not None and isinstance(prev_obj, dict) + return (it_exists, prev_obj) + + def requires_update(self, current_obj): + requested_obj = self.new_object + + obj_params = [ + ("name", "name"), + ("enabled", "enabled"), + ("adminSettings", "adminSettings"), + ("helpSettings", "helpSettings"), + ("customLogo", "customLogo"), + ("organizationId", "organizationId"), + ("brandingPolicyId", "brandingPolicyId"), + ] + # Method 1. Params present in request (Ansible) obj are the same as the current (DNAC) params + # If any does not have eq params, it requires update + return any(not meraki_compare_equality(current_obj.get(meraki_param), + requested_obj.get(ansible_param)) + for (meraki_param, ansible_param) in obj_params) + + def create(self): + result = self.meraki.exec_meraki( + family="organizations", + function="createOrganizationBrandingPolicy", + params=self.create_params(), + op_modifies=True, + ) + return result + + def update(self): + id = self.new_object.get("id") + id = id or self.new_object.get("brandingPolicyId") + name = self.new_object.get("name") + result = None + if not id: + prev_obj_name = self.get_object_by_name(name) + id_ = None + if prev_obj_name: + id_ = prev_obj_name.get("id") + id_ = id_ or prev_obj_name.get("brandingPolicyId") + if id_: + self.new_object.update(dict(brandingPolicyId=id_)) + result = self.meraki.exec_meraki( + family="organizations", + function="updateOrganizationBrandingPolicy", + params=self.update_by_id_params(), + op_modifies=True, + ) + return result + + def delete(self): + id = self.new_object.get("id") + id = id or self.new_object.get("brandingPolicyId") + name = self.new_object.get("name") + result = None + if not id: + prev_obj_name = self.get_object_by_name(name) + id_ = None + if prev_obj_name: + id_ = prev_obj_name.get("id") + id_ = id_ or prev_obj_name.get("brandingPolicyId") + if id_: + self.new_object.update(dict(brandingPolicyId=id_)) + result = self.meraki.exec_meraki( + family="organizations", + function="deleteOrganizationBrandingPolicy", + params=self.delete_by_id_params(), + ) + return result + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = False + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + meraki = MERAKI(self._task.args) + obj = OrganizationsBrandingPolicies(self._task.args, meraki) + + state = self._task.args.get("state") + + response = None + + if state == "present": + (obj_exists, prev_obj) = obj.exists() + if obj_exists: + if obj.requires_update(prev_obj): + response = obj.update() + meraki.object_updated() + else: + response = prev_obj + meraki.object_already_present() + else: + response = obj.create() + meraki.object_created() + + elif state == "absent": + (obj_exists, prev_obj) = obj.exists() + if obj_exists: + response = obj.delete() + meraki.object_deleted() + else: + meraki.object_already_absent() + + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/organizations_branding_policies_info.py b/ansible_collections/cisco/meraki/plugins/action/organizations_branding_policies_info.py new file mode 100644 index 000000000..050ca502b --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/organizations_branding_policies_info.py @@ -0,0 +1,112 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + organizationId=dict(type="str"), + brandingPolicyId=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_object(self, params): + new_object = {} + if params.get("organizationId") is not None: + new_object["organizationId"] = params.get( + "organizationId") + if params.get("brandingPolicyId") is not None: + new_object["brandingPolicyId"] = params.get( + "brandingPolicyId") + return new_object + + def get_all(self, params): + new_object = {} + if params.get("organizationId") is not None: + new_object["organizationId"] = params.get( + "organizationId") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + id = self._task.args.get("brandingPolicyId") + if id: + response = meraki.exec_meraki( + family="organizations", + function='getOrganizationBrandingPolicy', + params=self.get_object(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result + if not id: + response = meraki.exec_meraki( + family="organizations", + function='getOrganizationBrandingPolicies', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/organizations_branding_policies_priorities.py b/ansible_collections/cisco/meraki/plugins/action/organizations_branding_policies_priorities.py new file mode 100644 index 000000000..a0166570d --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/organizations_branding_policies_priorities.py @@ -0,0 +1,200 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or +# https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, + meraki_compare_equality, + get_dict_result, +) +from ansible_collections.cisco.meraki.plugins.plugin_utils.exceptions import ( + InconsistentParameters, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + state=dict(type="str", default="present", choices=["present"]), + brandingPolicyIds=dict(type="list"), + organizationId=dict(type="str"), +)) + +required_if = [ + ("state", "present", ["organizationId"], True), +] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class OrganizationsBrandingPoliciesPriorities(object): + def __init__(self, params, meraki): + self.meraki = meraki + self.new_object = dict( + brandingPolicyIds=params.get("brandingPolicyIds"), + organization_id=params.get("organizationId"), + ) + + def get_all_params(self, name=None, id=None): + new_object_params = {} + if self.new_object.get('organizationId') is not None or self.new_object.get('organization_id') is not None: + new_object_params['organizationId'] = self.new_object.get('organizationId') or \ + self.new_object.get('organization_id') + return new_object_params + + def update_all_params(self): + new_object_params = {} + if self.new_object.get('brandingPolicyIds') is not None or self.new_object.get('branding_policy_ids') is not None: + new_object_params['brandingPolicyIds'] = self.new_object.get('brandingPolicyIds') or \ + self.new_object.get('branding_policy_ids') + if self.new_object.get('organizationId') is not None or self.new_object.get('organization_id') is not None: + new_object_params['organizationId'] = self.new_object.get('organizationId') or \ + self.new_object.get('organization_id') + return new_object_params + + def get_object_by_name(self, name): + result = None + # NOTE: Does not have a get by name method, using get all + try: + items = self.meraki.exec_meraki( + family="organizations", + function="getOrganizationBrandingPoliciesPriorities", + params=self.get_all_params(name=name), + ) + if isinstance(items, dict): + if 'brandingPolicyIds' in items: + items = items.get('brandingPolicyIds') + result = get_dict_result(items, 'name', name) + if result is None: + result = items + except Exception as e: + print("Error: ", e) + result = None + return result + + def get_object_by_id(self, id): + result = None + # NOTE: Does not have a get by id method or it is in another action + return result + + def exists(self): + prev_obj = None + id_exists = False + name_exists = False + o_id = self.new_object.get("id") + name = self.new_object.get("name") + if o_id: + prev_obj = self.get_object_by_name(o_id) + id_exists = prev_obj is not None and isinstance(prev_obj, dict) + if not id_exists and name: + prev_obj = self.get_object_by_name(name) + name_exists = prev_obj is not None and isinstance(prev_obj, dict) + if name_exists: + _id = prev_obj.get("id") + if id_exists and name_exists and o_id != _id: + raise InconsistentParameters( + "The 'id' and 'name' params don't refer to the same object") + if _id: + self.new_object.update(dict(id=_id)) + it_exists = prev_obj is not None and isinstance(prev_obj, dict) + return (it_exists, prev_obj) + + def requires_update(self, current_obj): + requested_obj = self.new_object + + obj_params = [ + ("brandingPolicyIds", "brandingPolicyIds"), + ("organizationId", "organizationId"), + ] + # Method 1. Params present in request (Ansible) obj are the same as the current (ISE) params + # If any does not have eq params, it requires update + return any(not meraki_compare_equality(current_obj.get(meraki_param), + requested_obj.get(ansible_param)) + for (meraki_param, ansible_param) in obj_params) + + def update(self): + id = self.new_object.get("id") + name = self.new_object.get("name") + result = None + result = self.meraki.exec_meraki( + family="organizations", + function="updateOrganizationBrandingPoliciesPriorities", + params=self.update_all_params(), + op_modifies=True, + ) + return result + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = False + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + meraki = MERAKI(self._task.args) + obj = OrganizationsBrandingPoliciesPriorities(self._task.args, meraki) + + state = self._task.args.get("state") + + response = None + if state == "present": + (obj_exists, prev_obj) = obj.exists() + if obj_exists: + if obj.requires_update(prev_obj): + response = obj.update() + meraki.object_updated() + else: + response = prev_obj + meraki.object_already_present() + else: + meraki.fail_json( + "Object does not exists, plugin only has update") + + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/organizations_branding_policies_priorities_info.py b/ansible_collections/cisco/meraki/plugins/action/organizations_branding_policies_priorities_info.py new file mode 100644 index 000000000..d4158d09e --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/organizations_branding_policies_priorities_info.py @@ -0,0 +1,90 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + organizationId=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_all(self, params): + new_object = {} + if params.get("organizationId") is not None: + new_object["organizationId"] = params.get( + "organizationId") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="organizations", + function='getOrganizationBrandingPoliciesPriorities', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/organizations_camera_custom_analytics_artifacts.py b/ansible_collections/cisco/meraki/plugins/action/organizations_camera_custom_analytics_artifacts.py new file mode 100644 index 000000000..248c509c1 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/organizations_camera_custom_analytics_artifacts.py @@ -0,0 +1,266 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or +# https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, + meraki_compare_equality, + get_dict_result, +) +from ansible_collections.cisco.meraki.plugins.plugin_utils.exceptions import ( + InconsistentParameters, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + state=dict(type="str", default="present", choices=["present", "absent"]), + name=dict(type="str"), + organizationId=dict(type="str"), + artifactId=dict(type="str"), +)) + +required_if = [ + ("state", "present", ["artifactId", "name", "organizationId"], True), + ("state", "absent", ["artifactId", "name", "organizationId"], True), +] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class OrganizationsCameraCustomAnalyticsArtifacts(object): + def __init__(self, params, meraki): + self.meraki = meraki + self.new_object = dict( + name=params.get("name"), + organization_id=params.get("organizationId"), + artifact_id=params.get("artifactId"), + ) + + def get_all_params(self, name=None, id=None): + new_object_params = {} + if self.new_object.get('organizationId') is not None or self.new_object.get('organization_id') is not None: + new_object_params['organizationId'] = self.new_object.get('organizationId') or \ + self.new_object.get('organization_id') + return new_object_params + + def get_params_by_id(self, name=None, id=None): + new_object_params = {} + if self.new_object.get('organizationId') is not None or self.new_object.get('organization_id') is not None: + new_object_params['organizationId'] = self.new_object.get('organizationId') or \ + self.new_object.get('organization_id') + if self.new_object.get('artifactId') is not None or self.new_object.get('artifact_id') is not None: + new_object_params['artifactId'] = self.new_object.get('artifactId') or \ + self.new_object.get('artifact_id') + return new_object_params + + def create_params(self): + new_object_params = {} + if self.new_object.get('name') is not None or self.new_object.get('name') is not None: + new_object_params['name'] = self.new_object.get('name') or \ + self.new_object.get('name') + if self.new_object.get('organizationId') is not None or self.new_object.get('organization_id') is not None: + new_object_params['organizationId'] = self.new_object.get('organizationId') or \ + self.new_object.get('organization_id') + return new_object_params + + def delete_by_id_params(self): + new_object_params = {} + if self.new_object.get('organizationId') is not None or self.new_object.get('organization_id') is not None: + new_object_params['organizationId'] = self.new_object.get('organizationId') or \ + self.new_object.get('organization_id') + if self.new_object.get('artifactId') is not None or self.new_object.get('artifact_id') is not None: + new_object_params['artifactId'] = self.new_object.get('artifactId') or \ + self.new_object.get('artifact_id') + return new_object_params + + def get_object_by_name(self, name): + result = None + # NOTE: Does not have a get by name method, using get all + try: + items = self.meraki.exec_meraki( + family="camera", + function="getOrganizationCameraCustomAnalyticsArtifacts", + params=self.get_all_params(name=name), + ) + if isinstance(items, dict): + if 'response' in items: + items = items.get('response') + result = get_dict_result(items, 'name', name) + if result is None: + result = items + except Exception as e: + print("Error: ", e) + result = None + return result + + def get_object_by_id(self, id): + result = None + try: + items = self.meraki.exec_meraki( + family="camera", + function="getOrganizationCameraCustomAnalyticsArtifact", + params=self.get_params_by_id() + ) + if isinstance(items, dict): + if 'response' in items: + items = items.get('response') + result = items + except Exception as e: + print("Error: ", e) + result = None + return result + + def exists(self): + prev_obj = None + id_exists = False + name_exists = False + o_id = self.new_object.get("id") + o_id = o_id or self.new_object.get( + "artifact_id") or self.new_object.get("artifactId") + name = self.new_object.get("name") + if o_id: + prev_obj = self.get_object_by_id(o_id) + id_exists = prev_obj is not None and isinstance(prev_obj, dict) + if not id_exists and name: + prev_obj = self.get_object_by_name(name) + name_exists = prev_obj is not None and isinstance(prev_obj, dict) + if name_exists: + _id = prev_obj.get("id") + _id = _id or prev_obj.get("artifactId") + if id_exists and name_exists and o_id != _id: + raise InconsistentParameters( + "The 'id' and 'name' params don't refer to the same object") + if _id: + self.new_object.update(dict(id=_id)) + self.new_object.update(dict(artifactId=_id)) + if _id: + prev_obj = self.get_object_by_id(_id) + it_exists = prev_obj is not None and isinstance(prev_obj, dict) + return (it_exists, prev_obj) + + def requires_update(self, current_obj): + requested_obj = self.new_object + + obj_params = [ + ("name", "name"), + ("organizationId", "organizationId"), + ("artifactId", "artifactId"), + ] + # Method 1. Params present in request (Ansible) obj are the same as the current (ISE) params + # If any does not have eq params, it requires update + return any(not meraki_compare_equality(current_obj.get(meraki_param), + requested_obj.get(ansible_param)) + for (meraki_param, ansible_param) in obj_params) + + def create(self): + result = self.meraki.exec_meraki( + family="camera", + function="createOrganizationCameraCustomAnalyticsArtifact", + params=self.create_params(), + op_modifies=True, + ) + return result + + def delete(self): + id = self.new_object.get("id") + id = id or self.new_object.get("artifactId") + name = self.new_object.get("name") + result = None + if not id: + prev_obj_name = self.get_object_by_name(name) + id_ = None + if prev_obj_name: + id_ = prev_obj_name.get("id") + id_ = id_ or prev_obj_name.get("artifactId") + if id_: + self.new_object.update(dict(artifactid=id_)) + result = self.meraki.exec_meraki( + family="camera", + function="deleteOrganizationCameraCustomAnalyticsArtifact", + params=self.delete_by_id_params(), + ) + return result + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = False + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + meraki = MERAKI(self._task.args) + obj = OrganizationsCameraCustomAnalyticsArtifacts(self._task.args, meraki) + + state = self._task.args.get("state") + + response = None + if state == "present": + (obj_exists, prev_obj) = obj.exists() + if obj_exists: + if obj.requires_update(prev_obj): + response = prev_obj + meraki.object_present_and_different() + else: + response = prev_obj + meraki.object_already_present() + else: + response = obj.create() + meraki.object_created() + elif state == "absent": + (obj_exists, prev_obj) = obj.exists() + if obj_exists: + response = obj.delete() + meraki.object_deleted() + else: + meraki.object_already_absent() + + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/organizations_camera_custom_analytics_artifacts_info.py b/ansible_collections/cisco/meraki/plugins/action/organizations_camera_custom_analytics_artifacts_info.py new file mode 100644 index 000000000..3e34df2ed --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/organizations_camera_custom_analytics_artifacts_info.py @@ -0,0 +1,112 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + organizationId=dict(type="str"), + artifactId=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_object(self, params): + new_object = {} + if params.get("organizationId") is not None: + new_object["organizationId"] = params.get( + "organizationId") + if params.get("artifactId") is not None: + new_object["artifactId"] = params.get( + "artifactId") + return new_object + + def get_all(self, params): + new_object = {} + if params.get("organizationId") is not None: + new_object["organizationId"] = params.get( + "organizationId") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + id = self._task.args.get("artifactId") + if id: + response = meraki.exec_meraki( + family="camera", + function='getOrganizationCameraCustomAnalyticsArtifact', + params=self.get_object(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result + if not id: + response = meraki.exec_meraki( + family="camera", + function='getOrganizationCameraCustomAnalyticsArtifacts', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/organizations_cellular_gateway_uplink_statuses_info.py b/ansible_collections/cisco/meraki/plugins/action/organizations_cellular_gateway_uplink_statuses_info.py new file mode 100644 index 000000000..d6a7db1cb --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/organizations_cellular_gateway_uplink_statuses_info.py @@ -0,0 +1,120 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + organizationId=dict(type="str"), + perPage=dict(type="int"), + total_pages=dict(type="int"), + direction=dict(type="str"), + startingAfter=dict(type="str"), + endingBefore=dict(type="str"), + networkIds=dict(type="list"), + serials=dict(type="list"), + iccids=dict(type="list"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_all(self, params): + new_object = {} + if params.get("organizationId") is not None: + new_object["organizationId"] = params.get( + "organizationId") + if params.get("perPage") is not None: + new_object["perPage"] = params.get( + "perPage") + new_object['total_pages'] = params.get( + "total_pages") or 1 + new_object['direction'] = params.get( + "direction") or "next" + if params.get("startingAfter") is not None: + new_object["startingAfter"] = params.get( + "startingAfter") + if params.get("endingBefore") is not None: + new_object["endingBefore"] = params.get( + "endingBefore") + if params.get("networkIds") is not None: + new_object["networkIds"] = params.get( + "networkIds") + if params.get("serials") is not None: + new_object["serials"] = params.get( + "serials") + if params.get("iccids") is not None: + new_object["iccids"] = params.get( + "iccids") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="cellular_gateway", + function='getOrganizationCellularGatewayUplinkStatuses', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/organizations_claim.py b/ansible_collections/cisco/meraki/plugins/action/organizations_claim.py new file mode 100644 index 000000000..5439a5af8 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/organizations_claim.py @@ -0,0 +1,93 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguements specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + orders=dict(type="list"), + serials=dict(type="list"), + licenses=dict(type="list"), + organizationId=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = False + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_object(self, params): + new_object = dict( + orders=params.get("orders"), + serials=params.get("serials"), + licenses=params.get("licenses"), + organizationId=params.get("organizationId"), + ) + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="organizations", + function='claimIntoOrganization', + op_modifies=True, + params=self.get_object(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/organizations_clients_bandwidth_usage_history_info.py b/ansible_collections/cisco/meraki/plugins/action/organizations_clients_bandwidth_usage_history_info.py new file mode 100644 index 000000000..bb7e8f6cd --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/organizations_clients_bandwidth_usage_history_info.py @@ -0,0 +1,102 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + organizationId=dict(type="str"), + t0=dict(type="str"), + t1=dict(type="str"), + timespan=dict(type="float"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_all(self, params): + new_object = {} + if params.get("organizationId") is not None: + new_object["organizationId"] = params.get( + "organizationId") + if params.get("t0") is not None: + new_object["t0"] = params.get( + "t0") + if params.get("t1") is not None: + new_object["t1"] = params.get( + "t1") + if params.get("timespan") is not None: + new_object["timespan"] = params.get( + "timespan") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="organizations", + function='getOrganizationClientsBandwidthUsageHistory', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/organizations_clients_overview_info.py b/ansible_collections/cisco/meraki/plugins/action/organizations_clients_overview_info.py new file mode 100644 index 000000000..de982ed4a --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/organizations_clients_overview_info.py @@ -0,0 +1,102 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + organizationId=dict(type="str"), + t0=dict(type="str"), + t1=dict(type="str"), + timespan=dict(type="float"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_all(self, params): + new_object = {} + if params.get("organizationId") is not None: + new_object["organizationId"] = params.get( + "organizationId") + if params.get("t0") is not None: + new_object["t0"] = params.get( + "t0") + if params.get("t1") is not None: + new_object["t1"] = params.get( + "t1") + if params.get("timespan") is not None: + new_object["timespan"] = params.get( + "timespan") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="organizations", + function='getOrganizationClientsOverview', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/organizations_clients_search_info.py b/ansible_collections/cisco/meraki/plugins/action/organizations_clients_search_info.py new file mode 100644 index 000000000..3319d1c68 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/organizations_clients_search_info.py @@ -0,0 +1,112 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + organizationId=dict(type="str"), + mac=dict(type="str"), + perPage=dict(type="int"), + total_pages=dict(type="int"), + direction=dict(type="str"), + startingAfter=dict(type="str"), + endingBefore=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_all(self, params): + new_object = {} + if params.get("organizationId") is not None: + new_object["organizationId"] = params.get( + "organizationId") + if params.get("mac") is not None: + new_object["mac"] = params.get( + "mac") + if params.get("perPage") is not None: + new_object["perPage"] = params.get( + "perPage") + new_object['total_pages'] = params.get( + "total_pages") or 1 + new_object['direction'] = params.get( + "direction") or "next" + if params.get("startingAfter") is not None: + new_object["startingAfter"] = params.get( + "startingAfter") + if params.get("endingBefore") is not None: + new_object["endingBefore"] = params.get( + "endingBefore") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="organizations", + function='getOrganizationClientsSearch', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/organizations_clone.py b/ansible_collections/cisco/meraki/plugins/action/organizations_clone.py new file mode 100644 index 000000000..97d65dfaf --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/organizations_clone.py @@ -0,0 +1,89 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguements specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + name=dict(type="str"), + organizationId=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = False + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_object(self, params): + new_object = dict( + name=params.get("name"), + organizationId=params.get("organizationId"), + ) + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="organizations", + function='cloneOrganization', + op_modifies=True, + params=self.get_object(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/organizations_config_templates.py b/ansible_collections/cisco/meraki/plugins/action/organizations_config_templates.py new file mode 100644 index 000000000..09dc845b0 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/organizations_config_templates.py @@ -0,0 +1,311 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or +# https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, + meraki_compare_equality2, + get_dict_result, +) +from ansible_collections.cisco.meraki.plugins.plugin_utils.exceptions import ( + InconsistentParameters, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + state=dict(type="str", default="present", choices=["present", "absent"]), + name=dict(type="str"), + timeZone=dict(type="str"), + organizationId=dict(type="str"), + configTemplateId=dict(type="str"), +)) + +required_if = [ + ("state", "present", ["configTemplateId", "name", "organizationId"], True), + ("state", "absent", ["configTemplateId", "name", "organizationId"], True), +] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class OrganizationsConfigTemplates(object): + def __init__(self, params, meraki): + self.meraki = meraki + self.new_object = dict( + name=params.get("name"), + timeZone=params.get("timeZone"), + organizationId=params.get("organizationId"), + configTemplateId=params.get("configTemplateId"), + ) + + def get_all_params(self, name=None, id=None): + new_object_params = {} + if self.new_object.get('organizationId') is not None or self.new_object.get('organization_id') is not None: + new_object_params['organizationId'] = self.new_object.get('organizationId') or \ + self.new_object.get('organization_id') + return new_object_params + + def get_params_by_id(self, name=None, id=None): + new_object_params = {} + if self.new_object.get('organizationId') is not None or self.new_object.get('organization_id') is not None: + new_object_params['organizationId'] = self.new_object.get('organizationId') or \ + self.new_object.get('organization_id') + if self.new_object.get('configTemplateId') is not None or self.new_object.get('config_template_id') is not None: + new_object_params['configTemplateId'] = self.new_object.get('configTemplateId') or \ + self.new_object.get('config_template_id') + return new_object_params + + def create_params(self): + new_object_params = {} + if self.new_object.get('name') is not None or self.new_object.get('name') is not None: + new_object_params['name'] = self.new_object.get('name') or \ + self.new_object.get('name') + if self.new_object.get('timeZone') is not None or self.new_object.get('time_zone') is not None: + new_object_params['timeZone'] = self.new_object.get('timeZone') or \ + self.new_object.get('time_zone') + if self.new_object.get('organizationId') is not None or self.new_object.get('organization_id') is not None: + new_object_params['organizationId'] = self.new_object.get('organizationId') or \ + self.new_object.get('organization_id') + return new_object_params + + def delete_by_id_params(self): + new_object_params = {} + if self.new_object.get('organizationId') is not None or self.new_object.get('organization_id') is not None: + new_object_params['organizationId'] = self.new_object.get('organizationId') or \ + self.new_object.get('organization_id') + if self.new_object.get('configTemplateId') is not None or self.new_object.get('config_template_id') is not None: + new_object_params['configTemplateId'] = self.new_object.get('configTemplateId') or \ + self.new_object.get('config_template_id') + return new_object_params + + def update_by_id_params(self): + new_object_params = {} + if self.new_object.get('name') is not None or self.new_object.get('name') is not None: + new_object_params['name'] = self.new_object.get('name') or \ + self.new_object.get('name') + if self.new_object.get('timeZone') is not None or self.new_object.get('time_zone') is not None: + new_object_params['timeZone'] = self.new_object.get('timeZone') or \ + self.new_object.get('time_zone') + if self.new_object.get('organizationId') is not None or self.new_object.get('organization_id') is not None: + new_object_params['organizationId'] = self.new_object.get('organizationId') or \ + self.new_object.get('organization_id') + if self.new_object.get('configTemplateId') is not None or self.new_object.get('config_template_id') is not None: + new_object_params['configTemplateId'] = self.new_object.get('configTemplateId') or \ + self.new_object.get('config_template_id') + return new_object_params + + def get_object_by_name(self, name): + result = None + # NOTE: Does not have a get by name method or it is in another action + try: + items = self.meraki.exec_meraki( + family="organizations", + function="getOrganizationConfigTemplates", + params=self.get_all_params(name=name), + ) + if isinstance(items, dict): + if 'response' in items: + items = items.get('response') + result = get_dict_result(items, 'name', name) + if result is None: + result = items + except Exception as e: + print("Error: ", e) + result = None + return result + + def get_object_by_id(self, id): + result = None + try: + items = self.meraki.exec_meraki( + family="organizations", + function="getOrganizationConfigTemplate", + params=self.get_params_by_id() + ) + if isinstance(items, dict): + if 'response' in items: + items = items.get('response') + result = get_dict_result(items, 'configTemplateId', id) + except Exception as e: + print("Error: ", e) + result = None + return result + + def exists(self): + id_exists = False + name_exists = False + prev_obj = None + o_id = self.new_object.get("id") + o_id = o_id or self.new_object.get( + "config_template_id") or self.new_object.get("configTemplateId") + name = self.new_object.get("name") + if o_id: + prev_obj = self.get_object_by_id(o_id) + id_exists = prev_obj is not None and isinstance(prev_obj, dict) + if not id_exists and name: + prev_obj = self.get_object_by_name(name) + name_exists = prev_obj is not None and isinstance(prev_obj, dict) + if name_exists: + _id = prev_obj.get("id") + _id = _id or prev_obj.get("configTemplateId") + if id_exists and name_exists and o_id != _id: + raise InconsistentParameters( + "The 'id' and 'name' params don't refer to the same object") + if _id: + self.new_object.update(dict(id=_id)) + self.new_object.update(dict(configTemplateId=_id)) + if _id: + prev_obj = self.get_object_by_id(_id) + it_exists = prev_obj is not None and isinstance(prev_obj, dict) + return (it_exists, prev_obj) + + def requires_update(self, current_obj): + requested_obj = self.new_object + + obj_params = [ + ("name", "name"), + ("timeZone", "timeZone"), + ("organizationId", "organizationId"), + ("configTemplateId", "configTemplateId"), + ] + # Method 1. Params present in request (Ansible) obj are the same as the current (DNAC) params + # If any does not have eq params, it requires update + return any(not meraki_compare_equality2(current_obj.get(meraki_param), + requested_obj.get(ansible_param)) + for (meraki_param, ansible_param) in obj_params) + + def create(self): + result = self.meraki.exec_meraki( + family="organizations", + function="createOrganizationConfigTemplate", + params=self.create_params(), + op_modifies=True, + ) + return result + + def update(self): + id = self.new_object.get("id") + id = id or self.new_object.get("configTemplateId") + name = self.new_object.get("name") + result = None + if not id: + prev_obj_name = self.get_object_by_name(name) + id_ = None + if prev_obj_name: + id_ = prev_obj_name.get("id") + id_ = id_ or prev_obj_name.get("configTemplateId") + if id_: + self.new_object.update(dict(configTemplateId=id_)) + result = self.meraki.exec_meraki( + family="organizations", + function="updateOrganizationConfigTemplate", + params=self.update_by_id_params(), + op_modifies=True, + ) + return result + + def delete(self): + id = self.new_object.get("id") + id = id or self.new_object.get("configTemplateId") + name = self.new_object.get("name") + result = None + if not id: + prev_obj_name = self.get_object_by_name(name) + id_ = None + if prev_obj_name: + id_ = prev_obj_name.get("id") + id_ = id_ or prev_obj_name.get("configTemplateId") + if id_: + self.new_object.update(dict(configTemplateId=id_)) + result = self.meraki.exec_meraki( + family="organizations", + function="deleteOrganizationConfigTemplate", + params=self.delete_by_id_params(), + ) + return result + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = False + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + meraki = MERAKI(self._task.args) + obj = OrganizationsConfigTemplates(self._task.args, meraki) + + state = self._task.args.get("state") + + response = None + + if state == "present": + (obj_exists, prev_obj) = obj.exists() + if obj_exists: + if obj.requires_update(prev_obj): + response = obj.update() + meraki.object_updated() + else: + response = prev_obj + meraki.object_already_present() + else: + response = obj.create() + meraki.object_created() + + elif state == "absent": + (obj_exists, prev_obj) = obj.exists() + if obj_exists: + response = obj.delete() + meraki.object_deleted() + else: + meraki.object_already_absent() + + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/organizations_config_templates_info.py b/ansible_collections/cisco/meraki/plugins/action/organizations_config_templates_info.py new file mode 100644 index 000000000..5fc68648e --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/organizations_config_templates_info.py @@ -0,0 +1,112 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + organizationId=dict(type="str"), + configTemplateId=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_object(self, params): + new_object = {} + if params.get("organizationId") is not None: + new_object["organizationId"] = params.get( + "organizationId") + if params.get("configTemplateId") is not None: + new_object["configTemplateId"] = params.get( + "configTemplateId") + return new_object + + def get_all(self, params): + new_object = {} + if params.get("organizationId") is not None: + new_object["organizationId"] = params.get( + "organizationId") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + id = self._task.args.get("configTemplateId") + if id: + response = meraki.exec_meraki( + family="organizations", + function='getOrganizationConfigTemplate', + params=self.get_object(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result + if not id: + response = meraki.exec_meraki( + family="organizations", + function='getOrganizationConfigTemplates', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/organizations_config_templates_switch_profiles_info.py b/ansible_collections/cisco/meraki/plugins/action/organizations_config_templates_switch_profiles_info.py new file mode 100644 index 000000000..888d7c366 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/organizations_config_templates_switch_profiles_info.py @@ -0,0 +1,94 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + organizationId=dict(type="str"), + configTemplateId=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_all(self, params): + new_object = {} + if params.get("organizationId") is not None: + new_object["organizationId"] = params.get( + "organizationId") + if params.get("configTemplateId") is not None: + new_object["configTemplateId"] = params.get( + "configTemplateId") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="switch", + function='getOrganizationConfigTemplateSwitchProfiles', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/organizations_config_templates_switch_profiles_ports.py b/ansible_collections/cisco/meraki/plugins/action/organizations_config_templates_switch_profiles_ports.py new file mode 100644 index 000000000..38cd937fc --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/organizations_config_templates_switch_profiles_ports.py @@ -0,0 +1,392 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or +# https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, + meraki_compare_equality, + get_dict_result, +) +from ansible_collections.cisco.meraki.plugins.plugin_utils.exceptions import ( + InconsistentParameters, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + state=dict(type="str", default="present", choices=["present"]), + name=dict(type="str"), + tags=dict(type="list"), + enabled=dict(type="bool"), + poeEnabled=dict(type="bool"), + type=dict(type="str"), + vlan=dict(type="int"), + voiceVlan=dict(type="int"), + allowedVlans=dict(type="str"), + isolationEnabled=dict(type="bool"), + rstpEnabled=dict(type="bool"), + stpGuard=dict(type="str"), + linkNegotiation=dict(type="str"), + portScheduleId=dict(type="str"), + udld=dict(type="str"), + accessPolicyType=dict(type="str"), + accessPolicyNumber=dict(type="int"), + macAllowList=dict(type="list"), + stickyMacAllowList=dict(type="list"), + stickyMacAllowListLimit=dict(type="int"), + stormControlEnabled=dict(type="bool"), + flexibleStackingEnabled=dict(type="bool"), + daiTrusted=dict(type="bool"), + profile=dict(type="dict"), + organizationId=dict(type="str"), + configTemplateId=dict(type="str"), + profileId=dict(type="str"), + portId=dict(type="str"), +)) + +required_if = [ + ("state", "present", ["configTemplateId", "name", "organizationId", "portId", "profileId"], True), +] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class OrganizationsConfigTemplatesSwitchProfilesPorts(object): + def __init__(self, params, meraki): + self.meraki = meraki + self.new_object = dict( + name=params.get("name"), + tags=params.get("tags"), + enabled=params.get("enabled"), + poeEnabled=params.get("poeEnabled"), + type=params.get("type"), + vlan=params.get("vlan"), + voiceVlan=params.get("voiceVlan"), + allowedVlans=params.get("allowedVlans"), + isolationEnabled=params.get("isolationEnabled"), + rstpEnabled=params.get("rstpEnabled"), + stpGuard=params.get("stpGuard"), + linkNegotiation=params.get("linkNegotiation"), + portScheduleId=params.get("portScheduleId"), + udld=params.get("udld"), + accessPolicyType=params.get("accessPolicyType"), + accessPolicyNumber=params.get("accessPolicyNumber"), + macAllowList=params.get("macAllowList"), + stickyMacAllowList=params.get("stickyMacAllowList"), + stickyMacAllowListLimit=params.get("stickyMacAllowListLimit"), + stormControlEnabled=params.get("stormControlEnabled"), + flexibleStackingEnabled=params.get("flexibleStackingEnabled"), + daiTrusted=params.get("daiTrusted"), + profile=params.get("profile"), + organization_id=params.get("organizationId"), + config_template_id=params.get("configTemplateId"), + profile_id=params.get("profileId"), + port_id=params.get("portId"), + ) + + def get_all_params(self, name=None, id=None): + new_object_params = {} + if self.new_object.get('organizationId') is not None or self.new_object.get('organization_id') is not None: + new_object_params['organizationId'] = self.new_object.get('organizationId') or \ + self.new_object.get('organization_id') + if self.new_object.get('configTemplateId') is not None or self.new_object.get('config_template_id') is not None: + new_object_params['configTemplateId'] = self.new_object.get('configTemplateId') or \ + self.new_object.get('config_template_id') + if self.new_object.get('profileId') is not None or self.new_object.get('profile_id') is not None: + new_object_params['profileId'] = self.new_object.get('profileId') or \ + self.new_object.get('profile_id') + return new_object_params + + def get_params_by_id(self, name=None, id=None): + new_object_params = {} + if self.new_object.get('organizationId') is not None or self.new_object.get('organization_id') is not None: + new_object_params['organizationId'] = self.new_object.get('organizationId') or \ + self.new_object.get('organization_id') + if self.new_object.get('configTemplateId') is not None or self.new_object.get('config_template_id') is not None: + new_object_params['configTemplateId'] = self.new_object.get('configTemplateId') or \ + self.new_object.get('config_template_id') + if self.new_object.get('profileId') is not None or self.new_object.get('profile_id') is not None: + new_object_params['profileId'] = self.new_object.get('profileId') or \ + self.new_object.get('profile_id') + if self.new_object.get('portId') is not None or self.new_object.get('port_id') is not None: + new_object_params['portId'] = self.new_object.get('portId') or \ + self.new_object.get('port_id') + return new_object_params + + def update_by_id_params(self): + new_object_params = {} + if self.new_object.get('name') is not None or self.new_object.get('name') is not None: + new_object_params['name'] = self.new_object.get('name') or \ + self.new_object.get('name') + if self.new_object.get('tags') is not None or self.new_object.get('tags') is not None: + new_object_params['tags'] = self.new_object.get('tags') or \ + self.new_object.get('tags') + if self.new_object.get('enabled') is not None or self.new_object.get('enabled') is not None: + new_object_params['enabled'] = self.new_object.get('enabled') + if self.new_object.get('poeEnabled') is not None or self.new_object.get('poe_enabled') is not None: + new_object_params['poeEnabled'] = self.new_object.get('poeEnabled') + if self.new_object.get('type') is not None or self.new_object.get('type') is not None: + new_object_params['type'] = self.new_object.get('type') or \ + self.new_object.get('type') + if self.new_object.get('vlan') is not None or self.new_object.get('vlan') is not None: + new_object_params['vlan'] = self.new_object.get('vlan') or \ + self.new_object.get('vlan') + if self.new_object.get('voiceVlan') is not None or self.new_object.get('voice_vlan') is not None: + new_object_params['voiceVlan'] = self.new_object.get('voiceVlan') or \ + self.new_object.get('voice_vlan') + if self.new_object.get('allowedVlans') is not None or self.new_object.get('allowed_vlans') is not None: + new_object_params['allowedVlans'] = self.new_object.get('allowedVlans') or \ + self.new_object.get('allowed_vlans') + if self.new_object.get('isolationEnabled') is not None or self.new_object.get('isolation_enabled') is not None: + new_object_params['isolationEnabled'] = self.new_object.get('isolationEnabled') + if self.new_object.get('rstpEnabled') is not None or self.new_object.get('rstp_enabled') is not None: + new_object_params['rstpEnabled'] = self.new_object.get('rstpEnabled') + if self.new_object.get('stpGuard') is not None or self.new_object.get('stp_guard') is not None: + new_object_params['stpGuard'] = self.new_object.get('stpGuard') or \ + self.new_object.get('stp_guard') + if self.new_object.get('linkNegotiation') is not None or self.new_object.get('link_negotiation') is not None: + new_object_params['linkNegotiation'] = self.new_object.get('linkNegotiation') or \ + self.new_object.get('link_negotiation') + if self.new_object.get('portScheduleId') is not None or self.new_object.get('port_schedule_id') is not None: + new_object_params['portScheduleId'] = self.new_object.get('portScheduleId') or \ + self.new_object.get('port_schedule_id') + if self.new_object.get('udld') is not None or self.new_object.get('udld') is not None: + new_object_params['udld'] = self.new_object.get('udld') or \ + self.new_object.get('udld') + if self.new_object.get('accessPolicyType') is not None or self.new_object.get('access_policy_type') is not None: + new_object_params['accessPolicyType'] = self.new_object.get('accessPolicyType') or \ + self.new_object.get('access_policy_type') + if self.new_object.get('accessPolicyNumber') is not None or self.new_object.get('access_policy_number') is not None: + new_object_params['accessPolicyNumber'] = self.new_object.get('accessPolicyNumber') or \ + self.new_object.get('access_policy_number') + if self.new_object.get('macAllowList') is not None or self.new_object.get('mac_allow_list') is not None: + new_object_params['macAllowList'] = self.new_object.get('macAllowList') or \ + self.new_object.get('mac_allow_list') + if self.new_object.get('stickyMacAllowList') is not None or self.new_object.get('sticky_mac_allow_list') is not None: + new_object_params['stickyMacAllowList'] = self.new_object.get('stickyMacAllowList') or \ + self.new_object.get('sticky_mac_allow_list') + if self.new_object.get('stickyMacAllowListLimit') is not None or self.new_object.get('sticky_mac_allow_list_limit') is not None: + new_object_params['stickyMacAllowListLimit'] = self.new_object.get('stickyMacAllowListLimit') or \ + self.new_object.get('sticky_mac_allow_list_limit') + if self.new_object.get('stormControlEnabled') is not None or self.new_object.get('storm_control_enabled') is not None: + new_object_params['stormControlEnabled'] = self.new_object.get('stormControlEnabled') + if self.new_object.get('flexibleStackingEnabled') is not None or self.new_object.get('flexible_stacking_enabled') is not None: + new_object_params['flexibleStackingEnabled'] = self.new_object.get('flexibleStackingEnabled') + if self.new_object.get('daiTrusted') is not None or self.new_object.get('dai_trusted') is not None: + new_object_params['daiTrusted'] = self.new_object.get('daiTrusted') + if self.new_object.get('profile') is not None or self.new_object.get('profile') is not None: + new_object_params['profile'] = self.new_object.get('profile') or \ + self.new_object.get('profile') + if self.new_object.get('organizationId') is not None or self.new_object.get('organization_id') is not None: + new_object_params['organizationId'] = self.new_object.get('organizationId') or \ + self.new_object.get('organization_id') + if self.new_object.get('configTemplateId') is not None or self.new_object.get('config_template_id') is not None: + new_object_params['configTemplateId'] = self.new_object.get('configTemplateId') or \ + self.new_object.get('config_template_id') + if self.new_object.get('profileId') is not None or self.new_object.get('profile_id') is not None: + new_object_params['profileId'] = self.new_object.get('profileId') or \ + self.new_object.get('profile_id') + if self.new_object.get('portId') is not None or self.new_object.get('port_id') is not None: + new_object_params['portId'] = self.new_object.get('portId') or \ + self.new_object.get('port_id') + return new_object_params + + def get_object_by_name(self, name): + result = None + # NOTE: Does not have a get by name method, using get all + try: + items = self.meraki.exec_meraki( + family="switch", + function="getOrganizationConfigTemplateSwitchProfilePorts", + params=self.get_all_params(name=name), + ) + if isinstance(items, dict): + if 'response' in items: + items = items.get('response') + result = get_dict_result(items, 'name', name) + if result is None: + result = items + except Exception as e: + print("Error: ", e) + result = None + return result + + def get_object_by_id(self, id): + result = None + try: + items = self.meraki.exec_meraki( + family="switch", + function="getOrganizationConfigTemplateSwitchProfilePort", + params=self.get_params_by_id() + ) + if isinstance(items, dict): + if 'response' in items: + items = items.get('response') + result = items + except Exception as e: + print("Error: ", e) + result = None + return result + + def exists(self): + prev_obj = None + id_exists = False + name_exists = False + o_id = self.new_object.get("id") + o_id = o_id or self.new_object.get( + "port_id") or self.new_object.get("portId") + name = self.new_object.get("name") + if o_id: + prev_obj = self.get_object_by_id(o_id) + id_exists = prev_obj is not None and isinstance(prev_obj, dict) + if not id_exists and name: + prev_obj = self.get_object_by_name(name) + name_exists = prev_obj is not None and isinstance(prev_obj, dict) + if name_exists: + _id = prev_obj.get("id") + _id = _id or prev_obj.get("portId") + if id_exists and name_exists and o_id != _id: + raise InconsistentParameters( + "The 'id' and 'name' params don't refer to the same object") + if _id: + self.new_object.update(dict(id=_id)) + self.new_object.update(dict(portId=_id)) + if _id: + prev_obj = self.get_object_by_id(_id) + it_exists = prev_obj is not None and isinstance(prev_obj, dict) + return (it_exists, prev_obj) + + def requires_update(self, current_obj): + requested_obj = self.new_object + + obj_params = [ + ("name", "name"), + ("tags", "tags"), + ("enabled", "enabled"), + ("poeEnabled", "poeEnabled"), + ("type", "type"), + ("vlan", "vlan"), + ("voiceVlan", "voiceVlan"), + ("allowedVlans", "allowedVlans"), + ("isolationEnabled", "isolationEnabled"), + ("rstpEnabled", "rstpEnabled"), + ("stpGuard", "stpGuard"), + ("linkNegotiation", "linkNegotiation"), + ("portScheduleId", "portScheduleId"), + ("udld", "udld"), + ("accessPolicyType", "accessPolicyType"), + ("accessPolicyNumber", "accessPolicyNumber"), + ("macAllowList", "macAllowList"), + ("stickyMacAllowList", "stickyMacAllowList"), + ("stickyMacAllowListLimit", "stickyMacAllowListLimit"), + ("stormControlEnabled", "stormControlEnabled"), + ("flexibleStackingEnabled", "flexibleStackingEnabled"), + ("daiTrusted", "daiTrusted"), + ("profile", "profile"), + ("organizationId", "organizationId"), + ("configTemplateId", "configTemplateId"), + ("profileId", "profileId"), + ("portId", "portId"), + ] + # Method 1. Params present in request (Ansible) obj are the same as the current (ISE) params + # If any does not have eq params, it requires update + return any(not meraki_compare_equality(current_obj.get(meraki_param), + requested_obj.get(ansible_param)) + for (meraki_param, ansible_param) in obj_params) + + def update(self): + id = self.new_object.get("id") + id = id or self.new_object.get("portId") + name = self.new_object.get("name") + result = None + if not id: + prev_obj_name = self.get_object_by_name(name) + id_ = None + if prev_obj_name: + id_ = prev_obj_name.get("id") + id_ = id_ or prev_obj_name.get("portId") + if id_: + self.new_object.update(dict(portid=id_)) + result = self.meraki.exec_meraki( + family="switch", + function="updateOrganizationConfigTemplateSwitchProfilePort", + params=self.update_by_id_params(), + op_modifies=True, + ) + return result + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = False + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + meraki = MERAKI(self._task.args) + obj = OrganizationsConfigTemplatesSwitchProfilesPorts(self._task.args, meraki) + + state = self._task.args.get("state") + + response = None + if state == "present": + (obj_exists, prev_obj) = obj.exists() + if obj_exists: + if obj.requires_update(prev_obj): + response = obj.update() + meraki.object_updated() + else: + response = prev_obj + meraki.object_already_present() + else: + meraki.fail_json( + "Object does not exists, plugin only has update") + + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/organizations_config_templates_switch_profiles_ports_info.py b/ansible_collections/cisco/meraki/plugins/action/organizations_config_templates_switch_profiles_ports_info.py new file mode 100644 index 000000000..d7dfea062 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/organizations_config_templates_switch_profiles_ports_info.py @@ -0,0 +1,126 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + organizationId=dict(type="str"), + configTemplateId=dict(type="str"), + profileId=dict(type="str"), + portId=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_object(self, params): + new_object = {} + if params.get("organizationId") is not None: + new_object["organizationId"] = params.get( + "organizationId") + if params.get("configTemplateId") is not None: + new_object["configTemplateId"] = params.get( + "configTemplateId") + if params.get("profileId") is not None: + new_object["profileId"] = params.get( + "profileId") + if params.get("portId") is not None: + new_object["portId"] = params.get( + "portId") + return new_object + + def get_all(self, params): + new_object = {} + if params.get("organizationId") is not None: + new_object["organizationId"] = params.get( + "organizationId") + if params.get("configTemplateId") is not None: + new_object["configTemplateId"] = params.get( + "configTemplateId") + if params.get("profileId") is not None: + new_object["profileId"] = params.get( + "profileId") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + id = self._task.args.get("portId") + if id: + response = meraki.exec_meraki( + family="switch", + function='getOrganizationConfigTemplateSwitchProfilePort', + params=self.get_object(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result + if not id: + response = meraki.exec_meraki( + family="switch", + function='getOrganizationConfigTemplateSwitchProfilePorts', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/organizations_devices_availabilities_info.py b/ansible_collections/cisco/meraki/plugins/action/organizations_devices_availabilities_info.py new file mode 100644 index 000000000..20c320785 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/organizations_devices_availabilities_info.py @@ -0,0 +1,128 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + organizationId=dict(type="str"), + perPage=dict(type="int"), + total_pages=dict(type="int"), + direction=dict(type="str"), + startingAfter=dict(type="str"), + endingBefore=dict(type="str"), + networkIds=dict(type="list"), + productTypes=dict(type="list"), + serials=dict(type="list"), + tags=dict(type="list"), + tagsFilterType=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_all(self, params): + new_object = {} + if params.get("organizationId") is not None: + new_object["organizationId"] = params.get( + "organizationId") + if params.get("perPage") is not None: + new_object["perPage"] = params.get( + "perPage") + new_object['total_pages'] = params.get( + "total_pages") or 1 + new_object['direction'] = params.get( + "direction") or "next" + if params.get("startingAfter") is not None: + new_object["startingAfter"] = params.get( + "startingAfter") + if params.get("endingBefore") is not None: + new_object["endingBefore"] = params.get( + "endingBefore") + if params.get("networkIds") is not None: + new_object["networkIds"] = params.get( + "networkIds") + if params.get("productTypes") is not None: + new_object["productTypes"] = params.get( + "productTypes") + if params.get("serials") is not None: + new_object["serials"] = params.get( + "serials") + if params.get("tags") is not None: + new_object["tags"] = params.get( + "tags") + if params.get("tagsFilterType") is not None: + new_object["tagsFilterType"] = params.get( + "tagsFilterType") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="organizations", + function='getOrganizationDevicesAvailabilities', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/organizations_devices_info.py b/ansible_collections/cisco/meraki/plugins/action/organizations_devices_info.py new file mode 100644 index 000000000..1d5df40fe --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/organizations_devices_info.py @@ -0,0 +1,164 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + organizationId=dict(type="str"), + perPage=dict(type="int"), + total_pages=dict(type="int"), + direction=dict(type="str"), + startingAfter=dict(type="str"), + endingBefore=dict(type="str"), + configurationUpdatedAfter=dict(type="str"), + networkIds=dict(type="list"), + productTypes=dict(type="list"), + tags=dict(type="list"), + tagsFilterType=dict(type="str"), + name=dict(type="str"), + mac=dict(type="str"), + serial=dict(type="str"), + model=dict(type="str"), + macs=dict(type="list"), + serials=dict(type="list"), + sensorMetrics=dict(type="list"), + sensorAlertProfileIds=dict(type="list"), + models=dict(type="list"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_all(self, params): + new_object = {} + if params.get("organizationId") is not None: + new_object["organizationId"] = params.get( + "organizationId") + if params.get("perPage") is not None: + new_object["perPage"] = params.get( + "perPage") + new_object['total_pages'] = params.get( + "total_pages") or 1 + new_object['direction'] = params.get( + "direction") or "next" + if params.get("startingAfter") is not None: + new_object["startingAfter"] = params.get( + "startingAfter") + if params.get("endingBefore") is not None: + new_object["endingBefore"] = params.get( + "endingBefore") + if params.get("configurationUpdatedAfter") is not None: + new_object["configurationUpdatedAfter"] = params.get( + "configurationUpdatedAfter") + if params.get("networkIds") is not None: + new_object["networkIds"] = params.get( + "networkIds") + if params.get("productTypes") is not None: + new_object["productTypes"] = params.get( + "productTypes") + if params.get("tags") is not None: + new_object["tags"] = params.get( + "tags") + if params.get("tagsFilterType") is not None: + new_object["tagsFilterType"] = params.get( + "tagsFilterType") + if params.get("name") is not None: + new_object["name"] = params.get( + "name") + if params.get("mac") is not None: + new_object["mac"] = params.get( + "mac") + if params.get("serial") is not None: + new_object["serial"] = params.get( + "serial") + if params.get("model") is not None: + new_object["model"] = params.get( + "model") + if params.get("macs") is not None: + new_object["macs"] = params.get( + "macs") + if params.get("serials") is not None: + new_object["serials"] = params.get( + "serials") + if params.get("sensorMetrics") is not None: + new_object["sensorMetrics"] = params.get( + "sensorMetrics") + if params.get("sensorAlertProfileIds") is not None: + new_object["sensorAlertProfileIds"] = params.get( + "sensorAlertProfileIds") + if params.get("models") is not None: + new_object["models"] = params.get( + "models") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="organizations", + function='getOrganizationDevices', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/organizations_devices_power_modules_statuses_by_device_info.py b/ansible_collections/cisco/meraki/plugins/action/organizations_devices_power_modules_statuses_by_device_info.py new file mode 100644 index 000000000..233655ac9 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/organizations_devices_power_modules_statuses_by_device_info.py @@ -0,0 +1,128 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + organizationId=dict(type="str"), + perPage=dict(type="int"), + total_pages=dict(type="int"), + direction=dict(type="str"), + startingAfter=dict(type="str"), + endingBefore=dict(type="str"), + networkIds=dict(type="list"), + productTypes=dict(type="list"), + serials=dict(type="list"), + tags=dict(type="list"), + tagsFilterType=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_all(self, params): + new_object = {} + if params.get("organizationId") is not None: + new_object["organizationId"] = params.get( + "organizationId") + if params.get("perPage") is not None: + new_object["perPage"] = params.get( + "perPage") + new_object['total_pages'] = params.get( + "total_pages") or 1 + new_object['direction'] = params.get( + "direction") or "next" + if params.get("startingAfter") is not None: + new_object["startingAfter"] = params.get( + "startingAfter") + if params.get("endingBefore") is not None: + new_object["endingBefore"] = params.get( + "endingBefore") + if params.get("networkIds") is not None: + new_object["networkIds"] = params.get( + "networkIds") + if params.get("productTypes") is not None: + new_object["productTypes"] = params.get( + "productTypes") + if params.get("serials") is not None: + new_object["serials"] = params.get( + "serials") + if params.get("tags") is not None: + new_object["tags"] = params.get( + "tags") + if params.get("tagsFilterType") is not None: + new_object["tagsFilterType"] = params.get( + "tagsFilterType") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="organizations", + function='getOrganizationDevicesPowerModulesStatusesByDevice', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/organizations_devices_provisioning_statuses_info.py b/ansible_collections/cisco/meraki/plugins/action/organizations_devices_provisioning_statuses_info.py new file mode 100644 index 000000000..78a9b4b10 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/organizations_devices_provisioning_statuses_info.py @@ -0,0 +1,132 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + organizationId=dict(type="str"), + perPage=dict(type="int"), + total_pages=dict(type="int"), + direction=dict(type="str"), + startingAfter=dict(type="str"), + endingBefore=dict(type="str"), + networkIds=dict(type="list"), + productTypes=dict(type="list"), + serials=dict(type="list"), + status=dict(type="str"), + tags=dict(type="list"), + tagsFilterType=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_all(self, params): + new_object = {} + if params.get("organizationId") is not None: + new_object["organizationId"] = params.get( + "organizationId") + if params.get("perPage") is not None: + new_object["perPage"] = params.get( + "perPage") + new_object['total_pages'] = params.get( + "total_pages") or 1 + new_object['direction'] = params.get( + "direction") or "next" + if params.get("startingAfter") is not None: + new_object["startingAfter"] = params.get( + "startingAfter") + if params.get("endingBefore") is not None: + new_object["endingBefore"] = params.get( + "endingBefore") + if params.get("networkIds") is not None: + new_object["networkIds"] = params.get( + "networkIds") + if params.get("productTypes") is not None: + new_object["productTypes"] = params.get( + "productTypes") + if params.get("serials") is not None: + new_object["serials"] = params.get( + "serials") + if params.get("status") is not None: + new_object["status"] = params.get( + "status") + if params.get("tags") is not None: + new_object["tags"] = params.get( + "tags") + if params.get("tagsFilterType") is not None: + new_object["tagsFilterType"] = params.get( + "tagsFilterType") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="organizations", + function='getOrganizationDevicesProvisioningStatuses', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/organizations_devices_statuses_info.py b/ansible_collections/cisco/meraki/plugins/action/organizations_devices_statuses_info.py new file mode 100644 index 000000000..2d01b8db8 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/organizations_devices_statuses_info.py @@ -0,0 +1,136 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + organizationId=dict(type="str"), + perPage=dict(type="int"), + total_pages=dict(type="int"), + direction=dict(type="str"), + startingAfter=dict(type="str"), + endingBefore=dict(type="str"), + networkIds=dict(type="list"), + serials=dict(type="list"), + statuses=dict(type="list"), + productTypes=dict(type="list"), + models=dict(type="list"), + tags=dict(type="list"), + tagsFilterType=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_all(self, params): + new_object = {} + if params.get("organizationId") is not None: + new_object["organizationId"] = params.get( + "organizationId") + if params.get("perPage") is not None: + new_object["perPage"] = params.get( + "perPage") + new_object['total_pages'] = params.get( + "total_pages") or 1 + new_object['direction'] = params.get( + "direction") or "next" + if params.get("startingAfter") is not None: + new_object["startingAfter"] = params.get( + "startingAfter") + if params.get("endingBefore") is not None: + new_object["endingBefore"] = params.get( + "endingBefore") + if params.get("networkIds") is not None: + new_object["networkIds"] = params.get( + "networkIds") + if params.get("serials") is not None: + new_object["serials"] = params.get( + "serials") + if params.get("statuses") is not None: + new_object["statuses"] = params.get( + "statuses") + if params.get("productTypes") is not None: + new_object["productTypes"] = params.get( + "productTypes") + if params.get("models") is not None: + new_object["models"] = params.get( + "models") + if params.get("tags") is not None: + new_object["tags"] = params.get( + "tags") + if params.get("tagsFilterType") is not None: + new_object["tagsFilterType"] = params.get( + "tagsFilterType") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="organizations", + function='getOrganizationDevicesStatuses', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/organizations_devices_statuses_overview_info.py b/ansible_collections/cisco/meraki/plugins/action/organizations_devices_statuses_overview_info.py new file mode 100644 index 000000000..bd64cabfa --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/organizations_devices_statuses_overview_info.py @@ -0,0 +1,98 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + organizationId=dict(type="str"), + productTypes=dict(type="list"), + networkIds=dict(type="list"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_all(self, params): + new_object = {} + if params.get("organizationId") is not None: + new_object["organizationId"] = params.get( + "organizationId") + if params.get("productTypes") is not None: + new_object["productTypes"] = params.get( + "productTypes") + if params.get("networkIds") is not None: + new_object["networkIds"] = params.get( + "networkIds") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="organizations", + function='getOrganizationDevicesStatusesOverview', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/organizations_devices_uplinks_addresses_by_device_info.py b/ansible_collections/cisco/meraki/plugins/action/organizations_devices_uplinks_addresses_by_device_info.py new file mode 100644 index 000000000..dd2988d77 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/organizations_devices_uplinks_addresses_by_device_info.py @@ -0,0 +1,128 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + organizationId=dict(type="str"), + perPage=dict(type="int"), + total_pages=dict(type="int"), + direction=dict(type="str"), + startingAfter=dict(type="str"), + endingBefore=dict(type="str"), + networkIds=dict(type="list"), + productTypes=dict(type="list"), + serials=dict(type="list"), + tags=dict(type="list"), + tagsFilterType=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_all(self, params): + new_object = {} + if params.get("organizationId") is not None: + new_object["organizationId"] = params.get( + "organizationId") + if params.get("perPage") is not None: + new_object["perPage"] = params.get( + "perPage") + new_object['total_pages'] = params.get( + "total_pages") or 1 + new_object['direction'] = params.get( + "direction") or "next" + if params.get("startingAfter") is not None: + new_object["startingAfter"] = params.get( + "startingAfter") + if params.get("endingBefore") is not None: + new_object["endingBefore"] = params.get( + "endingBefore") + if params.get("networkIds") is not None: + new_object["networkIds"] = params.get( + "networkIds") + if params.get("productTypes") is not None: + new_object["productTypes"] = params.get( + "productTypes") + if params.get("serials") is not None: + new_object["serials"] = params.get( + "serials") + if params.get("tags") is not None: + new_object["tags"] = params.get( + "tags") + if params.get("tagsFilterType") is not None: + new_object["tagsFilterType"] = params.get( + "tagsFilterType") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="organizations", + function='getOrganizationDevicesUplinksAddressesByDevice', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/organizations_devices_uplinks_loss_and_latency_info.py b/ansible_collections/cisco/meraki/plugins/action/organizations_devices_uplinks_loss_and_latency_info.py new file mode 100644 index 000000000..3f0fe56ed --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/organizations_devices_uplinks_loss_and_latency_info.py @@ -0,0 +1,110 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + organizationId=dict(type="str"), + t0=dict(type="str"), + t1=dict(type="str"), + timespan=dict(type="float"), + uplink=dict(type="str"), + ip=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_all(self, params): + new_object = {} + if params.get("organizationId") is not None: + new_object["organizationId"] = params.get( + "organizationId") + if params.get("t0") is not None: + new_object["t0"] = params.get( + "t0") + if params.get("t1") is not None: + new_object["t1"] = params.get( + "t1") + if params.get("timespan") is not None: + new_object["timespan"] = params.get( + "timespan") + if params.get("uplink") is not None: + new_object["uplink"] = params.get( + "uplink") + if params.get("ip") is not None: + new_object["ip"] = params.get( + "ip") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="organizations", + function='getOrganizationDevicesUplinksLossAndLatency', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/organizations_early_access_features_info.py b/ansible_collections/cisco/meraki/plugins/action/organizations_early_access_features_info.py new file mode 100644 index 000000000..889e735f4 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/organizations_early_access_features_info.py @@ -0,0 +1,90 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + organizationId=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_all(self, params): + new_object = {} + if params.get("organizationId") is not None: + new_object["organizationId"] = params.get( + "organizationId") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="organizations", + function='getOrganizationEarlyAccessFeatures', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/organizations_early_access_features_opt_ins.py b/ansible_collections/cisco/meraki/plugins/action/organizations_early_access_features_opt_ins.py new file mode 100644 index 000000000..7a952168f --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/organizations_early_access_features_opt_ins.py @@ -0,0 +1,308 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or +# https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, + meraki_compare_equality, + get_dict_result, +) +from ansible_collections.cisco.meraki.plugins.plugin_utils.exceptions import ( + InconsistentParameters, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + state=dict(type="str", default="present", choices=["present", "absent"]), + shortName=dict(type="str"), + limitScopeToNetworks=dict(type="list"), + organizationId=dict(type="str"), + optInId=dict(type="str"), +)) + +required_if = [ + ("state", "present", ["optInId", "organizationId"], True), + ("state", "absent", ["optInId", "organizationId"], True), +] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class OrganizationsEarlyAccessFeaturesOptIns(object): + def __init__(self, params, meraki): + self.meraki = meraki + self.new_object = dict( + shortName=params.get("shortName"), + limitScopeToNetworks=params.get("limitScopeToNetworks"), + organizationId=params.get("organizationId"), + optInId=params.get("optInId"), + ) + + def get_all_params(self, name=None, id=None): + new_object_params = {} + if self.new_object.get('organizationId') is not None or self.new_object.get('organization_id') is not None: + new_object_params['organizationId'] = self.new_object.get('organizationId') or \ + self.new_object.get('organization_id') + return new_object_params + + def get_params_by_id(self, name=None, id=None): + new_object_params = {} + if self.new_object.get('organizationId') is not None or self.new_object.get('organization_id') is not None: + new_object_params['organizationId'] = self.new_object.get('organizationId') or \ + self.new_object.get('organization_id') + if self.new_object.get('optInId') is not None or self.new_object.get('opt_in_id') is not None: + new_object_params['optInId'] = self.new_object.get('optInId') or \ + self.new_object.get('opt_in_id') + return new_object_params + + def create_params(self): + new_object_params = {} + if self.new_object.get('shortName') is not None or self.new_object.get('short_name') is not None: + new_object_params['shortName'] = self.new_object.get('shortName') or \ + self.new_object.get('short_name') + if self.new_object.get('limitScopeToNetworks') is not None or self.new_object.get('limit_scope_to_networks') is not None: + new_object_params['limitScopeToNetworks'] = self.new_object.get('limitScopeToNetworks') or \ + self.new_object.get('limit_scope_to_networks') + if self.new_object.get('organizationId') is not None or self.new_object.get('organization_id') is not None: + new_object_params['organizationId'] = self.new_object.get('organizationId') or \ + self.new_object.get('organization_id') + return new_object_params + + def delete_by_id_params(self): + new_object_params = {} + if self.new_object.get('organizationId') is not None or self.new_object.get('organization_id') is not None: + new_object_params['organizationId'] = self.new_object.get('organizationId') or \ + self.new_object.get('organization_id') + if self.new_object.get('optInId') is not None or self.new_object.get('opt_in_id') is not None: + new_object_params['optInId'] = self.new_object.get('optInId') or \ + self.new_object.get('opt_in_id') + return new_object_params + + def update_by_id_params(self): + new_object_params = {} + if self.new_object.get('limitScopeToNetworks') is not None or self.new_object.get('limit_scope_to_networks') is not None: + new_object_params['limitScopeToNetworks'] = self.new_object.get('limitScopeToNetworks') or \ + self.new_object.get('limit_scope_to_networks') + if self.new_object.get('organizationId') is not None or self.new_object.get('organization_id') is not None: + new_object_params['organizationId'] = self.new_object.get('organizationId') or \ + self.new_object.get('organization_id') + if self.new_object.get('optInId') is not None or self.new_object.get('opt_in_id') is not None: + new_object_params['optInId'] = self.new_object.get('optInId') or \ + self.new_object.get('opt_in_id') + return new_object_params + + def get_object_by_name(self, name): + result = None + # NOTE: Does not have a get by name method or it is in another action + try: + items = self.meraki.exec_meraki( + family="organizations", + function="getOrganizationEarlyAccessFeaturesOptIns", + params=self.get_all_params(name=name), + ) + if isinstance(items, dict): + if 'response' in items: + items = items.get('response') + result = get_dict_result(items, 'name', name) + if result is None: + result = items + except Exception as e: + print("Error: ", e) + result = None + return result + + def get_object_by_id(self, id): + result = None + try: + items = self.meraki.exec_meraki( + family="organizations", + function="getOrganizationEarlyAccessFeaturesOptIn", + params=self.get_params_by_id() + ) + if isinstance(items, dict): + if 'response' in items: + items = items.get('response') + result = get_dict_result(items, 'optInId', id) + except Exception as e: + print("Error: ", e) + result = None + return result + + def exists(self): + id_exists = False + name_exists = False + prev_obj = None + o_id = self.new_object.get("id") + o_id = o_id or self.new_object.get( + "opt_in_id") or self.new_object.get("optInId") + name = self.new_object.get("name") + if o_id: + prev_obj = self.get_object_by_id(o_id) + id_exists = prev_obj is not None and isinstance(prev_obj, dict) + if not id_exists and name: + prev_obj = self.get_object_by_name(name) + name_exists = prev_obj is not None and isinstance(prev_obj, dict) + if name_exists: + _id = prev_obj.get("id") + _id = _id or prev_obj.get("optInId") + if id_exists and name_exists and o_id != _id: + raise InconsistentParameters( + "The 'id' and 'name' params don't refer to the same object") + if _id: + self.new_object.update(dict(id=_id)) + self.new_object.update(dict(optInId=_id)) + if _id: + prev_obj = self.get_object_by_id(_id) + it_exists = prev_obj is not None and isinstance(prev_obj, dict) + return (it_exists, prev_obj) + + def requires_update(self, current_obj): + requested_obj = self.new_object + + obj_params = [ + ("shortName", "shortName"), + ("limitScopeToNetworks", "limitScopeToNetworks"), + ("organizationId", "organizationId"), + ("optInId", "optInId"), + ] + # Method 1. Params present in request (Ansible) obj are the same as the current (DNAC) params + # If any does not have eq params, it requires update + return any(not meraki_compare_equality(current_obj.get(meraki_param), + requested_obj.get(ansible_param)) + for (meraki_param, ansible_param) in obj_params) + + def create(self): + result = self.meraki.exec_meraki( + family="organizations", + function="createOrganizationEarlyAccessFeaturesOptIn", + params=self.create_params(), + op_modifies=True, + ) + return result + + def update(self): + id = self.new_object.get("id") + id = id or self.new_object.get("optInId") + name = self.new_object.get("name") + result = None + if not id: + prev_obj_name = self.get_object_by_name(name) + id_ = None + if prev_obj_name: + id_ = prev_obj_name.get("id") + id_ = id_ or prev_obj_name.get("optInId") + if id_: + self.new_object.update(dict(optInId=id_)) + result = self.meraki.exec_meraki( + family="organizations", + function="updateOrganizationEarlyAccessFeaturesOptIn", + params=self.update_by_id_params(), + op_modifies=True, + ) + return result + + def delete(self): + id = self.new_object.get("id") + id = id or self.new_object.get("optInId") + name = self.new_object.get("name") + result = None + if not id: + prev_obj_name = self.get_object_by_name(name) + id_ = None + if prev_obj_name: + id_ = prev_obj_name.get("id") + id_ = id_ or prev_obj_name.get("optInId") + if id_: + self.new_object.update(dict(optInId=id_)) + result = self.meraki.exec_meraki( + family="organizations", + function="deleteOrganizationEarlyAccessFeaturesOptIn", + params=self.delete_by_id_params(), + ) + return result + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = False + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + meraki = MERAKI(self._task.args) + obj = OrganizationsEarlyAccessFeaturesOptIns(self._task.args, meraki) + + state = self._task.args.get("state") + + response = None + + if state == "present": + (obj_exists, prev_obj) = obj.exists() + if obj_exists: + if obj.requires_update(prev_obj): + response = obj.update() + meraki.object_updated() + else: + response = prev_obj + meraki.object_already_present() + else: + response = obj.create() + meraki.object_created() + + elif state == "absent": + (obj_exists, prev_obj) = obj.exists() + if obj_exists: + response = obj.delete() + meraki.object_deleted() + else: + meraki.object_already_absent() + + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/organizations_early_access_features_opt_ins_info.py b/ansible_collections/cisco/meraki/plugins/action/organizations_early_access_features_opt_ins_info.py new file mode 100644 index 000000000..f104a1fa6 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/organizations_early_access_features_opt_ins_info.py @@ -0,0 +1,112 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + organizationId=dict(type="str"), + optInId=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_object(self, params): + new_object = {} + if params.get("organizationId") is not None: + new_object["organizationId"] = params.get( + "organizationId") + if params.get("optInId") is not None: + new_object["optInId"] = params.get( + "optInId") + return new_object + + def get_all(self, params): + new_object = {} + if params.get("organizationId") is not None: + new_object["organizationId"] = params.get( + "organizationId") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + id = self._task.args.get("optInId") + if id: + response = meraki.exec_meraki( + family="organizations", + function='getOrganizationEarlyAccessFeaturesOptIn', + params=self.get_object(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result + if not id: + response = meraki.exec_meraki( + family="organizations", + function='getOrganizationEarlyAccessFeaturesOptIns', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/organizations_firmware_upgrades_by_device_info.py b/ansible_collections/cisco/meraki/plugins/action/organizations_firmware_upgrades_by_device_info.py new file mode 100644 index 000000000..254770a93 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/organizations_firmware_upgrades_by_device_info.py @@ -0,0 +1,128 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + organizationId=dict(type="str"), + perPage=dict(type="int"), + total_pages=dict(type="int"), + direction=dict(type="str"), + startingAfter=dict(type="str"), + endingBefore=dict(type="str"), + networkIds=dict(type="list"), + serials=dict(type="list"), + macs=dict(type="list"), + firmwareUpgradeIds=dict(type="list"), + firmwareUpgradeBatchIds=dict(type="list"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_all(self, params): + new_object = {} + if params.get("organizationId") is not None: + new_object["organizationId"] = params.get( + "organizationId") + if params.get("perPage") is not None: + new_object["perPage"] = params.get( + "perPage") + new_object['total_pages'] = params.get( + "total_pages") or 1 + new_object['direction'] = params.get( + "direction") or "next" + if params.get("startingAfter") is not None: + new_object["startingAfter"] = params.get( + "startingAfter") + if params.get("endingBefore") is not None: + new_object["endingBefore"] = params.get( + "endingBefore") + if params.get("networkIds") is not None: + new_object["networkIds"] = params.get( + "networkIds") + if params.get("serials") is not None: + new_object["serials"] = params.get( + "serials") + if params.get("macs") is not None: + new_object["macs"] = params.get( + "macs") + if params.get("firmwareUpgradeIds") is not None: + new_object["firmwareUpgradeIds"] = params.get( + "firmwareUpgradeIds") + if params.get("firmwareUpgradeBatchIds") is not None: + new_object["firmwareUpgradeBatchIds"] = params.get( + "firmwareUpgradeBatchIds") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="organizations", + function='getOrganizationFirmwareUpgradesByDevice', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/organizations_firmware_upgrades_info.py b/ansible_collections/cisco/meraki/plugins/action/organizations_firmware_upgrades_info.py new file mode 100644 index 000000000..e8e72f6ce --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/organizations_firmware_upgrades_info.py @@ -0,0 +1,98 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + organizationId=dict(type="str"), + status=dict(type="list"), + productType=dict(type="list"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_all(self, params): + new_object = {} + if params.get("organizationId") is not None: + new_object["organizationId"] = params.get( + "organizationId") + if params.get("status") is not None: + new_object["status"] = params.get( + "status") + if params.get("productType") is not None: + new_object["productType"] = params.get( + "productType") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="organizations", + function='getOrganizationFirmwareUpgrades', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/organizations_info.py b/ansible_collections/cisco/meraki/plugins/action/organizations_info.py new file mode 100644 index 000000000..e7dba48d4 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/organizations_info.py @@ -0,0 +1,105 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + organizationId=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_object(self, params): + new_object = {} + if params.get("organizationId") is not None: + new_object["organizationId"] = params.get( + "organizationId") + return new_object + + def get_all(self, params): + new_object = {} + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + id = self._task.args.get("organizationId") + if id: + response = meraki.exec_meraki( + family="organizations", + function='getOrganization', + params=self.get_object(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result + if not id: + response = meraki.exec_meraki( + family="organizations", + function='getOrganizations', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/organizations_insight_applications_info.py b/ansible_collections/cisco/meraki/plugins/action/organizations_insight_applications_info.py new file mode 100644 index 000000000..f3227dd77 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/organizations_insight_applications_info.py @@ -0,0 +1,90 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + organizationId=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_all(self, params): + new_object = {} + if params.get("organizationId") is not None: + new_object["organizationId"] = params.get( + "organizationId") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="insight", + function='getOrganizationInsightApplications', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/organizations_insight_monitored_media_servers.py b/ansible_collections/cisco/meraki/plugins/action/organizations_insight_monitored_media_servers.py new file mode 100644 index 000000000..14957d943 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/organizations_insight_monitored_media_servers.py @@ -0,0 +1,318 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or +# https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, + meraki_compare_equality, + get_dict_result, +) +from ansible_collections.cisco.meraki.plugins.plugin_utils.exceptions import ( + InconsistentParameters, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + state=dict(type="str", default="present", choices=["present", "absent"]), + name=dict(type="str"), + address=dict(type="str"), + bestEffortMonitoringEnabled=dict(type="bool"), + organizationId=dict(type="str"), + monitoredMediaServerId=dict(type="str"), +)) + +required_if = [ + ("state", "present", ["monitoredMediaServerId", "name", "organizationId"], True), + ("state", "absent", ["monitoredMediaServerId", "name", "organizationId"], True), +] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class OrganizationsInsightMonitoredMediaServers(object): + def __init__(self, params, meraki): + self.meraki = meraki + self.new_object = dict( + name=params.get("name"), + address=params.get("address"), + bestEffortMonitoringEnabled=params.get("bestEffortMonitoringEnabled"), + organizationId=params.get("organizationId"), + monitoredMediaServerId=params.get("monitoredMediaServerId"), + ) + + def get_all_params(self, name=None, id=None): + new_object_params = {} + if self.new_object.get('organizationId') is not None or self.new_object.get('organization_id') is not None: + new_object_params['organizationId'] = self.new_object.get('organizationId') or \ + self.new_object.get('organization_id') + return new_object_params + + def get_params_by_id(self, name=None, id=None): + new_object_params = {} + if self.new_object.get('organizationId') is not None or self.new_object.get('organization_id') is not None: + new_object_params['organizationId'] = self.new_object.get('organizationId') or \ + self.new_object.get('organization_id') + if self.new_object.get('monitoredMediaServerId') is not None or self.new_object.get('monitored_media_server_id') is not None: + new_object_params['monitoredMediaServerId'] = self.new_object.get('monitoredMediaServerId') or \ + self.new_object.get('monitored_media_server_id') + return new_object_params + + def create_params(self): + new_object_params = {} + if self.new_object.get('name') is not None or self.new_object.get('name') is not None: + new_object_params['name'] = self.new_object.get('name') or \ + self.new_object.get('name') + if self.new_object.get('address') is not None or self.new_object.get('address') is not None: + new_object_params['address'] = self.new_object.get('address') or \ + self.new_object.get('address') + if self.new_object.get('bestEffortMonitoringEnabled') is not None or self.new_object.get('best_effort_monitoring_enabled') is not None: + new_object_params['bestEffortMonitoringEnabled'] = self.new_object.get('bestEffortMonitoringEnabled') + if self.new_object.get('organizationId') is not None or self.new_object.get('organization_id') is not None: + new_object_params['organizationId'] = self.new_object.get('organizationId') or \ + self.new_object.get('organization_id') + return new_object_params + + def delete_by_id_params(self): + new_object_params = {} + if self.new_object.get('organizationId') is not None or self.new_object.get('organization_id') is not None: + new_object_params['organizationId'] = self.new_object.get('organizationId') or \ + self.new_object.get('organization_id') + if self.new_object.get('monitoredMediaServerId') is not None or self.new_object.get('monitored_media_server_id') is not None: + new_object_params['monitoredMediaServerId'] = self.new_object.get('monitoredMediaServerId') or \ + self.new_object.get('monitored_media_server_id') + return new_object_params + + def update_by_id_params(self): + new_object_params = {} + if self.new_object.get('name') is not None or self.new_object.get('name') is not None: + new_object_params['name'] = self.new_object.get('name') or \ + self.new_object.get('name') + if self.new_object.get('address') is not None or self.new_object.get('address') is not None: + new_object_params['address'] = self.new_object.get('address') or \ + self.new_object.get('address') + if self.new_object.get('bestEffortMonitoringEnabled') is not None or self.new_object.get('best_effort_monitoring_enabled') is not None: + new_object_params['bestEffortMonitoringEnabled'] = self.new_object.get('bestEffortMonitoringEnabled') + if self.new_object.get('organizationId') is not None or self.new_object.get('organization_id') is not None: + new_object_params['organizationId'] = self.new_object.get('organizationId') or \ + self.new_object.get('organization_id') + if self.new_object.get('monitoredMediaServerId') is not None or self.new_object.get('monitored_media_server_id') is not None: + new_object_params['monitoredMediaServerId'] = self.new_object.get('monitoredMediaServerId') or \ + self.new_object.get('monitored_media_server_id') + return new_object_params + + def get_object_by_name(self, name): + result = None + # NOTE: Does not have a get by name method or it is in another action + try: + items = self.meraki.exec_meraki( + family="insight", + function="getOrganizationInsightMonitoredMediaServers", + params=self.get_all_params(name=name), + ) + if isinstance(items, dict): + if 'response' in items: + items = items.get('response') + result = get_dict_result(items, 'name', name) + if result is None: + result = items + except Exception as e: + print("Error: ", e) + result = None + return result + + def get_object_by_id(self, id): + result = None + try: + items = self.meraki.exec_meraki( + family="insight", + function="getOrganizationInsightMonitoredMediaServer", + params=self.get_params_by_id() + ) + if isinstance(items, dict): + if 'response' in items: + items = items.get('response') + result = get_dict_result(items, 'monitoredMediaServerId', id) + except Exception as e: + print("Error: ", e) + result = None + return result + + def exists(self): + id_exists = False + name_exists = False + prev_obj = None + o_id = self.new_object.get("id") + o_id = o_id or self.new_object.get( + "monitored_media_server_id") or self.new_object.get("monitoredMediaServerId") + name = self.new_object.get("name") + if o_id: + prev_obj = self.get_object_by_id(o_id) + id_exists = prev_obj is not None and isinstance(prev_obj, dict) + if not id_exists and name: + prev_obj = self.get_object_by_name(name) + name_exists = prev_obj is not None and isinstance(prev_obj, dict) + if name_exists: + _id = prev_obj.get("id") + _id = _id or prev_obj.get("monitoredMediaServerId") + if id_exists and name_exists and o_id != _id: + raise InconsistentParameters( + "The 'id' and 'name' params don't refer to the same object") + if _id: + self.new_object.update(dict(id=_id)) + self.new_object.update(dict(monitoredMediaServerId=_id)) + if _id: + prev_obj = self.get_object_by_id(_id) + it_exists = prev_obj is not None and isinstance(prev_obj, dict) + return (it_exists, prev_obj) + + def requires_update(self, current_obj): + requested_obj = self.new_object + + obj_params = [ + ("name", "name"), + ("address", "address"), + ("bestEffortMonitoringEnabled", "bestEffortMonitoringEnabled"), + ("organizationId", "organizationId"), + ("monitoredMediaServerId", "monitoredMediaServerId"), + ] + # Method 1. Params present in request (Ansible) obj are the same as the current (DNAC) params + # If any does not have eq params, it requires update + return any(not meraki_compare_equality(current_obj.get(meraki_param), + requested_obj.get(ansible_param)) + for (meraki_param, ansible_param) in obj_params) + + def create(self): + result = self.meraki.exec_meraki( + family="insight", + function="createOrganizationInsightMonitoredMediaServer", + params=self.create_params(), + op_modifies=True, + ) + return result + + def update(self): + id = self.new_object.get("id") + id = id or self.new_object.get("monitoredMediaServerId") + name = self.new_object.get("name") + result = None + if not id: + prev_obj_name = self.get_object_by_name(name) + id_ = None + if prev_obj_name: + id_ = prev_obj_name.get("id") + id_ = id_ or prev_obj_name.get("monitoredMediaServerId") + if id_: + self.new_object.update(dict(monitoredMediaServerId=id_)) + result = self.meraki.exec_meraki( + family="insight", + function="updateOrganizationInsightMonitoredMediaServer", + params=self.update_by_id_params(), + op_modifies=True, + ) + return result + + def delete(self): + id = self.new_object.get("id") + id = id or self.new_object.get("monitoredMediaServerId") + name = self.new_object.get("name") + result = None + if not id: + prev_obj_name = self.get_object_by_name(name) + id_ = None + if prev_obj_name: + id_ = prev_obj_name.get("id") + id_ = id_ or prev_obj_name.get("monitoredMediaServerId") + if id_: + self.new_object.update(dict(monitoredMediaServerId=id_)) + result = self.meraki.exec_meraki( + family="insight", + function="deleteOrganizationInsightMonitoredMediaServer", + params=self.delete_by_id_params(), + ) + return result + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = False + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + meraki = MERAKI(self._task.args) + obj = OrganizationsInsightMonitoredMediaServers(self._task.args, meraki) + + state = self._task.args.get("state") + + response = None + + if state == "present": + (obj_exists, prev_obj) = obj.exists() + if obj_exists: + if obj.requires_update(prev_obj): + response = obj.update() + meraki.object_updated() + else: + response = prev_obj + meraki.object_already_present() + else: + response = obj.create() + meraki.object_created() + + elif state == "absent": + (obj_exists, prev_obj) = obj.exists() + if obj_exists: + response = obj.delete() + meraki.object_deleted() + else: + meraki.object_already_absent() + + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/organizations_insight_monitored_media_servers_info.py b/ansible_collections/cisco/meraki/plugins/action/organizations_insight_monitored_media_servers_info.py new file mode 100644 index 000000000..aeff26f2b --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/organizations_insight_monitored_media_servers_info.py @@ -0,0 +1,112 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + organizationId=dict(type="str"), + monitoredMediaServerId=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_object(self, params): + new_object = {} + if params.get("organizationId") is not None: + new_object["organizationId"] = params.get( + "organizationId") + if params.get("monitoredMediaServerId") is not None: + new_object["monitoredMediaServerId"] = params.get( + "monitoredMediaServerId") + return new_object + + def get_all(self, params): + new_object = {} + if params.get("organizationId") is not None: + new_object["organizationId"] = params.get( + "organizationId") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + id = self._task.args.get("monitoredMediaServerId") + if id: + response = meraki.exec_meraki( + family="insight", + function='getOrganizationInsightMonitoredMediaServer', + params=self.get_object(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result + if not id: + response = meraki.exec_meraki( + family="insight", + function='getOrganizationInsightMonitoredMediaServers', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/organizations_inventory_claim.py b/ansible_collections/cisco/meraki/plugins/action/organizations_inventory_claim.py new file mode 100644 index 000000000..5bc648b91 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/organizations_inventory_claim.py @@ -0,0 +1,93 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguements specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + orders=dict(type="list"), + serials=dict(type="list"), + licenses=dict(type="list"), + organizationId=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = False + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_object(self, params): + new_object = dict( + orders=params.get("orders"), + serials=params.get("serials"), + licenses=params.get("licenses"), + organizationId=params.get("organizationId"), + ) + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="organizations", + function='claimIntoOrganizationInventory', + op_modifies=True, + params=self.get_object(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/organizations_inventory_devices_info.py b/ansible_collections/cisco/meraki/plugins/action/organizations_inventory_devices_info.py new file mode 100644 index 000000000..5c94ac258 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/organizations_inventory_devices_info.py @@ -0,0 +1,170 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + organizationId=dict(type="str"), + perPage=dict(type="int"), + total_pages=dict(type="int"), + direction=dict(type="str"), + startingAfter=dict(type="str"), + endingBefore=dict(type="str"), + usedState=dict(type="str"), + search=dict(type="str"), + macs=dict(type="list"), + networkIds=dict(type="list"), + serials=dict(type="list"), + models=dict(type="list"), + orderNumbers=dict(type="list"), + tags=dict(type="list"), + tagsFilterType=dict(type="str"), + productTypes=dict(type="list"), + serial=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_object(self, params): + new_object = {} + if params.get("organizationId") is not None: + new_object["organizationId"] = params.get( + "organizationId") + if params.get("serial") is not None: + new_object["serial"] = params.get( + "serial") + return new_object + + def get_all(self, params): + new_object = {} + if params.get("organizationId") is not None: + new_object["organizationId"] = params.get( + "organizationId") + if params.get("perPage") is not None: + new_object["perPage"] = params.get( + "perPage") + new_object['total_pages'] = params.get( + "total_pages") or 1 + new_object['direction'] = params.get( + "direction") or "next" + if params.get("startingAfter") is not None: + new_object["startingAfter"] = params.get( + "startingAfter") + if params.get("endingBefore") is not None: + new_object["endingBefore"] = params.get( + "endingBefore") + if params.get("usedState") is not None: + new_object["usedState"] = params.get( + "usedState") + if params.get("search") is not None: + new_object["search"] = params.get( + "search") + if params.get("macs") is not None: + new_object["macs"] = params.get( + "macs") + if params.get("networkIds") is not None: + new_object["networkIds"] = params.get( + "networkIds") + if params.get("serials") is not None: + new_object["serials"] = params.get( + "serials") + if params.get("models") is not None: + new_object["models"] = params.get( + "models") + if params.get("orderNumbers") is not None: + new_object["orderNumbers"] = params.get( + "orderNumbers") + if params.get("tags") is not None: + new_object["tags"] = params.get( + "tags") + if params.get("tagsFilterType") is not None: + new_object["tagsFilterType"] = params.get( + "tagsFilterType") + if params.get("productTypes") is not None: + new_object["productTypes"] = params.get( + "productTypes") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + id = self._task.args.get("serial") + if id: + response = meraki.exec_meraki( + family="organizations", + function='getOrganizationInventoryDevice', + params=self.get_object(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result + if not id: + response = meraki.exec_meraki( + family="organizations", + function='getOrganizationInventoryDevices', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/organizations_inventory_onboarding_cloud_monitoring_export_events.py b/ansible_collections/cisco/meraki/plugins/action/organizations_inventory_onboarding_cloud_monitoring_export_events.py new file mode 100644 index 000000000..11cefb220 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/organizations_inventory_onboarding_cloud_monitoring_export_events.py @@ -0,0 +1,95 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguements specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + logEvent=dict(type="str"), + timestamp=dict(type="int"), + targetOS=dict(type="str"), + request=dict(type="str"), + organizationId=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = False + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_object(self, params): + new_object = dict( + logEvent=params.get("logEvent"), + timestamp=params.get("timestamp"), + targetOS=params.get("targetOS"), + request=params.get("request"), + organizationId=params.get("organizationId"), + ) + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="organizations", + function='createOrganizationInventoryOnboardingCloudMonitoringExportEvent', + op_modifies=True, + params=self.get_object(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/organizations_inventory_onboarding_cloud_monitoring_imports.py b/ansible_collections/cisco/meraki/plugins/action/organizations_inventory_onboarding_cloud_monitoring_imports.py new file mode 100644 index 000000000..811acb9bd --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/organizations_inventory_onboarding_cloud_monitoring_imports.py @@ -0,0 +1,200 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or +# https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, + meraki_compare_equality, + get_dict_result, +) +from ansible_collections.cisco.meraki.plugins.plugin_utils.exceptions import ( + InconsistentParameters, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + state=dict(type="str", default="present", choices=["present"]), + devices=dict(type="list"), + organizationId=dict(type="str"), +)) + +required_if = [ + ("state", "present", ["organizationId"], True), +] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class OrganizationsInventoryOnboardingCloudMonitoringImports(object): + def __init__(self, params, meraki): + self.meraki = meraki + self.new_object = dict( + devices=params.get("devices"), + organization_id=params.get("organizationId"), + ) + + def get_all_params(self, name=None, id=None): + new_object_params = {} + if self.new_object.get('importIds') is not None or self.new_object.get('import_ids') is not None: + new_object_params['importIds'] = self.new_object.get('importIds') or \ + self.new_object.get('import_ids') + if self.new_object.get('organizationId') is not None or self.new_object.get('organization_id') is not None: + new_object_params['organizationId'] = self.new_object.get('organizationId') or \ + self.new_object.get('organization_id') + return new_object_params + + def create_params(self): + new_object_params = {} + if self.new_object.get('devices') is not None or self.new_object.get('devices') is not None: + new_object_params['devices'] = self.new_object.get('devices') or \ + self.new_object.get('devices') + if self.new_object.get('organizationId') is not None or self.new_object.get('organization_id') is not None: + new_object_params['organizationId'] = self.new_object.get('organizationId') or \ + self.new_object.get('organization_id') + return new_object_params + + def get_object_by_name(self, name): + result = None + # NOTE: Does not have a get by name method, using get all + try: + items = self.meraki.exec_meraki( + family="organizations", + function="getOrganizationInventoryOnboardingCloudMonitoringImports", + params=self.get_all_params(name=name), + ) + if isinstance(items, dict): + if 'response' in items: + items = items.get('response') + result = get_dict_result(items, 'name', name) + if result is None: + result = items + except Exception as e: + print("Error: ", e) + result = None + return result + + def get_object_by_id(self, id): + result = None + # NOTE: Does not have a get by id method or it is in another action + return result + + def exists(self): + prev_obj = None + id_exists = False + name_exists = False + o_id = self.new_object.get("id") + name = self.new_object.get("name") + if o_id: + prev_obj = self.get_object_by_name(o_id) + id_exists = prev_obj is not None and isinstance(prev_obj, dict) + if not id_exists and name: + prev_obj = self.get_object_by_name(name) + name_exists = prev_obj is not None and isinstance(prev_obj, dict) + if name_exists: + _id = prev_obj.get("id") + if id_exists and name_exists and o_id != _id: + raise InconsistentParameters( + "The 'id' and 'name' params don't refer to the same object") + if _id: + self.new_object.update(dict(id=_id)) + it_exists = prev_obj is not None and isinstance(prev_obj, dict) + return (it_exists, prev_obj) + + def requires_update(self, current_obj): + requested_obj = self.new_object + + obj_params = [ + ("devices", "devices"), + ("organizationId", "organizationId"), + ] + # Method 1. Params present in request (Ansible) obj are the same as the current (ISE) params + # If any does not have eq params, it requires update + return any(not meraki_compare_equality(current_obj.get(meraki_param), + requested_obj.get(ansible_param)) + for (meraki_param, ansible_param) in obj_params) + + def create(self): + result = self.meraki.exec_meraki( + family="organizations", + function="createOrganizationInventoryOnboardingCloudMonitoringImport", + params=self.create_params(), + op_modifies=True, + ) + return result + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = False + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + meraki = MERAKI(self._task.args) + obj = OrganizationsInventoryOnboardingCloudMonitoringImports(self._task.args, meraki) + + state = self._task.args.get("state") + + response = None + if state == "present": + (obj_exists, prev_obj) = obj.exists() + if obj_exists: + if obj.requires_update(prev_obj): + response = prev_obj + meraki.object_present_and_different() + else: + response = prev_obj + meraki.object_already_present() + else: + response = obj.create() + meraki.object_created() + + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/organizations_inventory_onboarding_cloud_monitoring_imports_info.py b/ansible_collections/cisco/meraki/plugins/action/organizations_inventory_onboarding_cloud_monitoring_imports_info.py new file mode 100644 index 000000000..c58fd6d8b --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/organizations_inventory_onboarding_cloud_monitoring_imports_info.py @@ -0,0 +1,94 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + organizationId=dict(type="str"), + importIds=dict(type="list"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_all(self, params): + new_object = {} + if params.get("organizationId") is not None: + new_object["organizationId"] = params.get( + "organizationId") + if params.get("importIds") is not None: + new_object["importIds"] = params.get( + "importIds") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="organizations", + function='getOrganizationInventoryOnboardingCloudMonitoringImports', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/organizations_inventory_onboarding_cloud_monitoring_networks_info.py b/ansible_collections/cisco/meraki/plugins/action/organizations_inventory_onboarding_cloud_monitoring_networks_info.py new file mode 100644 index 000000000..409b7abdb --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/organizations_inventory_onboarding_cloud_monitoring_networks_info.py @@ -0,0 +1,112 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + organizationId=dict(type="str"), + deviceType=dict(type="str"), + perPage=dict(type="int"), + total_pages=dict(type="int"), + direction=dict(type="str"), + startingAfter=dict(type="str"), + endingBefore=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_all(self, params): + new_object = {} + if params.get("organizationId") is not None: + new_object["organizationId"] = params.get( + "organizationId") + if params.get("deviceType") is not None: + new_object["deviceType"] = params.get( + "deviceType") + if params.get("perPage") is not None: + new_object["perPage"] = params.get( + "perPage") + new_object['total_pages'] = params.get( + "total_pages") or 1 + new_object['direction'] = params.get( + "direction") or "next" + if params.get("startingAfter") is not None: + new_object["startingAfter"] = params.get( + "startingAfter") + if params.get("endingBefore") is not None: + new_object["endingBefore"] = params.get( + "endingBefore") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="organizations", + function='getOrganizationInventoryOnboardingCloudMonitoringNetworks', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/organizations_inventory_onboarding_cloud_monitoring_prepare.py b/ansible_collections/cisco/meraki/plugins/action/organizations_inventory_onboarding_cloud_monitoring_prepare.py new file mode 100644 index 000000000..51efc8790 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/organizations_inventory_onboarding_cloud_monitoring_prepare.py @@ -0,0 +1,89 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguements specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + devices=dict(type="list"), + organizationId=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = False + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_object(self, params): + new_object = dict( + devices=params.get("devices"), + organizationId=params.get("organizationId"), + ) + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="organizations", + function='createOrganizationInventoryOnboardingCloudMonitoringPrepare', + op_modifies=True, + params=self.get_object(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/organizations_inventory_release.py b/ansible_collections/cisco/meraki/plugins/action/organizations_inventory_release.py new file mode 100644 index 000000000..af36faa05 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/organizations_inventory_release.py @@ -0,0 +1,89 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguements specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + serials=dict(type="list"), + organizationId=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = False + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_object(self, params): + new_object = dict( + serials=params.get("serials"), + organizationId=params.get("organizationId"), + ) + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="organizations", + function='releaseFromOrganizationInventory', + op_modifies=True, + params=self.get_object(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/organizations_licenses.py b/ansible_collections/cisco/meraki/plugins/action/organizations_licenses.py new file mode 100644 index 000000000..33f0bb98c --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/organizations_licenses.py @@ -0,0 +1,220 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or +# https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, + meraki_compare_equality, +) +from ansible_collections.cisco.meraki.plugins.plugin_utils.exceptions import ( + InconsistentParameters, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + state=dict(type="str", default="present", choices=["present"]), + deviceSerial=dict(type="str"), + organizationId=dict(type="str"), + licenseId=dict(type="str"), +)) + +required_if = [ + ("state", "present", ["licenseId", "organizationId"], True), +] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class OrganizationsLicenses(object): + def __init__(self, params, meraki): + self.meraki = meraki + self.new_object = dict( + deviceSerial=params.get("deviceSerial"), + organization_id=params.get("organizationId"), + license_id=params.get("licenseId"), + ) + + def get_params_by_id(self, name=None, id=None): + new_object_params = {} + if self.new_object.get('organizationId') is not None or self.new_object.get('organization_id') is not None: + new_object_params['organizationId'] = self.new_object.get('organizationId') or \ + self.new_object.get('organization_id') + if self.new_object.get('licenseId') is not None or self.new_object.get('license_id') is not None: + new_object_params['licenseId'] = self.new_object.get('licenseId') or \ + self.new_object.get('license_id') + return new_object_params + + def update_by_id_params(self): + new_object_params = {} + if self.new_object.get('deviceSerial') is not None or self.new_object.get('device_serial') is not None: + new_object_params['deviceSerial'] = self.new_object.get('deviceSerial') or \ + self.new_object.get('device_serial') + if self.new_object.get('organizationId') is not None or self.new_object.get('organization_id') is not None: + new_object_params['organizationId'] = self.new_object.get('organizationId') or \ + self.new_object.get('organization_id') + if self.new_object.get('licenseId') is not None or self.new_object.get('license_id') is not None: + new_object_params['licenseId'] = self.new_object.get('licenseId') or \ + self.new_object.get('license_id') + return new_object_params + + def get_object_by_name(self, name): + result = None + # NOTE: Does not have a get by name and get all + return result + + def get_object_by_id(self, id): + result = None + try: + items = self.meraki.exec_meraki( + family="organizations", + function="getOrganizationLicense", + params=self.get_params_by_id() + ) + if isinstance(items, dict): + if 'response' in items: + items = items.get('response') + result = items + except Exception as e: + print("Error: ", e) + result = None + return result + + def exists(self): + prev_obj = None + id_exists = False + name_exists = False + o_id = self.new_object.get("id") + o_id = o_id or self.new_object.get( + "license_id") or self.new_object.get("licenseId") + name = self.new_object.get("name") + if o_id: + prev_obj = self.get_object_by_id(o_id) + id_exists = prev_obj is not None and isinstance(prev_obj, dict) + if not id_exists and name: + prev_obj = self.get_object_by_name(name) + name_exists = prev_obj is not None and isinstance(prev_obj, dict) + if name_exists: + _id = prev_obj.get("id") + _id = _id or prev_obj.get("licenseId") + if id_exists and name_exists and o_id != _id: + raise InconsistentParameters( + "The 'id' and 'name' params don't refer to the same object") + if _id: + self.new_object.update(dict(id=_id)) + self.new_object.update(dict(licenseId=_id)) + if _id: + prev_obj = self.get_object_by_id(_id) + it_exists = prev_obj is not None and isinstance(prev_obj, dict) + return (it_exists, prev_obj) + + def requires_update(self, current_obj): + requested_obj = self.new_object + + obj_params = [ + ("deviceSerial", "deviceSerial"), + ("organizationId", "organizationId"), + ("licenseId", "licenseId"), + ] + # Method 1. Params present in request (Ansible) obj are the same as the current (ISE) params + # If any does not have eq params, it requires update + return any(not meraki_compare_equality(current_obj.get(meraki_param), + requested_obj.get(ansible_param)) + for (meraki_param, ansible_param) in obj_params) + + def update(self): + id = self.new_object.get("id") + id = id or self.new_object.get("licenseId") + name = self.new_object.get("name") + result = None + if not id: + prev_obj_name = self.get_object_by_name(name) + id_ = None + if prev_obj_name: + id_ = prev_obj_name.get("id") + id_ = id_ or prev_obj_name.get("licenseId") + if id_: + self.new_object.update(dict(licenseid=id_)) + result = self.meraki.exec_meraki( + family="organizations", + function="updateOrganizationLicense", + params=self.update_by_id_params(), + op_modifies=True, + ) + return result + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = False + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + meraki = MERAKI(self._task.args) + obj = OrganizationsLicenses(self._task.args, meraki) + + state = self._task.args.get("state") + + response = None + if state == "present": + (obj_exists, prev_obj) = obj.exists() + if obj_exists: + if obj.requires_update(prev_obj): + response = obj.update() + meraki.object_updated() + else: + response = prev_obj + meraki.object_already_present() + else: + meraki.fail_json( + "Object does not exists, plugin only has update") + + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/organizations_licenses_assign_seats.py b/ansible_collections/cisco/meraki/plugins/action/organizations_licenses_assign_seats.py new file mode 100644 index 000000000..8513ed4af --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/organizations_licenses_assign_seats.py @@ -0,0 +1,93 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguements specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + licenseId=dict(type="str"), + networkId=dict(type="str"), + seatCount=dict(type="int"), + organizationId=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = False + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_object(self, params): + new_object = dict( + licenseId=params.get("licenseId"), + networkId=params.get("networkId"), + seatCount=params.get("seatCount"), + organizationId=params.get("organizationId"), + ) + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="organizations", + function='assignOrganizationLicensesSeats', + op_modifies=True, + params=self.get_object(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/organizations_licenses_info.py b/ansible_collections/cisco/meraki/plugins/action/organizations_licenses_info.py new file mode 100644 index 000000000..2cb6487b3 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/organizations_licenses_info.py @@ -0,0 +1,102 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + organizationId=dict(type="str"), + licenseId=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_object(self, params): + new_object = {} + if params.get("organizationId") is not None: + new_object["organizationId"] = params.get( + "organizationId") + if params.get("licenseId") is not None: + new_object["licenseId"] = params.get( + "licenseId") + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + id = self._task.args.get("licenseId") + if id: + response = meraki.exec_meraki( + family="organizations", + function='getOrganizationLicense', + params=self.get_object(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result + if not id: + # NOTE: Does not have a get all method or it is in another action + response = None + meraki.object_modify_result(changed=False, result="Module does not have get all, check arguments of module") + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/organizations_licenses_move.py b/ansible_collections/cisco/meraki/plugins/action/organizations_licenses_move.py new file mode 100644 index 000000000..c030cc8f7 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/organizations_licenses_move.py @@ -0,0 +1,91 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguements specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + destOrganizationId=dict(type="str"), + licenseIds=dict(type="list"), + organizationId=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = False + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_object(self, params): + new_object = dict( + destOrganizationId=params.get("destOrganizationId"), + licenseIds=params.get("licenseIds"), + organizationId=params.get("organizationId"), + ) + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="organizations", + function='moveOrganizationLicenses', + op_modifies=True, + params=self.get_object(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/organizations_licenses_move_seats.py b/ansible_collections/cisco/meraki/plugins/action/organizations_licenses_move_seats.py new file mode 100644 index 000000000..ba1a264c2 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/organizations_licenses_move_seats.py @@ -0,0 +1,93 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguements specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + destOrganizationId=dict(type="str"), + licenseId=dict(type="str"), + seatCount=dict(type="int"), + organizationId=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = False + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_object(self, params): + new_object = dict( + destOrganizationId=params.get("destOrganizationId"), + licenseId=params.get("licenseId"), + seatCount=params.get("seatCount"), + organizationId=params.get("organizationId"), + ) + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="organizations", + function='moveOrganizationLicensesSeats', + op_modifies=True, + params=self.get_object(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/organizations_licenses_overview_info.py b/ansible_collections/cisco/meraki/plugins/action/organizations_licenses_overview_info.py new file mode 100644 index 000000000..cb77c1135 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/organizations_licenses_overview_info.py @@ -0,0 +1,90 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + organizationId=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_all(self, params): + new_object = {} + if params.get("organizationId") is not None: + new_object["organizationId"] = params.get( + "organizationId") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="organizations", + function='getOrganizationLicensesOverview', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/organizations_licenses_renew_seats.py b/ansible_collections/cisco/meraki/plugins/action/organizations_licenses_renew_seats.py new file mode 100644 index 000000000..b5f24f336 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/organizations_licenses_renew_seats.py @@ -0,0 +1,91 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguements specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + licenseIdToRenew=dict(type="str"), + unusedLicenseId=dict(type="str"), + organizationId=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = False + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_object(self, params): + new_object = dict( + licenseIdToRenew=params.get("licenseIdToRenew"), + unusedLicenseId=params.get("unusedLicenseId"), + organizationId=params.get("organizationId"), + ) + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="organizations", + function='renewOrganizationLicensesSeats', + op_modifies=True, + params=self.get_object(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/organizations_licensing_coterm_licenses_info.py b/ansible_collections/cisco/meraki/plugins/action/organizations_licensing_coterm_licenses_info.py new file mode 100644 index 000000000..30f09b26d --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/organizations_licensing_coterm_licenses_info.py @@ -0,0 +1,116 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + organizationId=dict(type="str"), + perPage=dict(type="int"), + total_pages=dict(type="int"), + direction=dict(type="str"), + startingAfter=dict(type="str"), + endingBefore=dict(type="str"), + invalidated=dict(type="bool"), + expired=dict(type="bool"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_all(self, params): + new_object = {} + if params.get("organizationId") is not None: + new_object["organizationId"] = params.get( + "organizationId") + if params.get("perPage") is not None: + new_object["perPage"] = params.get( + "perPage") + new_object['total_pages'] = params.get( + "total_pages") or 1 + new_object['direction'] = params.get( + "direction") or "next" + if params.get("startingAfter") is not None: + new_object["startingAfter"] = params.get( + "startingAfter") + if params.get("endingBefore") is not None: + new_object["endingBefore"] = params.get( + "endingBefore") + if params.get("invalidated") is not None: + new_object["invalidated"] = params.get( + "invalidated") + if params.get("expired") is not None: + new_object["expired"] = params.get( + "expired") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="licensing", + function='getOrganizationLicensingCotermLicenses', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/organizations_licensing_coterm_licenses_move.py b/ansible_collections/cisco/meraki/plugins/action/organizations_licensing_coterm_licenses_move.py new file mode 100644 index 000000000..2679b0abc --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/organizations_licensing_coterm_licenses_move.py @@ -0,0 +1,91 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguements specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + destination=dict(type="dict"), + licenses=dict(type="list"), + organizationId=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = False + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_object(self, params): + new_object = dict( + destination=params.get("destination"), + licenses=params.get("licenses"), + organizationId=params.get("organizationId"), + ) + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="licensing", + function='moveOrganizationLicensingCotermLicenses', + op_modifies=True, + params=self.get_object(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/organizations_login_security.py b/ansible_collections/cisco/meraki/plugins/action/organizations_login_security.py new file mode 100644 index 000000000..64f5ea7b4 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/organizations_login_security.py @@ -0,0 +1,264 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or +# https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, + meraki_compare_equality, + get_dict_result, +) +from ansible_collections.cisco.meraki.plugins.plugin_utils.exceptions import ( + InconsistentParameters, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + state=dict(type="str", default="present", choices=["present"]), + enforcePasswordExpiration=dict(type="bool"), + passwordExpirationDays=dict(type="int"), + enforceDifferentPasswords=dict(type="bool"), + numDifferentPasswords=dict(type="int"), + enforceStrongPasswords=dict(type="bool"), + enforceAccountLockout=dict(type="bool"), + accountLockoutAttempts=dict(type="int"), + enforceIdleTimeout=dict(type="bool"), + idleTimeoutMinutes=dict(type="int"), + enforceTwoFactorAuth=dict(type="bool"), + enforceLoginIpRanges=dict(type="bool"), + loginIpRanges=dict(type="list"), + apiAuthentication=dict(type="dict"), + organizationId=dict(type="str"), +)) + +required_if = [ + ("state", "present", ["organizationId"], True), +] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class OrganizationsLoginSecurity(object): + def __init__(self, params, meraki): + self.meraki = meraki + self.new_object = dict( + enforcePasswordExpiration=params.get("enforcePasswordExpiration"), + passwordExpirationDays=params.get("passwordExpirationDays"), + enforceDifferentPasswords=params.get("enforceDifferentPasswords"), + numDifferentPasswords=params.get("numDifferentPasswords"), + enforceStrongPasswords=params.get("enforceStrongPasswords"), + enforceAccountLockout=params.get("enforceAccountLockout"), + accountLockoutAttempts=params.get("accountLockoutAttempts"), + enforceIdleTimeout=params.get("enforceIdleTimeout"), + idleTimeoutMinutes=params.get("idleTimeoutMinutes"), + enforceTwoFactorAuth=params.get("enforceTwoFactorAuth"), + enforceLoginIpRanges=params.get("enforceLoginIpRanges"), + loginIpRanges=params.get("loginIpRanges"), + apiAuthentication=params.get("apiAuthentication"), + organization_id=params.get("organizationId"), + ) + + def get_all_params(self, name=None, id=None): + new_object_params = {} + if self.new_object.get('organizationId') is not None or self.new_object.get('organization_id') is not None: + new_object_params['organizationId'] = self.new_object.get('organizationId') or \ + self.new_object.get('organization_id') + return new_object_params + + def update_all_params(self): + new_object_params = {} + if self.new_object.get('enforcePasswordExpiration') is not None or self.new_object.get('enforce_password_expiration') is not None: + new_object_params['enforcePasswordExpiration'] = self.new_object.get('enforcePasswordExpiration') + if self.new_object.get('passwordExpirationDays') is not None or self.new_object.get('password_expiration_days') is not None: + new_object_params['passwordExpirationDays'] = self.new_object.get('passwordExpirationDays') or \ + self.new_object.get('password_expiration_days') + if self.new_object.get('enforceDifferentPasswords') is not None or self.new_object.get('enforce_different_passwords') is not None: + new_object_params['enforceDifferentPasswords'] = self.new_object.get('enforceDifferentPasswords') + if self.new_object.get('numDifferentPasswords') is not None or self.new_object.get('num_different_passwords') is not None: + new_object_params['numDifferentPasswords'] = self.new_object.get('numDifferentPasswords') or \ + self.new_object.get('num_different_passwords') + if self.new_object.get('enforceStrongPasswords') is not None or self.new_object.get('enforce_strong_passwords') is not None: + new_object_params['enforceStrongPasswords'] = self.new_object.get('enforceStrongPasswords') + if self.new_object.get('enforceAccountLockout') is not None or self.new_object.get('enforce_account_lockout') is not None: + new_object_params['enforceAccountLockout'] = self.new_object.get('enforceAccountLockout') + if self.new_object.get('accountLockoutAttempts') is not None or self.new_object.get('account_lockout_attempts') is not None: + new_object_params['accountLockoutAttempts'] = self.new_object.get('accountLockoutAttempts') or \ + self.new_object.get('account_lockout_attempts') + if self.new_object.get('enforceIdleTimeout') is not None or self.new_object.get('enforce_idle_timeout') is not None: + new_object_params['enforceIdleTimeout'] = self.new_object.get('enforceIdleTimeout') + if self.new_object.get('idleTimeoutMinutes') is not None or self.new_object.get('idle_timeout_minutes') is not None: + new_object_params['idleTimeoutMinutes'] = self.new_object.get('idleTimeoutMinutes') or \ + self.new_object.get('idle_timeout_minutes') + if self.new_object.get('enforceTwoFactorAuth') is not None or self.new_object.get('enforce_two_factor_auth') is not None: + new_object_params['enforceTwoFactorAuth'] = self.new_object.get('enforceTwoFactorAuth') + if self.new_object.get('enforceLoginIpRanges') is not None or self.new_object.get('enforce_login_ip_ranges') is not None: + new_object_params['enforceLoginIpRanges'] = self.new_object.get('enforceLoginIpRanges') + if self.new_object.get('loginIpRanges') is not None or self.new_object.get('login_ip_ranges') is not None: + new_object_params['loginIpRanges'] = self.new_object.get('loginIpRanges') or \ + self.new_object.get('login_ip_ranges') + if self.new_object.get('apiAuthentication') is not None or self.new_object.get('api_authentication') is not None: + new_object_params['apiAuthentication'] = self.new_object.get('apiAuthentication') or \ + self.new_object.get('api_authentication') + if self.new_object.get('organizationId') is not None or self.new_object.get('organization_id') is not None: + new_object_params['organizationId'] = self.new_object.get('organizationId') or \ + self.new_object.get('organization_id') + return new_object_params + + def get_object_by_name(self, name): + result = None + # NOTE: Does not have a get by name method, using get all + try: + items = self.meraki.exec_meraki( + family="organizations", + function="getOrganizationLoginSecurity", + params=self.get_all_params(name=name), + ) + if isinstance(items, dict): + if 'response' in items: + items = items.get('response') + result = get_dict_result(items, 'name', name) + if result is None: + result = items + except Exception as e: + print("Error: ", e) + result = None + return result + + def get_object_by_id(self, id): + result = None + # NOTE: Does not have a get by id method or it is in another action + return result + + def exists(self): + prev_obj = None + id_exists = False + name_exists = False + o_id = self.new_object.get("id") + name = self.new_object.get("organization_id") + if o_id: + prev_obj = self.get_object_by_name(o_id) + id_exists = prev_obj is not None and isinstance(prev_obj, dict) + if not id_exists and name: + prev_obj = self.get_object_by_name(name) + name_exists = prev_obj is not None and isinstance(prev_obj, dict) + if name_exists: + _id = prev_obj.get("id") + if id_exists and name_exists and o_id != _id: + raise InconsistentParameters( + "The 'id' and 'name' params don't refer to the same object") + if _id: + self.new_object.update(dict(id=_id)) + it_exists = prev_obj is not None and isinstance(prev_obj, dict) + return (it_exists, prev_obj) + + def requires_update(self, current_obj): + requested_obj = self.new_object + + obj_params = [ + ("enforcePasswordExpiration", "enforcePasswordExpiration"), + ("enforceDifferentPasswords", "enforceDifferentPasswords"), + ("numDifferentPasswords", "numDifferentPasswords"), + ("enforceStrongPasswords", "enforceStrongPasswords"), + ("enforceAccountLockout", "enforceAccountLockout"), + ("accountLockoutAttempts", "accountLockoutAttempts"), + ("enforceIdleTimeout", "enforceIdleTimeout"), + ("idleTimeoutMinutes", "idleTimeoutMinutes"), + ("enforceTwoFactorAuth", "enforceTwoFactorAuth"), + ("enforceLoginIpRanges", "enforceLoginIpRanges"), + ("loginIpRanges", "loginIpRanges"), + ("apiAuthentication", "apiAuthentication"), + ("organizationId", "organizationId"), + ] + # Method 1. Params present in request (Ansible) obj are the same as the current (ISE) params + # If any does not have eq params, it requires update + return any(not meraki_compare_equality(current_obj.get(meraki_param), + requested_obj.get(ansible_param)) + for (meraki_param, ansible_param) in obj_params) + + def update(self): + id = self.new_object.get("id") + name = self.new_object.get("name") + result = None + result = self.meraki.exec_meraki( + family="organizations", + function="updateOrganizationLoginSecurity", + params=self.update_all_params(), + op_modifies=True, + ) + return result + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = False + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + meraki = MERAKI(self._task.args) + obj = OrganizationsLoginSecurity(self._task.args, meraki) + + state = self._task.args.get("state") + + response = None + if state == "present": + (obj_exists, prev_obj) = obj.exists() + if obj_exists: + if obj.requires_update(prev_obj): + response = obj.update() + meraki.object_updated() + else: + response = prev_obj + meraki.object_already_present() + else: + meraki.fail_json( + "Object does not exists, plugin only has update") + + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/organizations_login_security_info.py b/ansible_collections/cisco/meraki/plugins/action/organizations_login_security_info.py new file mode 100644 index 000000000..cea9151ab --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/organizations_login_security_info.py @@ -0,0 +1,90 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + organizationId=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_all(self, params): + new_object = {} + if params.get("organizationId") is not None: + new_object["organizationId"] = params.get( + "organizationId") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="organizations", + function='getOrganizationLoginSecurity', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/organizations_networks_combine.py b/ansible_collections/cisco/meraki/plugins/action/organizations_networks_combine.py new file mode 100644 index 000000000..c6d337d78 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/organizations_networks_combine.py @@ -0,0 +1,93 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguements specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + name=dict(type="str"), + networkIds=dict(type="list"), + enrollmentString=dict(type="str"), + organizationId=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = False + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_object(self, params): + new_object = dict( + name=params.get("name"), + networkIds=params.get("networkIds"), + enrollmentString=params.get("enrollmentString"), + organizationId=params.get("organizationId"), + ) + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="organizations", + function='combineOrganizationNetworks', + op_modifies=True, + params=self.get_object(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/organizations_openapi_spec_info.py b/ansible_collections/cisco/meraki/plugins/action/organizations_openapi_spec_info.py new file mode 100644 index 000000000..6ad1215dc --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/organizations_openapi_spec_info.py @@ -0,0 +1,90 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + organizationId=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_all(self, params): + new_object = {} + if params.get("organizationId") is not None: + new_object["organizationId"] = params.get( + "organizationId") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="organizations", + function='getOrganizationOpenapiSpec', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/organizations_policy_objects.py b/ansible_collections/cisco/meraki/plugins/action/organizations_policy_objects.py new file mode 100644 index 000000000..6e49366b2 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/organizations_policy_objects.py @@ -0,0 +1,369 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or +# https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, + meraki_compare_equality, + get_dict_result, +) +from ansible_collections.cisco.meraki.plugins.plugin_utils.exceptions import ( + InconsistentParameters, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + state=dict(type="str", default="present", choices=["present", "absent"]), + name=dict(type="str"), + category=dict(type="str"), + type=dict(type="str"), + cidr=dict(type="str"), + fqdn=dict(type="str"), + mask=dict(type="str"), + ip=dict(type="str"), + groupIds=dict(type="list"), + organizationId=dict(type="str"), + policyObjectId=dict(type="str"), +)) + +required_if = [ + ("state", "present", ["name", "organizationId", "policyObjectId"], True), + ("state", "absent", ["name", "organizationId", "policyObjectId"], True), +] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class OrganizationsPolicyObjects(object): + def __init__(self, params, meraki): + self.meraki = meraki + self.new_object = dict( + name=params.get("name"), + category=params.get("category"), + type=params.get("type"), + cidr=params.get("cidr"), + fqdn=params.get("fqdn"), + mask=params.get("mask"), + ip=params.get("ip"), + groupIds=params.get("groupIds"), + organizationId=params.get("organizationId"), + policyObjectId=params.get("policyObjectId"), + ) + + def get_all_params(self, name=None, id=None): + new_object_params = {} + if self.new_object.get('perPage') is not None or self.new_object.get('per_page') is not None: + new_object_params['perPage'] = self.new_object.get('perPage') or \ + self.new_object.get('per_page') + new_object_params['total_pages'] = -1 + if self.new_object.get('startingAfter') is not None or self.new_object.get('starting_after') is not None: + new_object_params['startingAfter'] = self.new_object.get('startingAfter') or \ + self.new_object.get('starting_after') + if self.new_object.get('endingBefore') is not None or self.new_object.get('ending_before') is not None: + new_object_params['endingBefore'] = self.new_object.get('endingBefore') or \ + self.new_object.get('ending_before') + if self.new_object.get('organizationId') is not None or self.new_object.get('organization_id') is not None: + new_object_params['organizationId'] = self.new_object.get('organizationId') or \ + self.new_object.get('organization_id') + return new_object_params + + def get_params_by_id(self, name=None, id=None): + new_object_params = {} + if self.new_object.get('organizationId') is not None or self.new_object.get('organization_id') is not None: + new_object_params['organizationId'] = self.new_object.get('organizationId') or \ + self.new_object.get('organization_id') + if self.new_object.get('policyObjectId') is not None or self.new_object.get('policy_object_id') is not None: + new_object_params['policyObjectId'] = self.new_object.get('policyObjectId') or \ + self.new_object.get('policy_object_id') + return new_object_params + + def create_params(self): + new_object_params = {} + if self.new_object.get('name') is not None or self.new_object.get('name') is not None: + new_object_params['name'] = self.new_object.get('name') or \ + self.new_object.get('name') + if self.new_object.get('category') is not None or self.new_object.get('category') is not None: + new_object_params['category'] = self.new_object.get('category') or \ + self.new_object.get('category') + if self.new_object.get('type') is not None or self.new_object.get('type') is not None: + new_object_params['type'] = self.new_object.get('type') or \ + self.new_object.get('type') + if self.new_object.get('cidr') is not None or self.new_object.get('cidr') is not None: + new_object_params['cidr'] = self.new_object.get('cidr') or \ + self.new_object.get('cidr') + if self.new_object.get('fqdn') is not None or self.new_object.get('fqdn') is not None: + new_object_params['fqdn'] = self.new_object.get('fqdn') or \ + self.new_object.get('fqdn') + if self.new_object.get('mask') is not None or self.new_object.get('mask') is not None: + new_object_params['mask'] = self.new_object.get('mask') or \ + self.new_object.get('mask') + if self.new_object.get('ip') is not None or self.new_object.get('ip') is not None: + new_object_params['ip'] = self.new_object.get('ip') or \ + self.new_object.get('ip') + if self.new_object.get('groupIds') is not None or self.new_object.get('group_ids') is not None: + new_object_params['groupIds'] = self.new_object.get('groupIds') or \ + self.new_object.get('group_ids') + if self.new_object.get('organizationId') is not None or self.new_object.get('organization_id') is not None: + new_object_params['organizationId'] = self.new_object.get('organizationId') or \ + self.new_object.get('organization_id') + return new_object_params + + def delete_by_id_params(self): + new_object_params = {} + if self.new_object.get('organizationId') is not None or self.new_object.get('organization_id') is not None: + new_object_params['organizationId'] = self.new_object.get('organizationId') or \ + self.new_object.get('organization_id') + if self.new_object.get('policyObjectId') is not None or self.new_object.get('policy_object_id') is not None: + new_object_params['policyObjectId'] = self.new_object.get('policyObjectId') or \ + self.new_object.get('policy_object_id') + return new_object_params + + def update_by_id_params(self): + new_object_params = {} + if self.new_object.get('name') is not None or self.new_object.get('name') is not None: + new_object_params['name'] = self.new_object.get('name') or \ + self.new_object.get('name') + if self.new_object.get('cidr') is not None or self.new_object.get('cidr') is not None: + new_object_params['cidr'] = self.new_object.get('cidr') or \ + self.new_object.get('cidr') + if self.new_object.get('fqdn') is not None or self.new_object.get('fqdn') is not None: + new_object_params['fqdn'] = self.new_object.get('fqdn') or \ + self.new_object.get('fqdn') + if self.new_object.get('mask') is not None or self.new_object.get('mask') is not None: + new_object_params['mask'] = self.new_object.get('mask') or \ + self.new_object.get('mask') + if self.new_object.get('ip') is not None or self.new_object.get('ip') is not None: + new_object_params['ip'] = self.new_object.get('ip') or \ + self.new_object.get('ip') + if self.new_object.get('groupIds') is not None or self.new_object.get('group_ids') is not None: + new_object_params['groupIds'] = self.new_object.get('groupIds') or \ + self.new_object.get('group_ids') + if self.new_object.get('organizationId') is not None or self.new_object.get('organization_id') is not None: + new_object_params['organizationId'] = self.new_object.get('organizationId') or \ + self.new_object.get('organization_id') + if self.new_object.get('policyObjectId') is not None or self.new_object.get('policy_object_id') is not None: + new_object_params['policyObjectId'] = self.new_object.get('policyObjectId') or \ + self.new_object.get('policy_object_id') + return new_object_params + + def get_object_by_name(self, name): + result = None + # NOTE: Does not have a get by name method or it is in another action + try: + items = self.meraki.exec_meraki( + family="organizations", + function="getOrganizationPolicyObjects", + params=self.get_all_params(name=name), + ) + if isinstance(items, dict): + if 'response' in items: + items = items.get('response') + result = get_dict_result(items, 'name', name) + if result is None: + result = items + except Exception as e: + print("Error: ", e) + result = None + return result + + def get_object_by_id(self, id): + result = None + try: + items = self.meraki.exec_meraki( + family="organizations", + function="getOrganizationPolicyObject", + params=self.get_params_by_id() + ) + if isinstance(items, dict): + if 'response' in items: + items = items.get('response') + result = get_dict_result(items, 'policyObjectId', id) + except Exception as e: + print("Error: ", e) + result = None + return result + + def exists(self): + id_exists = False + name_exists = False + prev_obj = None + o_id = self.new_object.get("id") + o_id = o_id or self.new_object.get( + "policy_object_id") or self.new_object.get("policyObjectId") + name = self.new_object.get("name") + if o_id: + prev_obj = self.get_object_by_id(o_id) + id_exists = prev_obj is not None and isinstance(prev_obj, dict) + if not id_exists and name: + prev_obj = self.get_object_by_name(name) + name_exists = prev_obj is not None and isinstance(prev_obj, dict) + if name_exists: + _id = prev_obj.get("id") + _id = _id or prev_obj.get("policyObjectId") + if id_exists and name_exists and o_id != _id: + raise InconsistentParameters( + "The 'id' and 'name' params don't refer to the same object") + if _id: + self.new_object.update(dict(id=_id)) + self.new_object.update(dict(policyObjectId=_id)) + if _id: + prev_obj = self.get_object_by_id(_id) + it_exists = prev_obj is not None and isinstance(prev_obj, dict) + return (it_exists, prev_obj) + + def requires_update(self, current_obj): + requested_obj = self.new_object + + obj_params = [ + ("name", "name"), + ("category", "category"), + ("type", "type"), + ("cidr", "cidr"), + ("fqdn", "fqdn"), + ("mask", "mask"), + ("ip", "ip"), + ("groupIds", "groupIds"), + ("organizationId", "organizationId"), + ("policyObjectId", "policyObjectId"), + ] + # Method 1. Params present in request (Ansible) obj are the same as the current (DNAC) params + # If any does not have eq params, it requires update + return any(not meraki_compare_equality(current_obj.get(meraki_param), + requested_obj.get(ansible_param)) + for (meraki_param, ansible_param) in obj_params) + + def create(self): + result = self.meraki.exec_meraki( + family="organizations", + function="createOrganizationPolicyObject", + params=self.create_params(), + op_modifies=True, + ) + return result + + def update(self): + id = self.new_object.get("id") + id = id or self.new_object.get("policyObjectId") + name = self.new_object.get("name") + result = None + if not id: + prev_obj_name = self.get_object_by_name(name) + id_ = None + if prev_obj_name: + id_ = prev_obj_name.get("id") + id_ = id_ or prev_obj_name.get("policyObjectId") + if id_: + self.new_object.update(dict(policyObjectId=id_)) + result = self.meraki.exec_meraki( + family="organizations", + function="updateOrganizationPolicyObject", + params=self.update_by_id_params(), + op_modifies=True, + ) + return result + + def delete(self): + id = self.new_object.get("id") + id = id or self.new_object.get("policyObjectId") + name = self.new_object.get("name") + result = None + if not id: + prev_obj_name = self.get_object_by_name(name) + id_ = None + if prev_obj_name: + id_ = prev_obj_name.get("id") + id_ = id_ or prev_obj_name.get("policyObjectId") + if id_: + self.new_object.update(dict(policyObjectId=id_)) + result = self.meraki.exec_meraki( + family="organizations", + function="deleteOrganizationPolicyObject", + params=self.delete_by_id_params(), + ) + return result + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = False + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + meraki = MERAKI(self._task.args) + obj = OrganizationsPolicyObjects(self._task.args, meraki) + + state = self._task.args.get("state") + + response = None + + if state == "present": + (obj_exists, prev_obj) = obj.exists() + if obj_exists: + if obj.requires_update(prev_obj): + response = obj.update() + meraki.object_updated() + else: + response = prev_obj + meraki.object_already_present() + else: + response = obj.create() + meraki.object_created() + + elif state == "absent": + (obj_exists, prev_obj) = obj.exists() + if obj_exists: + response = obj.delete() + meraki.object_deleted() + else: + meraki.object_already_absent() + + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/organizations_policy_objects_groups.py b/ansible_collections/cisco/meraki/plugins/action/organizations_policy_objects_groups.py new file mode 100644 index 000000000..ff6b3f852 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/organizations_policy_objects_groups.py @@ -0,0 +1,327 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or +# https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, + meraki_compare_equality, + get_dict_result, +) +from ansible_collections.cisco.meraki.plugins.plugin_utils.exceptions import ( + InconsistentParameters, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + state=dict(type="str", default="present", choices=["present", "absent"]), + name=dict(type="str"), + category=dict(type="str"), + objectIds=dict(type="list"), + organizationId=dict(type="str"), + policyObjectGroupId=dict(type="str"), +)) + +required_if = [ + ("state", "present", ["name", "organizationId", "policyObjectGroupId"], True), + ("state", "absent", ["name", "organizationId", "policyObjectGroupId"], True), +] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class OrganizationsPolicyObjectsGroups(object): + def __init__(self, params, meraki): + self.meraki = meraki + self.new_object = dict( + name=params.get("name"), + category=params.get("category"), + objectIds=params.get("objectIds"), + organizationId=params.get("organizationId"), + policyObjectGroupId=params.get("policyObjectGroupId"), + ) + + def get_all_params(self, name=None, id=None): + new_object_params = {} + if self.new_object.get('perPage') is not None or self.new_object.get('per_page') is not None: + new_object_params['perPage'] = self.new_object.get('perPage') or \ + self.new_object.get('per_page') + new_object_params['total_pages'] = -1 + if self.new_object.get('startingAfter') is not None or self.new_object.get('starting_after') is not None: + new_object_params['startingAfter'] = self.new_object.get('startingAfter') or \ + self.new_object.get('starting_after') + if self.new_object.get('endingBefore') is not None or self.new_object.get('ending_before') is not None: + new_object_params['endingBefore'] = self.new_object.get('endingBefore') or \ + self.new_object.get('ending_before') + if self.new_object.get('organizationId') is not None or self.new_object.get('organization_id') is not None: + new_object_params['organizationId'] = self.new_object.get('organizationId') or \ + self.new_object.get('organization_id') + return new_object_params + + def get_params_by_id(self, name=None, id=None): + new_object_params = {} + if self.new_object.get('organizationId') is not None or self.new_object.get('organization_id') is not None: + new_object_params['organizationId'] = self.new_object.get('organizationId') or \ + self.new_object.get('organization_id') + if self.new_object.get('policyObjectGroupId') is not None or self.new_object.get('policy_object_group_id') is not None: + new_object_params['policyObjectGroupId'] = self.new_object.get('policyObjectGroupId') or \ + self.new_object.get('policy_object_group_id') + return new_object_params + + def create_params(self): + new_object_params = {} + if self.new_object.get('name') is not None or self.new_object.get('name') is not None: + new_object_params['name'] = self.new_object.get('name') or \ + self.new_object.get('name') + if self.new_object.get('category') is not None or self.new_object.get('category') is not None: + new_object_params['category'] = self.new_object.get('category') or \ + self.new_object.get('category') + if self.new_object.get('objectIds') is not None or self.new_object.get('object_ids') is not None: + new_object_params['objectIds'] = self.new_object.get('objectIds') or \ + self.new_object.get('object_ids') + if self.new_object.get('organizationId') is not None or self.new_object.get('organization_id') is not None: + new_object_params['organizationId'] = self.new_object.get('organizationId') or \ + self.new_object.get('organization_id') + return new_object_params + + def delete_by_id_params(self): + new_object_params = {} + if self.new_object.get('organizationId') is not None or self.new_object.get('organization_id') is not None: + new_object_params['organizationId'] = self.new_object.get('organizationId') or \ + self.new_object.get('organization_id') + if self.new_object.get('policyObjectGroupId') is not None or self.new_object.get('policy_object_group_id') is not None: + new_object_params['policyObjectGroupId'] = self.new_object.get('policyObjectGroupId') or \ + self.new_object.get('policy_object_group_id') + return new_object_params + + def update_by_id_params(self): + new_object_params = {} + if self.new_object.get('name') is not None or self.new_object.get('name') is not None: + new_object_params['name'] = self.new_object.get('name') or \ + self.new_object.get('name') + if self.new_object.get('objectIds') is not None or self.new_object.get('object_ids') is not None: + new_object_params['objectIds'] = self.new_object.get('objectIds') or \ + self.new_object.get('object_ids') + if self.new_object.get('organizationId') is not None or self.new_object.get('organization_id') is not None: + new_object_params['organizationId'] = self.new_object.get('organizationId') or \ + self.new_object.get('organization_id') + if self.new_object.get('policyObjectGroupId') is not None or self.new_object.get('policy_object_group_id') is not None: + new_object_params['policyObjectGroupId'] = self.new_object.get('policyObjectGroupId') or \ + self.new_object.get('policy_object_group_id') + return new_object_params + + def get_object_by_name(self, name): + result = None + # NOTE: Does not have a get by name method or it is in another action + try: + items = self.meraki.exec_meraki( + family="organizations", + function="getOrganizationPolicyObjectsGroups", + params=self.get_all_params(name=name), + ) + if isinstance(items, dict): + if 'response' in items: + items = items.get('response') + result = get_dict_result(items, 'name', name) + if result is None: + result = items + except Exception as e: + print("Error: ", e) + result = None + return result + + def get_object_by_id(self, id): + result = None + try: + items = self.meraki.exec_meraki( + family="organizations", + function="getOrganizationPolicyObjectsGroup", + params=self.get_params_by_id() + ) + if isinstance(items, dict): + if 'response' in items: + items = items.get('response') + result = get_dict_result(items, 'policyObjectGroupId', id) + except Exception as e: + print("Error: ", e) + result = None + return result + + def exists(self): + id_exists = False + name_exists = False + prev_obj = None + o_id = self.new_object.get("id") + o_id = o_id or self.new_object.get( + "policy_object_group_id") or self.new_object.get("policyObjectGroupId") + name = self.new_object.get("name") + if o_id: + prev_obj = self.get_object_by_id(o_id) + id_exists = prev_obj is not None and isinstance(prev_obj, dict) + if not id_exists and name: + prev_obj = self.get_object_by_name(name) + name_exists = prev_obj is not None and isinstance(prev_obj, dict) + if name_exists: + _id = prev_obj.get("id") + _id = _id or prev_obj.get("policyObjectGroupId") + if id_exists and name_exists and o_id != _id: + raise InconsistentParameters( + "The 'id' and 'name' params don't refer to the same object") + if _id: + self.new_object.update(dict(id=_id)) + self.new_object.update(dict(policyObjectGroupId=_id)) + if _id: + prev_obj = self.get_object_by_id(_id) + it_exists = prev_obj is not None and isinstance(prev_obj, dict) + return (it_exists, prev_obj) + + def requires_update(self, current_obj): + requested_obj = self.new_object + + obj_params = [ + ("name", "name"), + ("category", "category"), + ("objectIds", "objectIds"), + ("organizationId", "organizationId"), + ("policyObjectGroupId", "policyObjectGroupId"), + ] + # Method 1. Params present in request (Ansible) obj are the same as the current (DNAC) params + # If any does not have eq params, it requires update + return any(not meraki_compare_equality(current_obj.get(meraki_param), + requested_obj.get(ansible_param)) + for (meraki_param, ansible_param) in obj_params) + + def create(self): + result = self.meraki.exec_meraki( + family="organizations", + function="createOrganizationPolicyObjectsGroup", + params=self.create_params(), + op_modifies=True, + ) + return result + + def update(self): + id = self.new_object.get("id") + id = id or self.new_object.get("policyObjectGroupId") + name = self.new_object.get("name") + result = None + if not id: + prev_obj_name = self.get_object_by_name(name) + id_ = None + if prev_obj_name: + id_ = prev_obj_name.get("id") + id_ = id_ or prev_obj_name.get("policyObjectGroupId") + if id_: + self.new_object.update(dict(policyObjectGroupId=id_)) + result = self.meraki.exec_meraki( + family="organizations", + function="updateOrganizationPolicyObjectsGroup", + params=self.update_by_id_params(), + op_modifies=True, + ) + return result + + def delete(self): + id = self.new_object.get("id") + id = id or self.new_object.get("policyObjectGroupId") + name = self.new_object.get("name") + result = None + if not id: + prev_obj_name = self.get_object_by_name(name) + id_ = None + if prev_obj_name: + id_ = prev_obj_name.get("id") + id_ = id_ or prev_obj_name.get("policyObjectGroupId") + if id_: + self.new_object.update(dict(policyObjectGroupId=id_)) + result = self.meraki.exec_meraki( + family="organizations", + function="deleteOrganizationPolicyObjectsGroup", + params=self.delete_by_id_params(), + ) + return result + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = False + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + meraki = MERAKI(self._task.args) + obj = OrganizationsPolicyObjectsGroups(self._task.args, meraki) + + state = self._task.args.get("state") + + response = None + + if state == "present": + (obj_exists, prev_obj) = obj.exists() + if obj_exists: + if obj.requires_update(prev_obj): + response = obj.update() + meraki.object_updated() + else: + response = prev_obj + meraki.object_already_present() + else: + response = obj.create() + meraki.object_created() + + elif state == "absent": + (obj_exists, prev_obj) = obj.exists() + if obj_exists: + response = obj.delete() + meraki.object_deleted() + else: + meraki.object_already_absent() + + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/organizations_policy_objects_groups_info.py b/ansible_collections/cisco/meraki/plugins/action/organizations_policy_objects_groups_info.py new file mode 100644 index 000000000..8eb2eb2c7 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/organizations_policy_objects_groups_info.py @@ -0,0 +1,130 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + organizationId=dict(type="str"), + perPage=dict(type="int"), + total_pages=dict(type="int"), + direction=dict(type="str"), + startingAfter=dict(type="str"), + endingBefore=dict(type="str"), + policyObjectGroupId=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_object(self, params): + new_object = {} + if params.get("organizationId") is not None: + new_object["organizationId"] = params.get( + "organizationId") + if params.get("policyObjectGroupId") is not None: + new_object["policyObjectGroupId"] = params.get( + "policyObjectGroupId") + return new_object + + def get_all(self, params): + new_object = {} + if params.get("organizationId") is not None: + new_object["organizationId"] = params.get( + "organizationId") + if params.get("perPage") is not None: + new_object["perPage"] = params.get( + "perPage") + new_object['total_pages'] = params.get( + "total_pages") or 1 + new_object['direction'] = params.get( + "direction") or "next" + if params.get("startingAfter") is not None: + new_object["startingAfter"] = params.get( + "startingAfter") + if params.get("endingBefore") is not None: + new_object["endingBefore"] = params.get( + "endingBefore") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + id = self._task.args.get("policyObjectGroupId") + if id: + response = meraki.exec_meraki( + family="organizations", + function='getOrganizationPolicyObjectsGroup', + params=self.get_object(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result + if not id: + response = meraki.exec_meraki( + family="organizations", + function='getOrganizationPolicyObjectsGroups', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/organizations_policy_objects_info.py b/ansible_collections/cisco/meraki/plugins/action/organizations_policy_objects_info.py new file mode 100644 index 000000000..c94a1e7f2 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/organizations_policy_objects_info.py @@ -0,0 +1,130 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + organizationId=dict(type="str"), + perPage=dict(type="int"), + total_pages=dict(type="int"), + direction=dict(type="str"), + startingAfter=dict(type="str"), + endingBefore=dict(type="str"), + policyObjectId=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_object(self, params): + new_object = {} + if params.get("organizationId") is not None: + new_object["organizationId"] = params.get( + "organizationId") + if params.get("policyObjectId") is not None: + new_object["policyObjectId"] = params.get( + "policyObjectId") + return new_object + + def get_all(self, params): + new_object = {} + if params.get("organizationId") is not None: + new_object["organizationId"] = params.get( + "organizationId") + if params.get("perPage") is not None: + new_object["perPage"] = params.get( + "perPage") + new_object['total_pages'] = params.get( + "total_pages") or 1 + new_object['direction'] = params.get( + "direction") or "next" + if params.get("startingAfter") is not None: + new_object["startingAfter"] = params.get( + "startingAfter") + if params.get("endingBefore") is not None: + new_object["endingBefore"] = params.get( + "endingBefore") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + id = self._task.args.get("policyObjectId") + if id: + response = meraki.exec_meraki( + family="organizations", + function='getOrganizationPolicyObject', + params=self.get_object(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result + if not id: + response = meraki.exec_meraki( + family="organizations", + function='getOrganizationPolicyObjects', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/organizations_saml.py b/ansible_collections/cisco/meraki/plugins/action/organizations_saml.py new file mode 100644 index 000000000..219242d26 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/organizations_saml.py @@ -0,0 +1,199 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or +# https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, + meraki_compare_equality, + get_dict_result, +) +from ansible_collections.cisco.meraki.plugins.plugin_utils.exceptions import ( + InconsistentParameters, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + state=dict(type="str", default="present", choices=["present"]), + enabled=dict(type="bool"), + organizationId=dict(type="str"), +)) + +required_if = [ + ("state", "present", ["organizationId"], True), +] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class OrganizationsSaml(object): + def __init__(self, params, meraki): + self.meraki = meraki + self.new_object = dict( + enabled=params.get("enabled"), + organization_id=params.get("organizationId"), + ) + + def get_all_params(self, name=None, id=None): + new_object_params = {} + if self.new_object.get('organizationId') is not None or self.new_object.get('organization_id') is not None: + new_object_params['organizationId'] = self.new_object.get('organizationId') or \ + self.new_object.get('organization_id') + return new_object_params + + def update_all_params(self): + new_object_params = {} + if self.new_object.get('enabled') is not None or self.new_object.get('enabled') is not None: + new_object_params['enabled'] = self.new_object.get('enabled') + if self.new_object.get('organizationId') is not None or self.new_object.get('organization_id') is not None: + new_object_params['organizationId'] = self.new_object.get('organizationId') or \ + self.new_object.get('organization_id') + return new_object_params + + def get_object_by_name(self, name): + result = None + # NOTE: Does not have a get by name method, using get all + try: + items = self.meraki.exec_meraki( + family="organizations", + function="getOrganizationSaml", + params=self.get_all_params(name=name), + ) + if isinstance(items, dict): + if 'enabled' in items: + items = items.get('enabled') + result = get_dict_result(items, 'name', name) + if result is None: + result = items + except Exception as e: + print("Error: ", e) + result = None + return result + + def get_object_by_id(self, id): + result = None + # NOTE: Does not have a get by id method or it is in another action + return result + + def exists(self): + prev_obj = None + id_exists = False + name_exists = False + o_id = self.new_object.get("id") + name = self.new_object.get("name") + if o_id: + prev_obj = self.get_object_by_name(o_id) + id_exists = prev_obj is not None and isinstance(prev_obj, dict) + if not id_exists and name: + prev_obj = self.get_object_by_name(name) + name_exists = prev_obj is not None and isinstance(prev_obj, dict) + if name_exists: + _id = prev_obj.get("id") + if id_exists and name_exists and o_id != _id: + raise InconsistentParameters( + "The 'id' and 'name' params don't refer to the same object") + if _id: + self.new_object.update(dict(id=_id)) + it_exists = prev_obj is not None and isinstance(prev_obj, dict) + return (it_exists, prev_obj) + + def requires_update(self, current_obj): + requested_obj = self.new_object + + obj_params = [ + ("enabled", "enabled"), + ("organizationId", "organizationId"), + ] + # Method 1. Params present in request (Ansible) obj are the same as the current (ISE) params + # If any does not have eq params, it requires update + return any(not meraki_compare_equality(current_obj.get(meraki_param), + requested_obj.get(ansible_param)) + for (meraki_param, ansible_param) in obj_params) + + def update(self): + id = self.new_object.get("id") + name = self.new_object.get("name") + result = None + result = self.meraki.exec_meraki( + family="organizations", + function="updateOrganizationSaml", + params=self.update_all_params(), + op_modifies=True, + ) + return result + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = False + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + meraki = MERAKI(self._task.args) + obj = OrganizationsSaml(self._task.args, meraki) + + state = self._task.args.get("state") + + response = None + if state == "present": + (obj_exists, prev_obj) = obj.exists() + if obj_exists: + if obj.requires_update(prev_obj): + response = obj.update() + meraki.object_updated() + else: + response = prev_obj + meraki.object_already_present() + else: + meraki.fail_json( + "Object does not exists, plugin only has update") + + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/organizations_saml_idps.py b/ansible_collections/cisco/meraki/plugins/action/organizations_saml_idps.py new file mode 100644 index 000000000..e557665b9 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/organizations_saml_idps.py @@ -0,0 +1,311 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or +# https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, + meraki_compare_equality, + get_dict_result, +) +from ansible_collections.cisco.meraki.plugins.plugin_utils.exceptions import ( + InconsistentParameters, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + state=dict(type="str", default="present", choices=["present", "absent"]), + x509certSha1Fingerprint=dict(type="str"), + sloLogoutUrl=dict(type="str"), + organizationId=dict(type="str"), + idpId=dict(type="str"), +)) + +required_if = [ + ("state", "present", ["idpId", "organizationId"], True), + ("state", "absent", ["idpId", "organizationId"], True), +] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class OrganizationsSamlIdps(object): + def __init__(self, params, meraki): + self.meraki = meraki + self.new_object = dict( + x509certSha1Fingerprint=params.get("x509certSha1Fingerprint"), + sloLogoutUrl=params.get("sloLogoutUrl"), + organizationId=params.get("organizationId"), + idpId=params.get("idpId"), + ) + + def get_all_params(self, name=None, id=None): + new_object_params = {} + if self.new_object.get('organizationId') is not None or self.new_object.get('organization_id') is not None: + new_object_params['organizationId'] = self.new_object.get('organizationId') or \ + self.new_object.get('organization_id') + return new_object_params + + def get_params_by_id(self, name=None, id=None): + new_object_params = {} + if self.new_object.get('organizationId') is not None or self.new_object.get('organization_id') is not None: + new_object_params['organizationId'] = self.new_object.get('organizationId') or \ + self.new_object.get('organization_id') + if self.new_object.get('idpId') is not None or self.new_object.get('idp_id') is not None: + new_object_params['idpId'] = self.new_object.get('idpId') or \ + self.new_object.get('idp_id') + return new_object_params + + def create_params(self): + new_object_params = {} + if self.new_object.get('x509certSha1Fingerprint') is not None or self.new_object.get('x509cert_sha1_fingerprint') is not None: + new_object_params['x509certSha1Fingerprint'] = self.new_object.get('x509certSha1Fingerprint') or \ + self.new_object.get('x509cert_sha1_fingerprint') + if self.new_object.get('sloLogoutUrl') is not None or self.new_object.get('slo_logout_url') is not None: + new_object_params['sloLogoutUrl'] = self.new_object.get('sloLogoutUrl') or \ + self.new_object.get('slo_logout_url') + if self.new_object.get('organizationId') is not None or self.new_object.get('organization_id') is not None: + new_object_params['organizationId'] = self.new_object.get('organizationId') or \ + self.new_object.get('organization_id') + return new_object_params + + def delete_by_id_params(self): + new_object_params = {} + if self.new_object.get('organizationId') is not None or self.new_object.get('organization_id') is not None: + new_object_params['organizationId'] = self.new_object.get('organizationId') or \ + self.new_object.get('organization_id') + if self.new_object.get('idpId') is not None or self.new_object.get('idp_id') is not None: + new_object_params['idpId'] = self.new_object.get('idpId') or \ + self.new_object.get('idp_id') + return new_object_params + + def update_by_id_params(self): + new_object_params = {} + if self.new_object.get('x509certSha1Fingerprint') is not None or self.new_object.get('x509cert_sha1_fingerprint') is not None: + new_object_params['x509certSha1Fingerprint'] = self.new_object.get('x509certSha1Fingerprint') or \ + self.new_object.get('x509cert_sha1_fingerprint') + if self.new_object.get('sloLogoutUrl') is not None or self.new_object.get('slo_logout_url') is not None: + new_object_params['sloLogoutUrl'] = self.new_object.get('sloLogoutUrl') or \ + self.new_object.get('slo_logout_url') + if self.new_object.get('organizationId') is not None or self.new_object.get('organization_id') is not None: + new_object_params['organizationId'] = self.new_object.get('organizationId') or \ + self.new_object.get('organization_id') + if self.new_object.get('idpId') is not None or self.new_object.get('idp_id') is not None: + new_object_params['idpId'] = self.new_object.get('idpId') or \ + self.new_object.get('idp_id') + return new_object_params + + def get_object_by_name(self, name): + result = None + # NOTE: Does not have a get by name method or it is in another action + try: + items = self.meraki.exec_meraki( + family="organizations", + function="getOrganizationSamlIdps", + params=self.get_all_params(name=name), + ) + if isinstance(items, dict): + if 'response' in items: + items = items.get('response') + result = get_dict_result(items, 'name', name) + if result is None: + result = items + except Exception as e: + print("Error: ", e) + result = None + return result + + def get_object_by_id(self, id): + result = None + try: + items = self.meraki.exec_meraki( + family="organizations", + function="getOrganizationSamlIdp", + params=self.get_params_by_id() + ) + if isinstance(items, dict): + if 'response' in items: + items = items.get('response') + result = get_dict_result(items, 'idpId', id) + except Exception as e: + print("Error: ", e) + result = None + return result + + def exists(self): + id_exists = False + name_exists = False + prev_obj = None + o_id = self.new_object.get("id") + o_id = o_id or self.new_object.get( + "idp_id") or self.new_object.get("idpId") + name = self.new_object.get("name") + if o_id: + prev_obj = self.get_object_by_id(o_id) + id_exists = prev_obj is not None and isinstance(prev_obj, dict) + if not id_exists and name: + prev_obj = self.get_object_by_name(name) + name_exists = prev_obj is not None and isinstance(prev_obj, dict) + if name_exists: + _id = prev_obj.get("id") + _id = _id or prev_obj.get("idpId") + if id_exists and name_exists and o_id != _id: + raise InconsistentParameters( + "The 'id' and 'name' params don't refer to the same object") + if _id: + self.new_object.update(dict(id=_id)) + self.new_object.update(dict(idpId=_id)) + if _id: + prev_obj = self.get_object_by_id(_id) + it_exists = prev_obj is not None and isinstance(prev_obj, dict) + return (it_exists, prev_obj) + + def requires_update(self, current_obj): + requested_obj = self.new_object + + obj_params = [ + ("x509certSha1Fingerprint", "x509certSha1Fingerprint"), + ("sloLogoutUrl", "sloLogoutUrl"), + ("organizationId", "organizationId"), + ("idpId", "idpId"), + ] + # Method 1. Params present in request (Ansible) obj are the same as the current (DNAC) params + # If any does not have eq params, it requires update + return any(not meraki_compare_equality(current_obj.get(meraki_param), + requested_obj.get(ansible_param)) + for (meraki_param, ansible_param) in obj_params) + + def create(self): + result = self.meraki.exec_meraki( + family="organizations", + function="createOrganizationSamlIdp", + params=self.create_params(), + op_modifies=True, + ) + return result + + def update(self): + id = self.new_object.get("id") + id = id or self.new_object.get("idpId") + name = self.new_object.get("name") + result = None + if not id: + prev_obj_name = self.get_object_by_name(name) + id_ = None + if prev_obj_name: + id_ = prev_obj_name.get("id") + id_ = id_ or prev_obj_name.get("idpId") + if id_: + self.new_object.update(dict(idpId=id_)) + result = self.meraki.exec_meraki( + family="organizations", + function="updateOrganizationSamlIdp", + params=self.update_by_id_params(), + op_modifies=True, + ) + return result + + def delete(self): + id = self.new_object.get("id") + id = id or self.new_object.get("idpId") + name = self.new_object.get("name") + result = None + if not id: + prev_obj_name = self.get_object_by_name(name) + id_ = None + if prev_obj_name: + id_ = prev_obj_name.get("id") + id_ = id_ or prev_obj_name.get("idpId") + if id_: + self.new_object.update(dict(idpId=id_)) + result = self.meraki.exec_meraki( + family="organizations", + function="deleteOrganizationSamlIdp", + params=self.delete_by_id_params(), + ) + return result + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = False + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + meraki = MERAKI(self._task.args) + obj = OrganizationsSamlIdps(self._task.args, meraki) + + state = self._task.args.get("state") + + response = None + + if state == "present": + (obj_exists, prev_obj) = obj.exists() + if obj_exists: + if obj.requires_update(prev_obj): + response = obj.update() + meraki.object_updated() + else: + response = prev_obj + meraki.object_already_present() + else: + response = obj.create() + meraki.object_created() + + elif state == "absent": + (obj_exists, prev_obj) = obj.exists() + if obj_exists: + response = obj.delete() + meraki.object_deleted() + else: + meraki.object_already_absent() + + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/organizations_saml_idps_info.py b/ansible_collections/cisco/meraki/plugins/action/organizations_saml_idps_info.py new file mode 100644 index 000000000..c012f50ed --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/organizations_saml_idps_info.py @@ -0,0 +1,112 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + organizationId=dict(type="str"), + idpId=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_object(self, params): + new_object = {} + if params.get("organizationId") is not None: + new_object["organizationId"] = params.get( + "organizationId") + if params.get("idpId") is not None: + new_object["idpId"] = params.get( + "idpId") + return new_object + + def get_all(self, params): + new_object = {} + if params.get("organizationId") is not None: + new_object["organizationId"] = params.get( + "organizationId") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + id = self._task.args.get("idpId") + if id: + response = meraki.exec_meraki( + family="organizations", + function='getOrganizationSamlIdp', + params=self.get_object(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result + if not id: + response = meraki.exec_meraki( + family="organizations", + function='getOrganizationSamlIdps', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/organizations_saml_info.py b/ansible_collections/cisco/meraki/plugins/action/organizations_saml_info.py new file mode 100644 index 000000000..7646bde4b --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/organizations_saml_info.py @@ -0,0 +1,90 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + organizationId=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_all(self, params): + new_object = {} + if params.get("organizationId") is not None: + new_object["organizationId"] = params.get( + "organizationId") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="organizations", + function='getOrganizationSaml', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/organizations_saml_roles.py b/ansible_collections/cisco/meraki/plugins/action/organizations_saml_roles.py new file mode 100644 index 000000000..48dc6dfdb --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/organizations_saml_roles.py @@ -0,0 +1,329 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or +# https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, + meraki_compare_equality, + get_dict_result, +) +from ansible_collections.cisco.meraki.plugins.plugin_utils.exceptions import ( + InconsistentParameters, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + state=dict(type="str", default="present", choices=["present", "absent"]), + role=dict(type="str"), + orgAccess=dict(type="str"), + tags=dict(type="list"), + networks=dict(type="list"), + organizationId=dict(type="str"), + samlRoleId=dict(type="str"), +)) + +required_if = [ + ("state", "present", ["organizationId", "role", "samlRoleId"], True), + ("state", "absent", ["organizationId", "role", "samlRoleId"], True), +] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class OrganizationsSamlRoles(object): + def __init__(self, params, meraki): + self.meraki = meraki + self.new_object = dict( + role=params.get("role"), + orgAccess=params.get("orgAccess"), + tags=params.get("tags"), + networks=params.get("networks"), + organizationId=params.get("organizationId"), + samlRoleId=params.get("samlRoleId"), + ) + + def get_all_params(self, name=None, id=None): + new_object_params = {} + if self.new_object.get('organizationId') is not None or self.new_object.get('organization_id') is not None: + new_object_params['organizationId'] = self.new_object.get('organizationId') or \ + self.new_object.get('organization_id') + return new_object_params + + def get_params_by_id(self, name=None, id=None): + new_object_params = {} + if self.new_object.get('organizationId') is not None or self.new_object.get('organization_id') is not None: + new_object_params['organizationId'] = self.new_object.get('organizationId') or \ + self.new_object.get('organization_id') + if self.new_object.get('samlRoleId') is not None or self.new_object.get('saml_role_id') is not None: + new_object_params['samlRoleId'] = self.new_object.get('samlRoleId') or \ + self.new_object.get('saml_role_id') + return new_object_params + + def create_params(self): + new_object_params = {} + if self.new_object.get('role') is not None or self.new_object.get('role') is not None: + new_object_params['role'] = self.new_object.get('role') or \ + self.new_object.get('role') + if self.new_object.get('orgAccess') is not None or self.new_object.get('org_access') is not None: + new_object_params['orgAccess'] = self.new_object.get('orgAccess') or \ + self.new_object.get('org_access') + if self.new_object.get('tags') is not None or self.new_object.get('tags') is not None: + new_object_params['tags'] = self.new_object.get('tags') or \ + self.new_object.get('tags') + if self.new_object.get('networks') is not None or self.new_object.get('networks') is not None: + new_object_params['networks'] = self.new_object.get('networks') or \ + self.new_object.get('networks') + if self.new_object.get('organizationId') is not None or self.new_object.get('organization_id') is not None: + new_object_params['organizationId'] = self.new_object.get('organizationId') or \ + self.new_object.get('organization_id') + return new_object_params + + def delete_by_id_params(self): + new_object_params = {} + if self.new_object.get('organizationId') is not None or self.new_object.get('organization_id') is not None: + new_object_params['organizationId'] = self.new_object.get('organizationId') or \ + self.new_object.get('organization_id') + if self.new_object.get('samlRoleId') is not None or self.new_object.get('saml_role_id') is not None: + new_object_params['samlRoleId'] = self.new_object.get('samlRoleId') or \ + self.new_object.get('saml_role_id') + return new_object_params + + def update_by_id_params(self): + new_object_params = {} + if self.new_object.get('role') is not None or self.new_object.get('role') is not None: + new_object_params['role'] = self.new_object.get('role') or \ + self.new_object.get('role') + if self.new_object.get('orgAccess') is not None or self.new_object.get('org_access') is not None: + new_object_params['orgAccess'] = self.new_object.get('orgAccess') or \ + self.new_object.get('org_access') + if self.new_object.get('tags') is not None or self.new_object.get('tags') is not None: + new_object_params['tags'] = self.new_object.get('tags') or \ + self.new_object.get('tags') + if self.new_object.get('networks') is not None or self.new_object.get('networks') is not None: + new_object_params['networks'] = self.new_object.get('networks') or \ + self.new_object.get('networks') + if self.new_object.get('organizationId') is not None or self.new_object.get('organization_id') is not None: + new_object_params['organizationId'] = self.new_object.get('organizationId') or \ + self.new_object.get('organization_id') + if self.new_object.get('samlRoleId') is not None or self.new_object.get('saml_role_id') is not None: + new_object_params['samlRoleId'] = self.new_object.get('samlRoleId') or \ + self.new_object.get('saml_role_id') + return new_object_params + + def get_object_by_name(self, name): + result = None + # NOTE: Does not have a get by name method or it is in another action + try: + items = self.meraki.exec_meraki( + family="organizations", + function="getOrganizationSamlRoles", + params=self.get_all_params(name=name), + ) + if isinstance(items, dict): + if 'response' in items: + items = items.get('response') + result = get_dict_result(items, 'name', name) + if result is None: + result = items + except Exception as e: + print("Error: ", e) + result = None + return result + + def get_object_by_id(self, id): + result = None + try: + items = self.meraki.exec_meraki( + family="organizations", + function="getOrganizationSamlRole", + params=self.get_params_by_id() + ) + if isinstance(items, dict): + if 'response' in items: + items = items.get('response') + result = get_dict_result(items, 'samlRoleId', id) + except Exception as e: + print("Error: ", e) + result = None + return result + + def exists(self): + id_exists = False + name_exists = False + prev_obj = None + o_id = self.new_object.get("id") + o_id = o_id or self.new_object.get( + "saml_role_id") or self.new_object.get("samlRoleId") + name = self.new_object.get("name") + if o_id: + prev_obj = self.get_object_by_id(o_id) + id_exists = prev_obj is not None and isinstance(prev_obj, dict) + if not id_exists and name: + prev_obj = self.get_object_by_name(name) + name_exists = prev_obj is not None and isinstance(prev_obj, dict) + if name_exists: + _id = prev_obj.get("id") + _id = _id or prev_obj.get("samlRoleId") + if id_exists and name_exists and o_id != _id: + raise InconsistentParameters( + "The 'id' and 'name' params don't refer to the same object") + if _id: + self.new_object.update(dict(id=_id)) + self.new_object.update(dict(samlRoleId=_id)) + if _id: + prev_obj = self.get_object_by_id(_id) + it_exists = prev_obj is not None and isinstance(prev_obj, dict) + return (it_exists, prev_obj) + + def requires_update(self, current_obj): + requested_obj = self.new_object + + obj_params = [ + ("role", "role"), + ("orgAccess", "orgAccess"), + ("tags", "tags"), + ("networks", "networks"), + ("organizationId", "organizationId"), + ("samlRoleId", "samlRoleId"), + ] + # Method 1. Params present in request (Ansible) obj are the same as the current (DNAC) params + # If any does not have eq params, it requires update + return any(not meraki_compare_equality(current_obj.get(meraki_param), + requested_obj.get(ansible_param)) + for (meraki_param, ansible_param) in obj_params) + + def create(self): + result = self.meraki.exec_meraki( + family="organizations", + function="createOrganizationSamlRole", + params=self.create_params(), + op_modifies=True, + ) + return result + + def update(self): + id = self.new_object.get("id") + id = id or self.new_object.get("samlRoleId") + name = self.new_object.get("name") + result = None + if not id: + prev_obj_name = self.get_object_by_name(name) + id_ = None + if prev_obj_name: + id_ = prev_obj_name.get("id") + id_ = id_ or prev_obj_name.get("samlRoleId") + if id_: + self.new_object.update(dict(samlRoleId=id_)) + result = self.meraki.exec_meraki( + family="organizations", + function="updateOrganizationSamlRole", + params=self.update_by_id_params(), + op_modifies=True, + ) + return result + + def delete(self): + id = self.new_object.get("id") + id = id or self.new_object.get("samlRoleId") + name = self.new_object.get("name") + result = None + if not id: + prev_obj_name = self.get_object_by_name(name) + id_ = None + if prev_obj_name: + id_ = prev_obj_name.get("id") + id_ = id_ or prev_obj_name.get("samlRoleId") + if id_: + self.new_object.update(dict(samlRoleId=id_)) + result = self.meraki.exec_meraki( + family="organizations", + function="deleteOrganizationSamlRole", + params=self.delete_by_id_params(), + ) + return result + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = False + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + meraki = MERAKI(self._task.args) + obj = OrganizationsSamlRoles(self._task.args, meraki) + + state = self._task.args.get("state") + + response = None + + if state == "present": + (obj_exists, prev_obj) = obj.exists() + if obj_exists: + if obj.requires_update(prev_obj): + response = obj.update() + meraki.object_updated() + else: + response = prev_obj + meraki.object_already_present() + else: + response = obj.create() + meraki.object_created() + + elif state == "absent": + (obj_exists, prev_obj) = obj.exists() + if obj_exists: + response = obj.delete() + meraki.object_deleted() + else: + meraki.object_already_absent() + + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/organizations_saml_roles_info.py b/ansible_collections/cisco/meraki/plugins/action/organizations_saml_roles_info.py new file mode 100644 index 000000000..97a2e05c4 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/organizations_saml_roles_info.py @@ -0,0 +1,112 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + organizationId=dict(type="str"), + samlRoleId=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_object(self, params): + new_object = {} + if params.get("organizationId") is not None: + new_object["organizationId"] = params.get( + "organizationId") + if params.get("samlRoleId") is not None: + new_object["samlRoleId"] = params.get( + "samlRoleId") + return new_object + + def get_all(self, params): + new_object = {} + if params.get("organizationId") is not None: + new_object["organizationId"] = params.get( + "organizationId") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + id = self._task.args.get("samlRoleId") + if id: + response = meraki.exec_meraki( + family="organizations", + function='getOrganizationSamlRole', + params=self.get_object(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result + if not id: + response = meraki.exec_meraki( + family="organizations", + function='getOrganizationSamlRoles', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/organizations_sensor_readings_history_info.py b/ansible_collections/cisco/meraki/plugins/action/organizations_sensor_readings_history_info.py new file mode 100644 index 000000000..005e93c6a --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/organizations_sensor_readings_history_info.py @@ -0,0 +1,132 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + organizationId=dict(type="str"), + perPage=dict(type="int"), + total_pages=dict(type="int"), + direction=dict(type="str"), + startingAfter=dict(type="str"), + endingBefore=dict(type="str"), + t0=dict(type="str"), + t1=dict(type="str"), + timespan=dict(type="float"), + networkIds=dict(type="list"), + serials=dict(type="list"), + metrics=dict(type="list"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_all(self, params): + new_object = {} + if params.get("organizationId") is not None: + new_object["organizationId"] = params.get( + "organizationId") + if params.get("perPage") is not None: + new_object["perPage"] = params.get( + "perPage") + new_object['total_pages'] = params.get( + "total_pages") or 1 + new_object['direction'] = params.get( + "direction") or "next" + if params.get("startingAfter") is not None: + new_object["startingAfter"] = params.get( + "startingAfter") + if params.get("endingBefore") is not None: + new_object["endingBefore"] = params.get( + "endingBefore") + if params.get("t0") is not None: + new_object["t0"] = params.get( + "t0") + if params.get("t1") is not None: + new_object["t1"] = params.get( + "t1") + if params.get("timespan") is not None: + new_object["timespan"] = params.get( + "timespan") + if params.get("networkIds") is not None: + new_object["networkIds"] = params.get( + "networkIds") + if params.get("serials") is not None: + new_object["serials"] = params.get( + "serials") + if params.get("metrics") is not None: + new_object["metrics"] = params.get( + "metrics") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="sensor", + function='getOrganizationSensorReadingsHistory', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/organizations_sensor_readings_latest_info.py b/ansible_collections/cisco/meraki/plugins/action/organizations_sensor_readings_latest_info.py new file mode 100644 index 000000000..9d3c2b8d6 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/organizations_sensor_readings_latest_info.py @@ -0,0 +1,120 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + organizationId=dict(type="str"), + perPage=dict(type="int"), + total_pages=dict(type="int"), + direction=dict(type="str"), + startingAfter=dict(type="str"), + endingBefore=dict(type="str"), + networkIds=dict(type="list"), + serials=dict(type="list"), + metrics=dict(type="list"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_all(self, params): + new_object = {} + if params.get("organizationId") is not None: + new_object["organizationId"] = params.get( + "organizationId") + if params.get("perPage") is not None: + new_object["perPage"] = params.get( + "perPage") + new_object['total_pages'] = params.get( + "total_pages") or 1 + new_object['direction'] = params.get( + "direction") or "next" + if params.get("startingAfter") is not None: + new_object["startingAfter"] = params.get( + "startingAfter") + if params.get("endingBefore") is not None: + new_object["endingBefore"] = params.get( + "endingBefore") + if params.get("networkIds") is not None: + new_object["networkIds"] = params.get( + "networkIds") + if params.get("serials") is not None: + new_object["serials"] = params.get( + "serials") + if params.get("metrics") is not None: + new_object["metrics"] = params.get( + "metrics") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="sensor", + function='getOrganizationSensorReadingsLatest', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/organizations_sm_apns_cert_info.py b/ansible_collections/cisco/meraki/plugins/action/organizations_sm_apns_cert_info.py new file mode 100644 index 000000000..1afe748ed --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/organizations_sm_apns_cert_info.py @@ -0,0 +1,90 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + organizationId=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_all(self, params): + new_object = {} + if params.get("organizationId") is not None: + new_object["organizationId"] = params.get( + "organizationId") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="sm", + function='getOrganizationSmApnsCert', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/organizations_sm_vpp_accounts_info.py b/ansible_collections/cisco/meraki/plugins/action/organizations_sm_vpp_accounts_info.py new file mode 100644 index 000000000..028dfcdab --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/organizations_sm_vpp_accounts_info.py @@ -0,0 +1,112 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + organizationId=dict(type="str"), + vppAccountId=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_object(self, params): + new_object = {} + if params.get("organizationId") is not None: + new_object["organizationId"] = params.get( + "organizationId") + if params.get("vppAccountId") is not None: + new_object["vppAccountId"] = params.get( + "vppAccountId") + return new_object + + def get_all(self, params): + new_object = {} + if params.get("organizationId") is not None: + new_object["organizationId"] = params.get( + "organizationId") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + id = self._task.args.get("vppAccountId") + if id: + response = meraki.exec_meraki( + family="sm", + function='getOrganizationSmVppAccount', + params=self.get_object(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result + if not id: + response = meraki.exec_meraki( + family="sm", + function='getOrganizationSmVppAccounts', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/organizations_snmp.py b/ansible_collections/cisco/meraki/plugins/action/organizations_snmp.py new file mode 100644 index 000000000..aaf676ee7 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/organizations_snmp.py @@ -0,0 +1,234 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or +# https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, + meraki_compare_equality, + get_dict_result, +) +from ansible_collections.cisco.meraki.plugins.plugin_utils.exceptions import ( + InconsistentParameters, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + state=dict(type="str", default="present", choices=["present"]), + v2cEnabled=dict(type="bool"), + v3Enabled=dict(type="bool"), + v3AuthMode=dict(type="str"), + v3AuthPass=dict(type="str"), + v3PrivMode=dict(type="str"), + v3PrivPass=dict(type="str"), + peerIps=dict(type="list"), + organizationId=dict(type="str"), +)) + +required_if = [ + ("state", "present", ["organizationId"], True), +] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class OrganizationsSnmp(object): + def __init__(self, params, meraki): + self.meraki = meraki + self.new_object = dict( + v2cEnabled=params.get("v2cEnabled"), + v3Enabled=params.get("v3Enabled"), + v3AuthMode=params.get("v3AuthMode"), + v3AuthPass=params.get("v3AuthPass"), + v3PrivMode=params.get("v3PrivMode"), + v3PrivPass=params.get("v3PrivPass"), + peerIps=params.get("peerIps"), + organization_id=params.get("organizationId"), + ) + + def get_all_params(self, name=None, id=None): + new_object_params = {} + if self.new_object.get('organizationId') is not None or self.new_object.get('organization_id') is not None: + new_object_params['organizationId'] = self.new_object.get('organizationId') or \ + self.new_object.get('organization_id') + return new_object_params + + def update_all_params(self): + new_object_params = {} + if self.new_object.get('v2cEnabled') is not None or self.new_object.get('v2c_enabled') is not None: + new_object_params['v2cEnabled'] = self.new_object.get('v2cEnabled') + if self.new_object.get('v3Enabled') is not None or self.new_object.get('v3_enabled') is not None: + new_object_params['v3Enabled'] = self.new_object.get('v3Enabled') + if self.new_object.get('v3AuthMode') is not None or self.new_object.get('v3_auth_mode') is not None: + new_object_params['v3AuthMode'] = self.new_object.get('v3AuthMode') or \ + self.new_object.get('v3_auth_mode') + if self.new_object.get('v3AuthPass') is not None or self.new_object.get('v3_auth_pass') is not None: + new_object_params['v3AuthPass'] = self.new_object.get('v3AuthPass') or \ + self.new_object.get('v3_auth_pass') + if self.new_object.get('v3PrivMode') is not None or self.new_object.get('v3_priv_mode') is not None: + new_object_params['v3PrivMode'] = self.new_object.get('v3PrivMode') or \ + self.new_object.get('v3_priv_mode') + if self.new_object.get('v3PrivPass') is not None or self.new_object.get('v3_priv_pass') is not None: + new_object_params['v3PrivPass'] = self.new_object.get('v3PrivPass') or \ + self.new_object.get('v3_priv_pass') + if self.new_object.get('peerIps') is not None or self.new_object.get('peer_ips') is not None: + new_object_params['peerIps'] = self.new_object.get('peerIps') or \ + self.new_object.get('peer_ips') + if self.new_object.get('organizationId') is not None or self.new_object.get('organization_id') is not None: + new_object_params['organizationId'] = self.new_object.get('organizationId') or \ + self.new_object.get('organization_id') + return new_object_params + + def get_object_by_name(self, name): + result = None + # NOTE: Does not have a get by name method, using get all + try: + items = self.meraki.exec_meraki( + family="organizations", + function="getOrganizationSnmp", + params=self.get_all_params(name=name), + ) + if isinstance(items, dict): + if 'response' in items: + items = items.get('response') + result = get_dict_result(items, 'name', name) + if result is None: + result = items + except Exception as e: + print("Error: ", e) + result = None + return result + + def get_object_by_id(self, id): + result = None + # NOTE: Does not have a get by id method or it is in another action + return result + + def exists(self): + prev_obj = None + id_exists = False + name_exists = False + o_id = self.new_object.get("organizationId") or self.new_object.get("organization_id") + name = self.new_object.get("name") + if o_id: + prev_obj = self.get_object_by_name(o_id) + id_exists = prev_obj is not None and isinstance(prev_obj, dict) + if not id_exists and name: + prev_obj = self.get_object_by_name(name) + name_exists = prev_obj is not None and isinstance(prev_obj, dict) + if name_exists: + _id = prev_obj.get("id") + if id_exists and name_exists and o_id != _id: + raise InconsistentParameters( + "The 'id' and 'name' params don't refer to the same object") + if _id: + self.new_object.update(dict(id=_id)) + it_exists = prev_obj is not None and isinstance(prev_obj, dict) + return (it_exists, prev_obj) + + def requires_update(self, current_obj): + requested_obj = self.new_object + + obj_params = [ + ("v2cEnabled", "v2cEnabled"), + ("v3Enabled", "v3Enabled"), + ("v3AuthMode", "v3AuthMode"), + ("v3AuthPass", "v3AuthPass"), + ("v3PrivMode", "v3PrivMode"), + ("v3PrivPass", "v3PrivPass"), + ("peerIps", "peerIps"), + ("organizationId", "organizationId"), + ] + # Method 1. Params present in request (Ansible) obj are the same as the current (ISE) params + # If any does not have eq params, it requires update + return any(not meraki_compare_equality(current_obj.get(meraki_param), + requested_obj.get(ansible_param)) + for (meraki_param, ansible_param) in obj_params) + + def update(self): + id = self.new_object.get("id") + name = self.new_object.get("name") + result = None + result = self.meraki.exec_meraki( + family="organizations", + function="updateOrganizationSnmp", + params=self.update_all_params(), + op_modifies=True, + ) + return result + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = False + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + meraki = MERAKI(self._task.args) + obj = OrganizationsSnmp(self._task.args, meraki) + + state = self._task.args.get("state") + + response = None + if state == "present": + (obj_exists, prev_obj) = obj.exists() + if obj_exists: + if obj.requires_update(prev_obj): + response = obj.update() + meraki.object_updated() + else: + response = prev_obj + meraki.object_already_present() + else: + meraki.fail_json( + "Object does not exists, plugin only has update") + + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/organizations_snmp_info.py b/ansible_collections/cisco/meraki/plugins/action/organizations_snmp_info.py new file mode 100644 index 000000000..d8db860da --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/organizations_snmp_info.py @@ -0,0 +1,90 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + organizationId=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_all(self, params): + new_object = {} + if params.get("organizationId") is not None: + new_object["organizationId"] = params.get( + "organizationId") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="organizations", + function='getOrganizationSnmp', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/organizations_summary_top_appliances_by_utilization_info.py b/ansible_collections/cisco/meraki/plugins/action/organizations_summary_top_appliances_by_utilization_info.py new file mode 100644 index 000000000..1870d2dfd --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/organizations_summary_top_appliances_by_utilization_info.py @@ -0,0 +1,102 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + organizationId=dict(type="str"), + t0=dict(type="str"), + t1=dict(type="str"), + timespan=dict(type="float"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_all(self, params): + new_object = {} + if params.get("organizationId") is not None: + new_object["organizationId"] = params.get( + "organizationId") + if params.get("t0") is not None: + new_object["t0"] = params.get( + "t0") + if params.get("t1") is not None: + new_object["t1"] = params.get( + "t1") + if params.get("timespan") is not None: + new_object["timespan"] = params.get( + "timespan") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="organizations", + function='getOrganizationSummaryTopAppliancesByUtilization', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/organizations_summary_top_clients_by_usage_info.py b/ansible_collections/cisco/meraki/plugins/action/organizations_summary_top_clients_by_usage_info.py new file mode 100644 index 000000000..456f8e077 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/organizations_summary_top_clients_by_usage_info.py @@ -0,0 +1,102 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + organizationId=dict(type="str"), + t0=dict(type="str"), + t1=dict(type="str"), + timespan=dict(type="float"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_all(self, params): + new_object = {} + if params.get("organizationId") is not None: + new_object["organizationId"] = params.get( + "organizationId") + if params.get("t0") is not None: + new_object["t0"] = params.get( + "t0") + if params.get("t1") is not None: + new_object["t1"] = params.get( + "t1") + if params.get("timespan") is not None: + new_object["timespan"] = params.get( + "timespan") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="organizations", + function='getOrganizationSummaryTopClientsByUsage', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/organizations_summary_top_clients_manufacturers_by_usage_info.py b/ansible_collections/cisco/meraki/plugins/action/organizations_summary_top_clients_manufacturers_by_usage_info.py new file mode 100644 index 000000000..ba1a95ff4 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/organizations_summary_top_clients_manufacturers_by_usage_info.py @@ -0,0 +1,102 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + organizationId=dict(type="str"), + t0=dict(type="str"), + t1=dict(type="str"), + timespan=dict(type="float"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_all(self, params): + new_object = {} + if params.get("organizationId") is not None: + new_object["organizationId"] = params.get( + "organizationId") + if params.get("t0") is not None: + new_object["t0"] = params.get( + "t0") + if params.get("t1") is not None: + new_object["t1"] = params.get( + "t1") + if params.get("timespan") is not None: + new_object["timespan"] = params.get( + "timespan") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="organizations", + function='getOrganizationSummaryTopClientsManufacturersByUsage', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/organizations_summary_top_devices_by_usage_info.py b/ansible_collections/cisco/meraki/plugins/action/organizations_summary_top_devices_by_usage_info.py new file mode 100644 index 000000000..360253371 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/organizations_summary_top_devices_by_usage_info.py @@ -0,0 +1,102 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + organizationId=dict(type="str"), + t0=dict(type="str"), + t1=dict(type="str"), + timespan=dict(type="float"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_all(self, params): + new_object = {} + if params.get("organizationId") is not None: + new_object["organizationId"] = params.get( + "organizationId") + if params.get("t0") is not None: + new_object["t0"] = params.get( + "t0") + if params.get("t1") is not None: + new_object["t1"] = params.get( + "t1") + if params.get("timespan") is not None: + new_object["timespan"] = params.get( + "timespan") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="organizations", + function='getOrganizationSummaryTopDevicesByUsage', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/organizations_summary_top_devices_models_by_usage_info.py b/ansible_collections/cisco/meraki/plugins/action/organizations_summary_top_devices_models_by_usage_info.py new file mode 100644 index 000000000..9f8cdb828 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/organizations_summary_top_devices_models_by_usage_info.py @@ -0,0 +1,102 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + organizationId=dict(type="str"), + t0=dict(type="str"), + t1=dict(type="str"), + timespan=dict(type="float"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_all(self, params): + new_object = {} + if params.get("organizationId") is not None: + new_object["organizationId"] = params.get( + "organizationId") + if params.get("t0") is not None: + new_object["t0"] = params.get( + "t0") + if params.get("t1") is not None: + new_object["t1"] = params.get( + "t1") + if params.get("timespan") is not None: + new_object["timespan"] = params.get( + "timespan") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="organizations", + function='getOrganizationSummaryTopDevicesModelsByUsage', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/organizations_summary_top_ssids_by_usage_info.py b/ansible_collections/cisco/meraki/plugins/action/organizations_summary_top_ssids_by_usage_info.py new file mode 100644 index 000000000..4e989e9d5 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/organizations_summary_top_ssids_by_usage_info.py @@ -0,0 +1,102 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + organizationId=dict(type="str"), + t0=dict(type="str"), + t1=dict(type="str"), + timespan=dict(type="float"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_all(self, params): + new_object = {} + if params.get("organizationId") is not None: + new_object["organizationId"] = params.get( + "organizationId") + if params.get("t0") is not None: + new_object["t0"] = params.get( + "t0") + if params.get("t1") is not None: + new_object["t1"] = params.get( + "t1") + if params.get("timespan") is not None: + new_object["timespan"] = params.get( + "timespan") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="organizations", + function='getOrganizationSummaryTopSsidsByUsage', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/organizations_summary_top_switches_by_energy_usage_info.py b/ansible_collections/cisco/meraki/plugins/action/organizations_summary_top_switches_by_energy_usage_info.py new file mode 100644 index 000000000..750053847 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/organizations_summary_top_switches_by_energy_usage_info.py @@ -0,0 +1,102 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + organizationId=dict(type="str"), + t0=dict(type="str"), + t1=dict(type="str"), + timespan=dict(type="float"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_all(self, params): + new_object = {} + if params.get("organizationId") is not None: + new_object["organizationId"] = params.get( + "organizationId") + if params.get("t0") is not None: + new_object["t0"] = params.get( + "t0") + if params.get("t1") is not None: + new_object["t1"] = params.get( + "t1") + if params.get("timespan") is not None: + new_object["timespan"] = params.get( + "timespan") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="organizations", + function='getOrganizationSummaryTopSwitchesByEnergyUsage', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/organizations_switch_devices_clone.py b/ansible_collections/cisco/meraki/plugins/action/organizations_switch_devices_clone.py new file mode 100644 index 000000000..37e199676 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/organizations_switch_devices_clone.py @@ -0,0 +1,91 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguements specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + sourceSerial=dict(type="str"), + targetSerials=dict(type="list"), + organizationId=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = False + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_object(self, params): + new_object = dict( + sourceSerial=params.get("sourceSerial"), + targetSerials=params.get("targetSerials"), + organizationId=params.get("organizationId"), + ) + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="switch", + function='cloneOrganizationSwitchDevices', + op_modifies=True, + params=self.get_object(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/organizations_switch_ports_by_switch_info.py b/ansible_collections/cisco/meraki/plugins/action/organizations_switch_ports_by_switch_info.py new file mode 100644 index 000000000..08072b186 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/organizations_switch_ports_by_switch_info.py @@ -0,0 +1,140 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + organizationId=dict(type="str"), + perPage=dict(type="int"), + total_pages=dict(type="int"), + direction=dict(type="str"), + startingAfter=dict(type="str"), + endingBefore=dict(type="str"), + networkIds=dict(type="list"), + portProfileIds=dict(type="list"), + name=dict(type="str"), + mac=dict(type="str"), + macs=dict(type="list"), + serial=dict(type="str"), + serials=dict(type="list"), + configurationUpdatedAfter=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_all(self, params): + new_object = {} + if params.get("organizationId") is not None: + new_object["organizationId"] = params.get( + "organizationId") + if params.get("perPage") is not None: + new_object["perPage"] = params.get( + "perPage") + new_object['total_pages'] = params.get( + "total_pages") or 1 + new_object['direction'] = params.get( + "direction") or "next" + if params.get("startingAfter") is not None: + new_object["startingAfter"] = params.get( + "startingAfter") + if params.get("endingBefore") is not None: + new_object["endingBefore"] = params.get( + "endingBefore") + if params.get("networkIds") is not None: + new_object["networkIds"] = params.get( + "networkIds") + if params.get("portProfileIds") is not None: + new_object["portProfileIds"] = params.get( + "portProfileIds") + if params.get("name") is not None: + new_object["name"] = params.get( + "name") + if params.get("mac") is not None: + new_object["mac"] = params.get( + "mac") + if params.get("macs") is not None: + new_object["macs"] = params.get( + "macs") + if params.get("serial") is not None: + new_object["serial"] = params.get( + "serial") + if params.get("serials") is not None: + new_object["serials"] = params.get( + "serials") + if params.get("configurationUpdatedAfter") is not None: + new_object["configurationUpdatedAfter"] = params.get( + "configurationUpdatedAfter") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="switch", + function='getOrganizationSwitchPortsBySwitch', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/organizations_uplinks_statuses_info.py b/ansible_collections/cisco/meraki/plugins/action/organizations_uplinks_statuses_info.py new file mode 100644 index 000000000..3c88a7c1a --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/organizations_uplinks_statuses_info.py @@ -0,0 +1,120 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + organizationId=dict(type="str"), + perPage=dict(type="int"), + total_pages=dict(type="int"), + direction=dict(type="str"), + startingAfter=dict(type="str"), + endingBefore=dict(type="str"), + networkIds=dict(type="list"), + serials=dict(type="list"), + iccids=dict(type="list"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_all(self, params): + new_object = {} + if params.get("organizationId") is not None: + new_object["organizationId"] = params.get( + "organizationId") + if params.get("perPage") is not None: + new_object["perPage"] = params.get( + "perPage") + new_object['total_pages'] = params.get( + "total_pages") or 1 + new_object['direction'] = params.get( + "direction") or "next" + if params.get("startingAfter") is not None: + new_object["startingAfter"] = params.get( + "startingAfter") + if params.get("endingBefore") is not None: + new_object["endingBefore"] = params.get( + "endingBefore") + if params.get("networkIds") is not None: + new_object["networkIds"] = params.get( + "networkIds") + if params.get("serials") is not None: + new_object["serials"] = params.get( + "serials") + if params.get("iccids") is not None: + new_object["iccids"] = params.get( + "iccids") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="organizations", + function='getOrganizationUplinksStatuses', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/organizations_users.py b/ansible_collections/cisco/meraki/plugins/action/organizations_users.py new file mode 100644 index 000000000..ae07884ee --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/organizations_users.py @@ -0,0 +1,88 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguements specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + organizationId=dict(type="str"), + userId=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = False + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_object(self, params): + new_object = dict( + organizationId=params.get("organizationId"), + user_id=params.get("userId"), + ) + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="organizations", + function="deleteOrganizationUser", + params=self.get_object(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/organizations_webhooks_logs_info.py b/ansible_collections/cisco/meraki/plugins/action/organizations_webhooks_logs_info.py new file mode 100644 index 000000000..fd14a1d2e --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/organizations_webhooks_logs_info.py @@ -0,0 +1,124 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + organizationId=dict(type="str"), + t0=dict(type="str"), + t1=dict(type="str"), + timespan=dict(type="float"), + perPage=dict(type="int"), + total_pages=dict(type="int"), + direction=dict(type="str"), + startingAfter=dict(type="str"), + endingBefore=dict(type="str"), + url=dict(type="str"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_all(self, params): + new_object = {} + if params.get("organizationId") is not None: + new_object["organizationId"] = params.get( + "organizationId") + if params.get("t0") is not None: + new_object["t0"] = params.get( + "t0") + if params.get("t1") is not None: + new_object["t1"] = params.get( + "t1") + if params.get("timespan") is not None: + new_object["timespan"] = params.get( + "timespan") + if params.get("perPage") is not None: + new_object["perPage"] = params.get( + "perPage") + new_object['total_pages'] = params.get( + "total_pages") or 1 + new_object['direction'] = params.get( + "direction") or "next" + if params.get("startingAfter") is not None: + new_object["startingAfter"] = params.get( + "startingAfter") + if params.get("endingBefore") is not None: + new_object["endingBefore"] = params.get( + "endingBefore") + if params.get("url") is not None: + new_object["url"] = params.get( + "url") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="organizations", + function='getOrganizationWebhooksLogs', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result diff --git a/ansible_collections/cisco/meraki/plugins/action/organizations_wireless_devices_ethernet_statuses_info.py b/ansible_collections/cisco/meraki/plugins/action/organizations_wireless_devices_ethernet_statuses_info.py new file mode 100644 index 000000000..f49356d95 --- /dev/null +++ b/ansible_collections/cisco/meraki/plugins/action/organizations_wireless_devices_ethernet_statuses_info.py @@ -0,0 +1,112 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2021, Cisco Systems +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +from ansible.plugins.action import ActionBase +try: + from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + AnsibleArgSpecValidator, + ) +except ImportError: + ANSIBLE_UTILS_IS_INSTALLED = False +else: + ANSIBLE_UTILS_IS_INSTALLED = True +from ansible.errors import AnsibleActionFail +from ansible_collections.cisco.meraki.plugins.plugin_utils.meraki import ( + MERAKI, + meraki_argument_spec, +) + +# Get common arguments specification +argument_spec = meraki_argument_spec() +# Add arguments specific for this module +argument_spec.update(dict( + organizationId=dict(type="str"), + perPage=dict(type="int"), + total_pages=dict(type="int"), + direction=dict(type="str"), + startingAfter=dict(type="str"), + endingBefore=dict(type="str"), + networkIds=dict(type="list"), +)) + +required_if = [] +required_one_of = [] +mutually_exclusive = [] +required_together = [] + + +class ActionModule(ActionBase): + def __init__(self, *args, **kwargs): + if not ANSIBLE_UTILS_IS_INSTALLED: + raise AnsibleActionFail( + "ansible.utils is not installed. Execute 'ansible-galaxy collection install ansible.utils'") + super(ActionModule, self).__init__(*args, **kwargs) + self._supports_async = False + self._supports_check_mode = True + self._result = None + + # Checks the supplied parameters against the argument spec for this module + def _check_argspec(self): + aav = AnsibleArgSpecValidator( + data=self._task.args, + schema=dict(argument_spec=argument_spec), + schema_format="argspec", + schema_conditionals=dict( + required_if=required_if, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + ), + name=self._task.action, + ) + valid, errors, self._task.args = aav.validate() + if not valid: + raise AnsibleActionFail(errors) + + def get_all(self, params): + new_object = {} + if params.get("organizationId") is not None: + new_object["organizationId"] = params.get( + "organizationId") + if params.get("perPage") is not None: + new_object["perPage"] = params.get( + "perPage") + new_object['total_pages'] = params.get( + "total_pages") or 1 + new_object['direction'] = params.get( + "direction") or "next" + if params.get("startingAfter") is not None: + new_object["startingAfter"] = params.get( + "startingAfter") + if params.get("endingBefore") is not None: + new_object["endingBefore"] = params.get( + "endingBefore") + if params.get("networkIds") is not None: + new_object["networkIds"] = params.get( + "networkIds") + + return new_object + + def run(self, tmp=None, task_vars=None): + self._task.diff = False + self._result = super(ActionModule, self).run(tmp, task_vars) + self._result["changed"] = False + self._check_argspec() + + self._result.update(dict(meraki_response={})) + + meraki = MERAKI(params=self._task.args) + + response = meraki.exec_meraki( + family="wireless", + function='getOrganizationWirelessDevicesEthernetStatuses', + params=self.get_all(self._task.args), + ) + self._result.update(dict(meraki_response=response)) + self._result.update(meraki.exit_json()) + return self._result |