def update_modify_payload(module, rest_obj, modify_payload, current_baseline): paylist = [ 'Name', "CatalogId", "RepositoryId", 'Description', 'DowngradeEnabled', 'Is64Bit' ] diff_tuple = recursive_diff(modify_payload, current_baseline) diff = 0 payload = dict([(item, current_baseline.get(item)) for item in paylist]) if diff_tuple: if diff_tuple[0]: diff += 1 payload.update(diff_tuple[0]) payload['Targets'] = current_baseline.get('Targets', []) inp_targets_list = get_target_list(module, rest_obj) if inp_targets_list: inp_target_dict = dict([(item['Id'], item['Type']['Id']) for item in inp_targets_list]) cur_target_dict = dict([ (item['Id'], item['Type']['Id']) for item in current_baseline.get('Targets', []) ]) diff_tuple = recursive_diff(inp_target_dict, cur_target_dict) if diff_tuple: diff += 1 payload['Targets'] = inp_targets_list if diff == 0: module.exit_json(msg=NO_CHANGES_MSG) payload['Id'] = current_baseline['Id'] return payload
def test_recursive_diff(self): a = {'foo': {'bar': [{'baz': {'qux': 'ham_sandwich'}}]}} c = {'foo': {'bar': [{'baz': {'qux': 'ham_sandwich'}}]}} b = {'foo': {'bar': [{'baz': {'qux': 'turkey_sandwich'}}]}} assert recursive_diff(a, b) is not None assert len(recursive_diff(a, b)) == 2 assert recursive_diff(a, c) is None
def generate_diff(self, before, after): """Creates a diff based on two objects. Applies to the object and returns nothing. """ try: diff = recursive_diff(before, after) self.result['diff'] = {'before': diff[0], 'after': diff[1]} except AttributeError: # Normally for passing a list instead of a dict diff = recursive_diff({'data': before}, {'data': after}) self.result['diff'] = { 'before': diff[0]['data'], 'after': diff[1]['data'] }
def modify_ad(module, rest_obj, ad): prm = module.params modify_payload = make_payload(prm) ad = rest_obj.strip_substr_dict(ad) if ad.get('ServerName'): (ad.get('ServerName')).sort() if modify_payload.get('ServerName'): (modify_payload.get('ServerName')).sort() diff = recursive_diff(modify_payload, ad) is_change = False if diff: if diff[0]: is_change = True ad.update(modify_payload) msg = validate_n_testconnection(module, rest_obj, ad) if not is_change and not ad.get('CertificateValidation'): module.exit_json(msg="{0}{1}".format(msg, NO_CHANGES_MSG), active_directory=ad) if module.check_mode: module.exit_json(msg="{0}{1}".format(msg, CHANGES_FOUND), changed=True) resp = rest_obj.invoke_request('PUT', "{0}({1})".format(AD_URI, ad['Id']), data=ad) ad = resp.json_data ad.pop('CertificateFile', "") module.exit_json(msg="{0}{1}".format(msg, MODIFY_SUCCESS), active_directory=ad, changed=True)
def _diff_payload(curr_resp, update_resp): is_change = False if update_resp: diff = recursive_diff(update_resp, curr_resp) if diff and diff[0]: is_change = True return is_change
def modify_profile(module, rest_obj): mparam = module.params payload = {} prof = get_profile(rest_obj, module) if not prof: module.fail_json(msg=PROFILE_NOT_FOUND.format(name=mparam.get('name'))) diff = 0 new_name = mparam.get('new_name') payload['Name'] = new_name if new_name else prof['ProfileName'] if new_name and new_name != prof['ProfileName']: diff += 1 desc = mparam.get('description') if desc and desc != prof['ProfileDescription']: payload['Description'] = desc diff += 1 boot_iso_dict = get_network_iso_payload(module) rdict = prof.get('NetworkBootToIso') if prof.get('NetworkBootToIso') else {} if boot_iso_dict: nest_diff = recursive_diff(boot_iso_dict, rdict) if nest_diff: module.warn(json.dumps(nest_diff)) if nest_diff[0]: diff += 1 payload["NetworkBootToIso"] = boot_iso_dict ad_opts = mparam.get("attributes") if ad_opts and ad_opts.get("Attributes"): payload["Attributes"] = ad_opts.get("Attributes") diff += 1 payload['Id'] = prof['Id'] if diff: resp = rest_obj.invoke_request('PUT', PROFILE_VIEW + "({0})".format(payload['Id']), data=payload) module.exit_json(msg="Successfully modified the profile.", changed=True) module.exit_json(msg="No changes found to be applied.")
def diff_objects(existing, new): result = dict() diff = recursive_diff(existing, new) if diff: result['before'] = diff[0] result['after'] = diff[1] return not diff, result
def test_dict_diff_with_diff(): from_dict = { 'string': 'foo', 'number': 4, 'dict': { 'a': 'z', 'c': 'x' }, 'foo_list': [ 1, 2, ] } to_dict = { 'string': 'bar', 'number': '4', 'dict': { 'a': 'z', 'b': 'y' }, 'foo_list': [ 1, 2, 3, 4 ] } assert recursive_diff(from_dict, to_dict) == ({'string': 'foo', 'dict': {'c': 'x'}, 'foo_list': [ 1, 2], 'number': 4}, {'string': 'bar', 'dict': {'b': 'y'}, 'foo_list': [1, 2, 3, 4], 'number': '4'})
def test_dict_diff_with_no_diff(): to_dict = { 'string': 'bar', 'number': 4, 'dict': { 'a': 'z', 'b': 'y' }, 'foo_list': [ 1, 2, 3, 4 ] } from_dict = { 'string': 'bar', 'number': 4, 'dict': { 'a': 'z', 'b': 'y' }, 'foo_list': [ 1, 2, 3, 4 ] } assert recursive_diff(to_dict, from_dict) is None
def create_admin(meraki, org_id, name, email): payload = dict() payload['name'] = name payload['email'] = email is_admin_existing = find_admin(meraki, get_admins(meraki, org_id), email) if meraki.params['org_access'] is not None: payload['orgAccess'] = meraki.params['org_access'] if meraki.params['tags'] is not None: payload['tags'] = json.loads(meraki.params['tags']) if meraki.params['networks'] is not None: nets = meraki.get_nets(org_id=org_id) networks = network_factory(meraki, meraki.params['networks'], nets) payload['networks'] = networks if is_admin_existing is None: # Create new admin if meraki.module.check_mode is True: meraki.result['data'] = payload meraki.result['changed'] = True meraki.exit_json(**meraki.result) path = meraki.construct_path('create', function='admin', org_id=org_id) r = meraki.request(path, method='POST', payload=json.dumps(payload)) if meraki.status == 201: meraki.result['changed'] = True return r elif is_admin_existing is not None: # Update existing admin if not meraki.params['tags']: payload['tags'] = [] if not meraki.params['networks']: payload['networks'] = [] if meraki.is_update_required(is_admin_existing, payload) is True: if meraki.module.check_mode is True: diff = recursive_diff(is_admin_existing, payload) is_admin_existing.update(payload) meraki.result['diff'] = { 'before': diff[0], 'after': diff[1], } meraki.result['changed'] = True meraki.result['data'] = payload meraki.exit_json(**meraki.result) path = meraki.construct_path( 'update', function='admin', org_id=org_id) + is_admin_existing['id'] r = meraki.request(path, method='PUT', payload=json.dumps(payload)) if meraki.status == 200: meraki.result['changed'] = True return r else: meraki.result['data'] = is_admin_existing if meraki.module.check_mode is True: meraki.result['data'] = payload meraki.exit_json(**meraki.result) return -1
def main(): module = AnsibleModule({ 'a': { 'type': 'dict' }, 'b': { 'type': 'dict' }, }) module.exit_json(the_diff=recursive_diff( module.params['a'], module.params['b'], ), )
def transform_diff(params, translator, sub_payload, bool_trans=None): df = {} inp_dict = {} for k, v in translator.items(): inp = params.get(k) if inp is not None: if isinstance(inp, bool) and bool_trans: inp = bool_trans.get(inp) inp_dict[v] = inp id_diff = recursive_diff(inp_dict, sub_payload) if id_diff and id_diff[0]: df = id_diff[0] sub_payload.update(inp_dict) return df
def compare_get_payload(module, current_list, input_config): payload_list = [strip_substr_dict(sys) for sys in current_list] # preserving list order current_config = dict([(sys.get('Id'), sys) for sys in payload_list]) diff = 0 for k, v in current_config.items(): i_dict = input_config.get(k) if i_dict: d = recursive_diff(i_dict, v) if d and d[0]: v.update(d[0]) diff = diff + 1 v.pop("Id", None) # not mandatory payload_list[int(k) - 1] = v # The order in list needs to be maintained if not diff: module.exit_json(msg=NO_CHANGES_MSG) if module.check_mode: module.exit_json(msg=CHANGES_FOUND, changed=True) return payload_list
def diff_hosts(before, beforedir, after, afterdir): result = dict() result['updated'] = dict() result['created'] = set(after.keys()) - set(before.keys()) result['deleted'] = set(before.keys()) - set(after.keys()) with tempfile.TemporaryDirectory() as tmpdirname: root = os.path.join(tmpdirname, 'root') for host in set(after.keys()) & set(before.keys()): os.symlink(beforedir, root) rendered_before = template(before[host], root) os.unlink(root) os.symlink(afterdir, root) rendered_after = template(after[host], root) os.unlink(root) if rendered_before != rendered_after: result['updated'][host] = recursive_diff( rendered_before, rendered_after) return result
def get_slot_data(module, rest_obj, ch_slots, chass_id): uri = DEVICE_URI + "({0})/DeviceBladeSlots".format(chass_id) chsvc_tag = ch_slots.get('chassis_service_tag') resp = rest_obj.invoke_request("GET", uri) blade_slots = resp.json_data.get('value') if len(blade_slots) < 8: # Storage type 3000 resp = get_device_type(rest_obj, 3000) storage = resp.get('value') for stx in storage: if stx.get('ChassisServiceTag') == chsvc_tag: blade_slots.append(stx.get('SlotConfiguration')) blade_dict = {} for slot in blade_slots: slot["ChassisId"] = chass_id slot["ChassisServiceTag"] = chsvc_tag if slot.get('Id'): slot["SlotId"] = str(slot.get('Id')) blade_dict[slot['SlotNumber']] = slot rest_obj.strip_substr_dict(slot) inp_slots = ch_slots.get('slots') existing_dict = dict([(slot['SlotNumber'], slot['SlotName']) for slot in blade_slots]) input_dict = dict([(str(slot['slot_number']), slot['slot_name']) for slot in inp_slots]) invalid_slot_number = set(input_dict.keys()) - set(existing_dict.keys()) if invalid_slot_number: module.fail_json( msg=INVALID_SLOT_NUMBERS.format(';'.join(invalid_slot_number))) if len(input_dict) < len(inp_slots): module.fail_json(msg=SLOT_NUM_DUP.format(chsvc_tag)) slot_dict_diff = {} slot_diff = recursive_diff(input_dict, existing_dict) if slot_diff and slot_diff[0]: diff = {} for k, v in (slot_diff[0]).items(): blade_dict[k]['new_name'] = input_dict.get(k) diff["{0}_{1}".format(chsvc_tag, k)] = blade_dict[k] slot_dict_diff.update(diff) return slot_dict_diff
def test_diff_between_dict_and_list(): from_dict = { 'CryptoValCred': { 'name': 'PKIX-CertAuthorityRootCA_ValCred', 'mAdminState': 'enabled', 'Certificate': {'value': 'cert_1'}, 'CertValidationMode': 'pkix', 'UseCRL': 'on', 'RequireCRL': 'off', 'CRLDPHandling': 'ignore', 'InitialPolicySet': '2.5.29.32.0', 'ExplicitPolicy': 'off', 'CheckDates': 'on' } } to_dict = { 'CryptoValCred': { 'CRLDPHandling': 'ignore', 'CertValidationMode': 'pkix', 'Certificate': [ {'value': 'cert_1'}, {'value': 'cert_2'}, {'value': 'cert_3'} ], 'CheckDates': 'on', 'ExplicitPolicy': 'off', 'InitialPolicySet': '2.5.29.32.0', 'RequireCRL': 'off', 'UseCRL': 'on', 'mAdminState': 'enabled', 'name': 'PKIX-CertAuthorityRootCA_ValCred' } } diff = recursive_diff(from_dict, to_dict) assert diff == ({'CryptoValCred': {'Certificate': {'value': 'cert_1'}}}, {'CryptoValCred': { 'Certificate': [{'value': 'cert_1'}, {'value': 'cert_2'}, {'value': 'cert_3'}]}})
def main(): module = setup_module_object() project_name = module.params['project_name'] rules = module.params['rules'] schedule = module.params['schedule'] harbor_iface = HarborInterface(module) changed = False project = harbor_iface.get_project_by_name(project_name) if not project: module.fail_json(msg="Project '%s' not found" % project_name) project_id = project["project_id"] if project["retention"] is None: trigger_references = {} harbor_iface.create_retention(project_id, rules, schedule, trigger_references) project = harbor_iface.get_project_by_name(project_name) changed = True trigger_references = project["retention"]["trigger"]["references"] existing_retention = clean_harbor_retention_rules(project["retention"]) requested_retention = harbor_iface.get_retention_definition( project_id, rules, schedule, trigger_references) if existing_retention != requested_retention: harbor_iface.update_retention(project["retention"]["id"], project_id, rules, schedule, trigger_references) project = harbor_iface.get_project_by_name(project_name) changed = True diff = recursive_diff(existing_retention, requested_retention) module.exit_json(changed=changed, project=project, diff=diff)
def set_snmp(meraki, org_id): payload = dict() if meraki.params['peer_ips']: if len(meraki.params['peer_ips']) > 7: if ';' not in meraki.params['peer_ips']: meraki.fail_json( msg='Peer IP addresses are semi-colon delimited.') if meraki.params['v2c_enabled'] is not None: payload = { 'v2cEnabled': meraki.params['v2c_enabled'], } if meraki.params['v3_enabled'] is True: if len(meraki.params['v3_auth_pass']) < 8 or len( meraki.params['v3_priv_pass']) < 8: meraki.fail_json( msg= 'v3_auth_pass and v3_priv_pass must both be at least 8 characters long.' ) if (meraki.params['v3_auth_mode'] is None or meraki.params['v3_auth_pass'] is None or meraki.params['v3_priv_mode'] is None or meraki.params['v3_priv_pass'] is None): meraki.fail_json( msg= 'v3_auth_mode, v3_auth_pass, v3_priv_mode, and v3_auth_pass are required' ) payload = { 'v3Enabled': meraki.params['v3_enabled'], 'v3AuthMode': meraki.params['v3_auth_mode'].upper(), 'v3AuthPass': meraki.params['v3_auth_pass'], 'v3PrivMode': meraki.params['v3_priv_mode'].upper(), 'v3PrivPass': meraki.params['v3_priv_pass'], } if meraki.params['peer_ips'] is not None: payload['peerIps'] = meraki.params['peer_ips'] elif meraki.params['v3_enabled'] is False: payload = {'v3Enabled': False} full_compare = snake_dict_to_camel_dict(payload) path = meraki.construct_path('create', org_id=org_id) snmp = get_snmp(meraki, org_id) ignored_parameters = [ 'v3AuthPass', 'v3PrivPass', 'hostname', 'port', 'v2CommunityString', 'v3User' ] if meraki.is_update_required(snmp, full_compare, optional_ignore=ignored_parameters): if meraki.module.check_mode is True: diff = recursive_diff(snmp, full_compare) snmp.update(payload) meraki.result['data'] = snmp meraki.result['changed'] = True meraki.result['diff'] = {'before': diff[0], 'after': diff[1]} meraki.exit_json(**meraki.result) r = meraki.request(path, method='PUT', payload=json.dumps(payload)) if meraki.status == 200: diff = recursive_diff(snmp, r) meraki.result['diff'] = {'before': diff[0], 'after': diff[1]} meraki.result['changed'] = True return r else: return snmp
def main(): # define the available arguments/parameters that a user can pass to # the module int_arg_spec = dict( wan_enabled=dict(type='str', choices=['enabled', 'disabled', 'not configured']), using_static_ip=dict(type='bool'), static_ip=dict(type='str'), static_gateway_ip=dict(type='str'), static_subnet_mask=dict(type='str'), static_dns=dict(type='list', element='str'), vlan=dict(type='int'), ) argument_spec = meraki_argument_spec() argument_spec.update( state=dict(type='str', choices=['absent', 'query', 'present'], default='query'), net_name=dict(type='str'), net_id=dict(type='str'), serial=dict(type='str', required=True), wan1=dict(type='dict', default=None, options=int_arg_spec, aliases=['mgmt1']), wan2=dict(type='dict', default=None, options=int_arg_spec, aliases=['mgmt2']), ) # the AnsibleModule object will be our abstraction working with Ansible # this includes instantiation, a couple of common attr would be the # args/params passed to the execution, as well as if the module # supports check mode module = AnsibleModule( argument_spec=argument_spec, supports_check_mode=True, ) meraki = MerakiModule(module, function='management_interface') meraki.params['follow_redirects'] = 'all' query_urls = { 'management_interface': '/networks/{net_id}/devices/{serial}/managementInterfaceSettings' } meraki.url_catalog['get_one'].update(query_urls) if meraki.params['net_id'] and meraki.params['net_name']: meraki.fail_json('net_id and net_name are mutually exclusive.') if meraki.params['state'] == 'present': interfaces = ('wan1', 'wan2') for interface in interfaces: if meraki.params[interface] is not None: if meraki.params[interface]['using_static_ip'] is True: if len(meraki.params[interface]['static_dns']) > 2: meraki.fail_json( "Maximum number of static DNS addresses is 2.") payload = dict() if meraki.params['state'] == 'present': interfaces = ('wan1', 'wan2') for interface in interfaces: if meraki.params[interface] is not None: wan_int = { 'wanEnabled': meraki.params[interface]['wan_enabled'], 'usingStaticIp': meraki.params[interface]['using_static_ip'], } if meraki.params[interface]['vlan'] is not None: wan_int['vlan'] = meraki.params[interface]['vlan'] if meraki.params[interface]['using_static_ip'] is True: wan_int['staticIp'] = meraki.params[interface]['static_ip'] wan_int['staticGatewayIp'] = meraki.params[interface][ 'static_gateway_ip'] wan_int['staticSubnetMask'] = meraki.params[interface][ 'static_subnet_mask'] wan_int['staticDns'] = meraki.params[interface][ 'static_dns'] payload[interface] = wan_int # manipulate or modify the state as needed (this is going to be the # part where your module will do what it needs to do) org_id = meraki.params['org_id'] if meraki.params['org_name']: org_id = meraki.get_org_id(meraki.params['org_name']) net_id = meraki.params['net_id'] if net_id is None: nets = meraki.get_nets(org_id=org_id) net_id = meraki.get_net_id(net_name=meraki.params['net_name'], data=nets) if meraki.params['state'] == 'query': path = meraki.construct_path( 'get_one', net_id=net_id, custom={'serial': meraki.params['serial']}) response = meraki.request(path, method='GET') if meraki.status == 200: meraki.result['data'] = response elif meraki.params['state'] == 'present': path = meraki.construct_path( 'get_one', net_id=net_id, custom={'serial': meraki.params['serial']}) # meraki.fail_json(path) original = meraki.request(path, method='GET') if meraki.is_update_required(original, payload): if meraki.check_mode is True: diff = recursive_diff(original, payload) original.update(payload) meraki.result['diff'] = {'before': diff[0], 'after': diff[1]} meraki.result['data'] = original meraki.result['changed'] = True meraki.exit_json(**meraki.result) response = meraki.request(path, method='PUT', payload=json.dumps(payload)) if meraki.status == 200: diff = recursive_diff(original, response) meraki.result['diff'] = {'before': diff[0], 'after': diff[1]} meraki.result['data'] = response meraki.result['changed'] = True else: meraki.result['data'] = original # in the event of a successful module execution, you will want to # simple AnsibleModule.exit_json(), passing the key/value results meraki.exit_json(**meraki.result)
def main(): # define the available arguments/parameters that a user can pass to # the module one_to_one_allowed_inbound_spec = dict( protocol=dict(type='str', choices=['tcp', 'udp', 'icmp-ping', 'any'], default='any'), destination_ports=dict(type='list', element='str'), allowed_ips=dict(type='list'), ) one_to_many_port_inbound_spec = dict( protocol=dict(type='str', choices=['tcp', 'udp']), name=dict(type='str'), local_ip=dict(type='str'), local_port=dict(type='str'), allowed_ips=dict(type='list'), public_port=dict(type='str'), ) one_to_one_spec = dict( name=dict(type='str'), public_ip=dict(type='str'), lan_ip=dict(type='str'), uplink=dict(type='str', choices=['internet1', 'internet2', 'both']), allowed_inbound=dict(type='list', element='dict', options=one_to_one_allowed_inbound_spec), ) one_to_many_spec = dict( public_ip=dict(type='str'), uplink=dict(type='str', choices=['internet1', 'internet2', 'both']), port_rules=dict(type='list', element='dict', options=one_to_many_port_inbound_spec), ) port_forwarding_spec = dict( name=dict(type='str'), lan_ip=dict(type='str'), uplink=dict(type='str', choices=['internet1', 'internet2', 'both']), protocol=dict(type='str', choices=['tcp', 'udp']), public_port=dict(type='int'), local_port=dict(type='int'), allowed_ips=dict(type='list'), ) argument_spec = meraki_argument_spec() argument_spec.update( net_id=dict(type='str'), net_name=dict(type='str', aliases=['name', 'network']), state=dict(type='str', choices=['present', 'query'], default='present'), subset=dict(type='list', choices=['1:1', '1:many', 'all', 'port_forwarding'], default='all'), one_to_one=dict(type='list', elements='dict', options=one_to_one_spec), one_to_many=dict(type='list', elements='dict', options=one_to_many_spec), port_forwarding=dict(type='list', elements='dict', options=port_forwarding_spec), ) # the AnsibleModule object will be our abstraction working with Ansible # this includes instantiation, a couple of common attr would be the # args/params passed to the execution, as well as if the module # supports check mode module = AnsibleModule( argument_spec=argument_spec, supports_check_mode=True, ) meraki = MerakiModule(module, function='nat') module.params['follow_redirects'] = 'all' one_to_one_payload = None one_to_many_payload = None port_forwarding_payload = None if meraki.params['state'] == 'present': if meraki.params['one_to_one'] is not None: rules = [] for i in meraki.params['one_to_one']: data = { 'name': i['name'], 'publicIp': i['public_ip'], 'uplink': i['uplink'], 'lanIp': i['lan_ip'], 'allowedInbound': construct_payload(i['allowed_inbound']) } for inbound in data['allowedInbound']: inbound['destinationPorts'] = list_int_to_str( inbound['destinationPorts']) rules.append(data) one_to_one_payload = {'rules': rules} if meraki.params['one_to_many'] is not None: rules = [] for i in meraki.params['one_to_many']: data = { 'publicIp': i['public_ip'], 'uplink': i['uplink'], } port_rules = [] for port_rule in i['port_rules']: rule = { 'name': port_rule['name'], 'protocol': port_rule['protocol'], 'publicPort': str(port_rule['public_port']), 'localIp': port_rule['local_ip'], 'localPort': str(port_rule['local_port']), 'allowedIps': port_rule['allowed_ips'], } port_rules.append(rule) data['portRules'] = port_rules rules.append(data) one_to_many_payload = {'rules': rules} if meraki.params['port_forwarding'] is not None: port_forwarding_payload = { 'rules': construct_payload(meraki.params['port_forwarding']) } for rule in port_forwarding_payload['rules']: rule['localPort'] = str(rule['localPort']) rule['publicPort'] = str(rule['publicPort']) onetomany_urls = {'nat': '/networks/{net_id}/oneToManyNatRules'} onetoone_urls = {'nat': '/networks/{net_id}/oneToOneNatRules'} port_forwarding_urls = {'nat': '/networks/{net_id}/portForwardingRules'} meraki.url_catalog['1:many'] = onetomany_urls meraki.url_catalog['1:1'] = onetoone_urls meraki.url_catalog['port_forwarding'] = port_forwarding_urls if meraki.params['net_name'] and meraki.params['net_id']: meraki.fail_json(msg='net_name and net_id are mutually exclusive') org_id = meraki.params['org_id'] if not org_id: org_id = meraki.get_org_id(meraki.params['org_name']) net_id = meraki.params['net_id'] if net_id is None: nets = meraki.get_nets(org_id=org_id) net_id = meraki.get_net_id(org_id, meraki.params['net_name'], data=nets) if meraki.params['state'] == 'query': if meraki.params['subset'][0] == 'all': path = meraki.construct_path('1:many', net_id=net_id) data = {'1:many': meraki.request(path, method='GET')} path = meraki.construct_path('1:1', net_id=net_id) data['1:1'] = meraki.request(path, method='GET') path = meraki.construct_path('port_forwarding', net_id=net_id) data['port_forwarding'] = meraki.request(path, method='GET') meraki.result['data'] = data else: for subset in meraki.params['subset']: path = meraki.construct_path(subset, net_id=net_id) data = {subset: meraki.request(path, method='GET')} try: meraki.result['data'][subset] = data except KeyError: meraki.result['data'] = {subset: data} elif meraki.params['state'] == 'present': meraki.result['data'] = dict() if one_to_one_payload is not None: path = meraki.construct_path('1:1', net_id=net_id) current = meraki.request(path, method='GET') if meraki.is_update_required(current, one_to_one_payload): if meraki.module.check_mode is True: diff = recursive_diff(current, one_to_one_payload) current.update(one_to_one_payload) if 'diff' not in meraki.result: meraki.result['diff'] = {'before': {}, 'after': {}} meraki.result['diff']['before'].update( {'one_to_one': diff[0]}) meraki.result['diff']['after'].update( {'one_to_one': diff[1]}) meraki.result['data'] = {'one_to_one': current} meraki.result['changed'] = True else: r = meraki.request(path, method='PUT', payload=json.dumps(one_to_one_payload)) if meraki.status == 200: diff = recursive_diff(current, one_to_one_payload) if 'diff' not in meraki.result: meraki.result['diff'] = {'before': {}, 'after': {}} meraki.result['diff']['before'].update( {'one_to_one': diff[0]}) meraki.result['diff']['after'].update( {'one_to_one': diff[1]}) meraki.result['data'] = {'one_to_one': r} meraki.result['changed'] = True else: meraki.result['data']['one_to_one'] = current if one_to_many_payload is not None: path = meraki.construct_path('1:many', net_id=net_id) current = meraki.request(path, method='GET') if meraki.is_update_required(current, one_to_many_payload): if meraki.module.check_mode is True: diff = recursive_diff(current, one_to_many_payload) current.update(one_to_many_payload) if 'diff' not in meraki.result: meraki.result['diff'] = {'before': {}, 'after': {}} meraki.result['diff']['before'].update( {'one_to_many': diff[0]}) meraki.result['diff']['after'].update( {'one_to_many': diff[1]}) meraki.result['data']['one_to_many'] = current meraki.result['changed'] = True else: r = meraki.request(path, method='PUT', payload=json.dumps(one_to_many_payload)) if meraki.status == 200: diff = recursive_diff(current, one_to_many_payload) if 'diff' not in meraki.result: meraki.result['diff'] = {'before': {}, 'after': {}} meraki.result['diff']['before'].update( {'one_to_many': diff[0]}) meraki.result['diff']['after'].update( {'one_to_many': diff[1]}) meraki.result['data'].update({'one_to_many': r}) meraki.result['changed'] = True else: meraki.result['data']['one_to_many'] = current if port_forwarding_payload is not None: path = meraki.construct_path('port_forwarding', net_id=net_id) current = meraki.request(path, method='GET') if meraki.is_update_required(current, port_forwarding_payload): if meraki.module.check_mode is True: diff = recursive_diff(current, port_forwarding_payload) current.update(port_forwarding_payload) if 'diff' not in meraki.result: meraki.result['diff'] = {'before': {}, 'after': {}} meraki.result['diff']['before'].update( {'port_forwarding': diff[0]}) meraki.result['diff']['after'].update( {'port_forwarding': diff[1]}) meraki.result['data']['port_forwarding'] = current meraki.result['changed'] = True else: r = meraki.request( path, method='PUT', payload=json.dumps(port_forwarding_payload)) if meraki.status == 200: if 'diff' not in meraki.result: meraki.result['diff'] = {'before': {}, 'after': {}} diff = recursive_diff(current, port_forwarding_payload) meraki.result['diff']['before'].update( {'port_forwarding': diff[0]}) meraki.result['diff']['after'].update( {'port_forwarding': diff[1]}) meraki.result['data'].update({'port_forwarding': r}) meraki.result['changed'] = True else: meraki.result['data']['port_forwarding'] = current # in the event of a successful module execution, you will want to # simple AnsibleModule.exit_json(), passing the key/value results meraki.exit_json(**meraki.result)
def get_device_slot_config(module, rest_obj): ids, tags = {}, {} dvc_list = [] for dvc in module.params.get('device_options'): sn = dvc.get('slot_name') id = dvc.get('device_id') st = dvc.get('device_service_tag') if id: ids[str(id)] = sn dvc_list.append(str(id)) else: tags[st] = sn dvc_list.append(st) duplicate = [x for i, x in enumerate(dvc_list) if i != dvc_list.index(x)] if duplicate: module.fail_json( msg=DEVICE_REPEATED.format((';'.join(set(duplicate))))) resp = rest_obj.get_all_items_with_pagination(DEVICE_URI) devices = resp.get('value') all_dvcs = {} invalid_slots = set() ident_map, name_map = {}, {} for dvc in devices: if not ids and not tags: break id = str(dvc.get('Id')) tag = dvc.get('Identifier') slot_cfg = dvc.get('SlotConfiguration') all_dvcs[tag] = slot_cfg if id in ids: if not slot_cfg or not slot_cfg.get("SlotNumber"): invalid_slots.add(id) else: ident_map[id] = tag name_map[id] = slot_cfg['SlotName'] slot_cfg['new_name'] = ids[id] slot_cfg['DeviceServiceTag'] = tag slot_cfg['DeviceId'] = id if tag in tags: if not slot_cfg or not slot_cfg.get("SlotNumber"): invalid_slots.add(tag) else: ident_map[tag] = tag name_map[tag] = slot_cfg['SlotName'] slot_cfg['new_name'] = tags[tag] slot_cfg['DeviceServiceTag'] = tag slot_cfg['DeviceId'] = id idf_list = list(ident_map.values()) duplicate = [x for i, x in enumerate(idf_list) if i != idf_list.index(x)] if duplicate: module.fail_json( msg=DEVICE_REPEATED.format((';'.join(set(duplicate))))) invalid_slots.update(set(ids.keys()) - set(ident_map.keys())) invalid_slots.update(set(tags.keys()) - set(ident_map.keys())) if invalid_slots: module.fail_json( msg=INVALID_SLOT_DEVICE.format(';'.join(invalid_slots))) slot_dict_diff = {} id_diff = recursive_diff(ids, name_map) if id_diff and id_diff[0]: diff = dict([(int(k), all_dvcs[ident_map[k]]) for k, v in (id_diff[0]).items()]) slot_dict_diff.update(diff) tag_diff = recursive_diff(tags, name_map) if tag_diff and tag_diff[0]: diff = dict([(ident_map[k], all_dvcs[k]) for k, v in (tag_diff[0]).items()]) slot_dict_diff.update(diff) if not slot_dict_diff: module.exit_json(msg=NO_CHANGES_MSG) if module.check_mode: module.exit_json(msg=CHANGES_FOUND, changed=True) return slot_dict_diff
def main(): # define the available arguments/parameters that a user can pass to # the module rules_arg_spec = dict( comment=dict(type='str'), policy=dict(type='str', choices=['allow', 'deny']), ip_version=dict(type='str', choices=['ipv4', 'ipv6', 'any']), protocol=dict(type='str', choices=['tcp', 'udp', 'any']), src_cidr=dict(type='str'), src_port=dict(type='str'), dst_cidr=dict(type='str'), dst_port=dict(type='str'), vlan=dict(type='str'), ) argument_spec = meraki_argument_spec() argument_spec.update( state=dict(type='str', choices=['absent', 'present', 'query'], default='query'), net_name=dict(type='str', aliases=['network']), net_id=dict(type='str'), rules=dict(type='list', elements='dict', options=rules_arg_spec), ) # the AnsibleModule object will be our abstraction working with Ansible # this includes instantiation, a couple of common attr would be the # args/params passed to the execution, as well as if the module # supports check mode module = AnsibleModule( argument_spec=argument_spec, supports_check_mode=True, ) meraki = MerakiModule(module, function='switch_access_list') meraki.params['follow_redirects'] = 'all' query_url = { 'switch_access_list': '/networks/{net_id}/switch/accessControlLists' } update_url = { 'switch_access_list': '/networks/{net_id}/switch/accessControlLists' } meraki.url_catalog['get_all'].update(query_url) meraki.url_catalog['update'] = update_url org_id = meraki.params['org_id'] if org_id is None: org_id = meraki.get_org_id(meraki.params['org_name']) net_id = meraki.params['net_id'] if net_id is None: nets = meraki.get_nets(org_id=org_id) net_id = meraki.get_net_id(net_name=meraki.params['net_name'], data=nets) if meraki.params['state'] == 'query': path = meraki.construct_path('get_all', net_id=net_id) result = meraki.request(path, method='GET') if meraki.status == 200: meraki.result['data'] = result elif meraki.params['state'] == 'present': path = meraki.construct_path('get_all', net_id=net_id) original = meraki.request(path, method='GET') payload = construct_payload(meraki.params) comparable = deepcopy(original) if len(comparable['rules']) > 1: del comparable['rules'][ len(comparable['rules']) - 1] # Delete the default rule for comparison else: del comparable['rules'][0] if meraki.is_update_required(comparable, payload): if meraki.check_mode is True: default_rule = original['rules'][len(original['rules']) - 1] payload['rules'].append(default_rule) new_rules = {'rules': payload['rules']} meraki.result['data'] = new_rules meraki.result['changed'] = True diff = recursive_diff(original, new_rules) meraki.result['diff'] = {'before': diff[0], 'after': diff[1]} meraki.exit_json(**meraki.result) path = meraki.construct_path('update', net_id=net_id) response = meraki.request(path, method='PUT', payload=json.dumps(payload)) if meraki.status == 200: diff = recursive_diff(original, payload) meraki.result['data'] = response meraki.result['changed'] = True meraki.result['diff'] = {'before': diff[0], 'after': diff[1]} else: meraki.result['data'] = original # in the event of a successful module execution, you will want to # simple AnsibleModule.exit_json(), passing the key/value results meraki.exit_json(**meraki.result)
def main(): # define the available arguments/parameters that a user can pass to # the module argument_spec = meraki_argument_spec() argument_spec.update( net_id=dict(type='str'), net_name=dict(type='str', aliases=['network']), state=dict(type='str', default='present', choices=['present', 'query']), allowed_urls=dict(type='list'), blocked_urls=dict(type='list'), blocked_categories=dict(type='list'), category_list_size=dict(type='str', choices=['top sites', 'full list']), subset=dict(type='str', choices=['categories', 'policy']), ) # the AnsibleModule object will be our abstraction working with Ansible # this includes instantiation, a couple of common attr would be the # args/params passed to the execution, as well as if the module # supports check mode module = AnsibleModule( argument_spec=argument_spec, supports_check_mode=True, ) meraki = MerakiModule(module, function='content_filtering') module.params['follow_redirects'] = 'all' category_urls = { 'content_filtering': '/networks/{net_id}/contentFiltering/categories' } policy_urls = {'content_filtering': '/networks/{net_id}/contentFiltering'} meraki.url_catalog['categories'] = category_urls meraki.url_catalog['policy'] = policy_urls if meraki.params['net_name'] and meraki.params['net_id']: meraki.fail_json(msg='net_name and net_id are mutually exclusive') # manipulate or modify the state as needed (this is going to be the # part where your module will do what it needs to do) org_id = meraki.params['org_id'] if not org_id: org_id = meraki.get_org_id(meraki.params['org_name']) net_id = meraki.params['net_id'] if net_id is None: nets = meraki.get_nets(org_id=org_id) net_id = meraki.get_net_id(org_id, meraki.params['net_name'], data=nets) if meraki.params['state'] == 'query': if meraki.params['subset']: if meraki.params['subset'] == 'categories': path = meraki.construct_path('categories', net_id=net_id) elif meraki.params['subset'] == 'policy': path = meraki.construct_path('policy', net_id=net_id) meraki.result['data'] = meraki.request(path, method='GET') else: response_data = { 'categories': None, 'policy': None, } path = meraki.construct_path('categories', net_id=net_id) response_data['categories'] = meraki.request(path, method='GET') path = meraki.construct_path('policy', net_id=net_id) response_data['policy'] = meraki.request(path, method='GET') meraki.result['data'] = response_data if module.params['state'] == 'present': payload = dict() if meraki.params['allowed_urls']: payload['allowedUrlPatterns'] = meraki.params['allowed_urls'] if meraki.params['blocked_urls']: payload['blockedUrlPatterns'] = meraki.params['blocked_urls'] if meraki.params['blocked_categories']: if len(meraki.params['blocked_categories'] ) == 0: # Corner case for resetting payload['blockedUrlCategories'] = [] else: category_path = meraki.construct_path('categories', net_id=net_id) categories = meraki.request(category_path, method='GET') payload['blockedUrlCategories'] = [] for category in meraki.params['blocked_categories']: payload['blockedUrlCategories'].append( get_category_dict(meraki, categories, category)) if meraki.params['category_list_size']: if meraki.params['category_list_size'].lower() == 'top sites': payload['urlCategoryListSize'] = "topSites" elif meraki.params['category_list_size'].lower() == 'full list': payload['urlCategoryListSize'] = "fullList" path = meraki.construct_path('policy', net_id=net_id) current = meraki.request(path, method='GET') proposed = current.copy() proposed.update(payload) if meraki.is_update_required(current, payload) is True: meraki.result['diff'] = dict() diff = recursive_diff(current, payload) meraki.result['diff']['before'] = diff[0] meraki.result['diff']['after'] = diff[1] if module.check_mode: current.update(payload) meraki.result['changed'] = True meraki.result['data'] = current meraki.exit_json(**meraki.result) response = meraki.request(path, method='PUT', payload=json.dumps(payload)) meraki.result['data'] = response meraki.result['changed'] = True else: meraki.result['data'] = current if module.check_mode: meraki.result['data'] = current meraki.exit_json(**meraki.result) meraki.result['data'] = current meraki.exit_json(**meraki.result) # in the event of a successful module execution, you will want to # simple AnsibleModule.exit_json(), passing the key/value results meraki.exit_json(**meraki.result)
def main(): # define the available arguments/parameters that a user can pass to # the module argument_spec = meraki_argument_spec() argument_spec.update( state=dict(type='str', choices=['present', 'query'], default='query'), net_name=dict(type='str'), net_id=dict(type='str'), broadcast_threshold=dict(type='int'), multicast_threshold=dict(type='int'), unknown_unicast_threshold=dict(type='int'), ) # the AnsibleModule object will be our abstraction working with Ansible # this includes instantiation, a couple of common attr would be the # args/params passed to the execution, as well as if the module # supports check mode module = AnsibleModule( argument_spec=argument_spec, supports_check_mode=True, ) meraki = MerakiModule(module, function='switch_storm_control') meraki.params['follow_redirects'] = 'all' query_urls = { 'switch_storm_control': '/networks/{net_id}/switch/stormControl' } update_url = { 'switch_storm_control': '/networks/{net_id}/switch/stormControl' } meraki.url_catalog['get_all'].update(query_urls) meraki.url_catalog['update'] = update_url payload = None org_id = meraki.params['org_id'] if not org_id: org_id = meraki.get_org_id(meraki.params['org_name']) net_id = meraki.params['net_id'] if net_id is None: nets = meraki.get_nets(org_id=org_id) net_id = meraki.get_net_id(net_name=meraki.params['net_name'], data=nets) # execute checks for argument completeness # manipulate or modify the state as needed (this is going to be the # part where your module will do what it needs to do) if meraki.params['state'] == 'query': path = meraki.construct_path('get_all', net_id=net_id) response = meraki.request(path, method='GET') if meraki.status == 200: meraki.result['data'] = response elif meraki.params['state'] == 'present': path = meraki.construct_path('get_all', net_id=net_id) original = meraki.request(path, method='GET') payload = construct_payload(meraki.params) if meraki.is_update_required(original, payload) is True: diff = recursive_diff(original, payload) if meraki.check_mode is True: original.update(payload) meraki.result['data'] = original meraki.result['changed'] = True meraki.result['diff'] = {'before': diff[0], 'after': diff[1]} meraki.exit_json(**meraki.result) path = meraki.construct_path('update', net_id=net_id) response = meraki.request(path, method='PUT', payload=json.dumps(payload)) if meraki.status == 200: meraki.result['diff'] = {'before': diff[0], 'after': diff[1]} meraki.result['data'] = response meraki.result['changed'] = True else: meraki.result['data'] = original # in the event of a successful module execution, you will want to # simple AnsibleModule.exit_json(), passing the key/value results meraki.exit_json(**meraki.result)
def main(): # define the available arguments/parameters that a user can pass to # the module server_arg_spec = dict( host=dict(type='str'), port=dict(type='int', default="514"), roles=dict(type='list', choices=[ 'Wireless Event log', 'Appliance event log', 'Switch event log', 'Air Marshal events', 'Flows', 'URLs', 'IDS alerts', 'Security events', ]), ) argument_spec = meraki_argument_spec() argument_spec.update( net_id=dict(type='str'), servers=dict(type='list', element='dict', options=server_arg_spec), state=dict(type='str', choices=['present', 'query'], default='present'), net_name=dict(type='str', aliases=['name', 'network']), ) # the AnsibleModule object will be our abstraction working with Ansible # this includes instantiation, a couple of common attr would be the # args/params passed to the execution, as well as if the module # supports check mode module = AnsibleModule( argument_spec=argument_spec, supports_check_mode=True, ) meraki = MerakiModule(module, function='syslog') module.params['follow_redirects'] = 'all' payload = None syslog_urls = {'syslog': '/networks/{net_id}/syslogServers'} meraki.url_catalog['query_update'] = syslog_urls if not meraki.params['org_name'] and not meraki.params['org_id']: meraki.fail_json(msg='org_name or org_id parameters are required') if meraki.params['state'] != 'query': if not meraki.params['net_name'] and not meraki.params['net_id']: meraki.fail_json( msg= 'net_name or net_id is required for present or absent states') if meraki.params['net_name'] and meraki.params['net_id']: meraki.fail_json(msg='net_name and net_id are mutually exclusive') # if the user is working with this module in only check mode we do not # want to make any changes to the environment, just return the current # state with no modifications # manipulate or modify the state as needed (this is going to be the # part where your module will do what it needs to do) org_id = meraki.params['org_id'] if not org_id: org_id = meraki.get_org_id(meraki.params['org_name']) net_id = meraki.params['net_id'] if net_id is None: nets = meraki.get_nets(org_id=org_id) net_id = meraki.get_net_id(net_name=meraki.params['net_name'], data=nets) if meraki.params['state'] == 'query': path = meraki.construct_path('query_update', net_id=net_id) r = meraki.request(path, method='GET') if meraki.status == 200: meraki.result['data'] = r elif meraki.params['state'] == 'present': # Construct payload payload = dict() payload['servers'] = meraki.params['servers'] # Convert port numbers to string for idempotency checks for server in payload['servers']: if server['port']: server['port'] = str(server['port']) path = meraki.construct_path('query_update', net_id=net_id) r = meraki.request(path, method='GET') if meraki.status == 200: original = dict() original['servers'] = r if meraki.is_update_required(original, payload): if meraki.module.check_mode is True: diff = recursive_diff(original, payload) original.update(payload) meraki.result['diff'] = {'before': diff[0], 'after': diff[1]} meraki.result['data'] = original meraki.result['changed'] = True meraki.exit_json(**meraki.result) path = meraki.construct_path('query_update', net_id=net_id) r = meraki.request(path, method='PUT', payload=json.dumps(payload)) if meraki.status == 200: meraki.result['data'] = r meraki.result['changed'] = True else: if meraki.module.check_mode is True: meraki.result['data'] = original meraki.exit_json(**meraki.result) meraki.result['data'] = original # in the event of a successful module execution, you will want to # simple AnsibleModule.exit_json(), passing the key/value results meraki.exit_json(**meraki.result)
def main(): # define the available arguments/parameters that a user can pass to # the module fixed_ip_arg_spec = dict( mac=dict(type='str'), ip=dict(type='str'), name=dict(type='str'), ) reserved_ip_arg_spec = dict( start=dict(type='str'), end=dict(type='str'), comment=dict(type='str'), ) argument_spec = meraki_argument_spec() argument_spec.update( state=dict(type='str', choices=['absent', 'present', 'query'], default='query'), net_name=dict(type='str', aliases=['network']), net_id=dict(type='str'), vlan_id=dict(type='int'), name=dict(type='str', aliases=['vlan_name']), subnet=dict(type='str'), appliance_ip=dict(type='str'), fixed_ip_assignments=dict(type='list', default=None, elements='dict', options=fixed_ip_arg_spec), reserved_ip_range=dict(type='list', default=None, elements='dict', options=reserved_ip_arg_spec), vpn_nat_subnet=dict(type='str'), dns_nameservers=dict(type='str'), ) # seed the result dict in the object # we primarily care about changed and state # change is if this module effectively modified the target # state will include any data that you want your module to pass back # for consumption, for example, in a subsequent task result = dict(changed=False, ) # the AnsibleModule object will be our abstraction working with Ansible # this includes instantiation, a couple of common attr would be the # args/params passed to the execution, as well as if the module # supports check mode module = AnsibleModule( argument_spec=argument_spec, supports_check_mode=True, ) meraki = MerakiModule(module, function='vlan') meraki.params['follow_redirects'] = 'all' query_urls = {'vlan': '/networks/{net_id}/vlans'} query_url = {'vlan': '/networks/{net_id}/vlans/{vlan_id}'} create_url = {'vlan': '/networks/{net_id}/vlans'} update_url = {'vlan': '/networks/{net_id}/vlans/'} delete_url = {'vlan': '/networks/{net_id}/vlans/'} meraki.url_catalog['get_all'].update(query_urls) meraki.url_catalog['get_one'].update(query_url) meraki.url_catalog['create'] = create_url meraki.url_catalog['update'] = update_url meraki.url_catalog['delete'] = delete_url payload = None org_id = meraki.params['org_id'] if org_id is None: org_id = meraki.get_org_id(meraki.params['org_name']) net_id = meraki.params['net_id'] if net_id is None: nets = meraki.get_nets(org_id=org_id) net_id = meraki.get_net_id(net_name=meraki.params['net_name'], data=nets) if meraki.params['state'] == 'query': if not meraki.params['vlan_id']: meraki.result['data'] = get_vlans(meraki, net_id) else: path = meraki.construct_path( 'get_one', net_id=net_id, custom={'vlan_id': meraki.params['vlan_id']}) response = meraki.request(path, method='GET') meraki.result['data'] = response elif meraki.params['state'] == 'present': payload = { 'id': meraki.params['vlan_id'], 'name': meraki.params['name'], 'subnet': meraki.params['subnet'], 'applianceIp': meraki.params['appliance_ip'], } if is_vlan_valid(meraki, net_id, meraki.params['vlan_id']) is False: # Create new VLAN if meraki.module.check_mode is True: meraki.result['data'] = payload meraki.result['changed'] = True meraki.exit_json(**meraki.result) path = meraki.construct_path('create', net_id=net_id) response = meraki.request(path, method='POST', payload=json.dumps(payload)) meraki.result['changed'] = True meraki.result['data'] = response else: # Update existing VLAN path = meraki.construct_path( 'get_one', net_id=net_id, custom={'vlan_id': meraki.params['vlan_id']}) original = meraki.request(path, method='GET') if meraki.params['dns_nameservers']: if meraki.params['dns_nameservers'] not in ('opendns', 'google_dns', 'upstream_dns'): payload['dnsNameservers'] = format_dns( meraki.params['dns_nameservers']) else: payload['dnsNameservers'] = meraki.params[ 'dns_nameservers'] if meraki.params['fixed_ip_assignments']: payload['fixedIpAssignments'] = fixed_ip_factory( meraki, meraki.params['fixed_ip_assignments']) if meraki.params['reserved_ip_range']: payload['reservedIpRanges'] = meraki.params[ 'reserved_ip_range'] if meraki.params['vpn_nat_subnet']: payload['vpnNatSubnet'] = meraki.params['vpn_nat_subnet'] ignored = ['networkId'] if meraki.is_update_required(original, payload, optional_ignore=ignored): meraki.result['diff'] = dict() diff = recursive_diff(original, payload) meraki.result['diff']['before'] = diff[0] meraki.result['diff']['after'] = diff[1] if meraki.module.check_mode is True: original.update(payload) meraki.result['changed'] = True meraki.result['data'] = original meraki.exit_json(**meraki.result) path = meraki.construct_path('update', net_id=net_id) + str( meraki.params['vlan_id']) response = meraki.request(path, method='PUT', payload=json.dumps(payload)) meraki.result['changed'] = True meraki.result['data'] = response else: if meraki.module.check_mode is True: meraki.result['data'] = original meraki.exit_json(**meraki.result) meraki.result['data'] = original elif meraki.params['state'] == 'absent': if is_vlan_valid(meraki, net_id, meraki.params['vlan_id']): if meraki.module.check_mode is True: meraki.result['data'] = {} meraki.result['changed'] = True meraki.exit_json(**meraki.result) path = meraki.construct_path('delete', net_id=net_id) + str( meraki.params['vlan_id']) response = meraki.request(path, 'DELETE') meraki.result['changed'] = True meraki.result['data'] = response # in the event of a successful module execution, you will want to # simple AnsibleModule.exit_json(), passing the key/value results meraki.exit_json(**meraki.result)
def main(): # define the available arguments/parameters that a user can pass to # the module argument_spec = meraki_argument_spec() argument_spec.update( state=dict(type='str', choices=['absent', 'present', 'query'], default='query'), net_name=dict(type='str', aliases=['network']), net_id=dict(type='str'), name=dict(type='str'), url=dict(type='str'), shared_secret=dict(type='str', no_log=True), webhook_id=dict(type='str'), test=dict(type='str', choices=['test', 'status']), test_id=dict(type='str'), ) # seed the result dict in the object # we primarily care about changed and state # change is if this module effectively modified the target # state will include any data that you want your module to pass back # for consumption, for example, in a subsequent task result = dict(changed=False, ) # the AnsibleModule object will be our abstraction working with Ansible # this includes instantiation, a couple of common attr would be the # args/params passed to the execution, as well as if the module # supports check mode module = AnsibleModule( argument_spec=argument_spec, supports_check_mode=True, ) meraki = MerakiModule(module, function='webhooks') meraki.params['follow_redirects'] = 'all' query_url = {'webhooks': '/networks/{net_id}/httpServers'} query_one_url = {'webhooks': '/networks/{net_id}/httpServers/{hookid}'} create_url = {'webhooks': '/networks/{net_id}/httpServers'} update_url = {'webhooks': '/networks/{net_id}/httpServers/{hookid}'} delete_url = {'webhooks': '/networks/{net_id}/httpServers/{hookid}'} test_url = {'webhooks': '/networks/{net_id}/httpServers/webhookTests'} test_status_url = { 'webhooks': '/networks/{net_id}/httpServers/webhookTests/{testid}' } meraki.url_catalog['get_all'].update(query_url) meraki.url_catalog['get_one'].update(query_one_url) meraki.url_catalog['create'] = create_url meraki.url_catalog['update'] = update_url meraki.url_catalog['delete'] = delete_url meraki.url_catalog['test'] = test_url meraki.url_catalog['test_status'] = test_status_url org_id = meraki.params['org_id'] if org_id is None: org_id = meraki.get_org_id(meraki.params['org_name']) net_id = meraki.params['net_id'] if net_id is None: nets = meraki.get_nets(org_id=org_id) net_id = meraki.get_net_id(net_name=meraki.params['net_name'], data=nets) webhook_id = meraki.params['webhook_id'] if webhook_id is None and meraki.params['name']: webhooks = get_all_webhooks(meraki, net_id) webhook_id = get_webhook_id(meraki.params['name'], webhooks) if meraki.params['state'] == 'present' and meraki.params['test'] is None: payload = { 'name': meraki.params['name'], 'url': meraki.params['url'], 'sharedSecret': meraki.params['shared_secret'] } if meraki.params['state'] == 'query': if webhook_id is not None: # Query a single webhook path = meraki.construct_path('get_one', net_id=net_id, custom={'hookid': webhook_id}) response = meraki.request(path, method='GET') if meraki.status == 200: meraki.result['data'] = response else: path = meraki.construct_path('get_all', net_id=net_id) response = meraki.request(path, method='GET') if meraki.status == 200: meraki.result['data'] = response elif meraki.params['state'] == 'present': if meraki.params['test'] == 'test': payload = {'url': meraki.params['url']} path = meraki.construct_path('test', net_id=net_id) response = meraki.request(path, method='POST', payload=json.dumps(payload)) if meraki.status == 200: meraki.result['data'] = response meraki.exit_json(**meraki.result) elif meraki.params['test'] == 'status': if meraki.params['test_id'] is None: meraki.fail_json( "test_id is required when querying test status.") path = meraki.construct_path( 'test_status', net_id=net_id, custom={'testid': meraki.params['test_id']}) response = meraki.request(path, method='GET') if meraki.status == 200: meraki.result['data'] = response meraki.exit_json(**meraki.result) if webhook_id is None: # Make sure it is downloaded if webhooks is None: wehooks = get_all_webhooks(meraki, net_id) webhook_id = get_webhook_id(meraki.params['name'], webhooks) if webhook_id is None: # Test to see if it needs to be created if meraki.check_mode is True: meraki.result['data'] = payload meraki.result['data']['networkId'] = net_id meraki.result['changed'] = True meraki.exit_json(**meraki.result) path = meraki.construct_path('create', net_id=net_id) response = meraki.request(path, method='POST', payload=json.dumps(payload)) if meraki.status == 201: meraki.result['data'] = response meraki.result['changed'] = True else: # Need to update path = meraki.construct_path('get_one', net_id=net_id, custom={'hookid': webhook_id}) original = meraki.request(path, method='GET') if meraki.is_update_required(original, payload): if meraki.check_mode is True: diff = recursive_diff(original, payload) original.update(payload) meraki.result['diff'] = { 'before': diff[0], 'after': diff[1] } meraki.result['data'] = original meraki.result['changed'] = True meraki.exit_json(**meraki.result) path = meraki.construct_path('update', net_id=net_id, custom={'hookid': webhook_id}) response = meraki.request(path, method='PUT', payload=json.dumps(payload)) if meraki.status == 200: meraki.result['data'] = response meraki.result['changed'] = True else: meraki.result['data'] = original elif meraki.params['state'] == 'absent': if webhook_id is None: # Make sure it is downloaded if webhooks is None: webhooks = get_all_webhooks(meraki, net_id) webhook_id = get_webhook_id(meraki.params['name'], webhooks) if webhook_id is None: meraki.fail_json(msg="There is no webhook with the name {0}". format(meraki.params['name'])) if webhook_id: # Test to see if it exists if meraki.module.check_mode is True: meraki.result['data'] = None meraki.result['changed'] = True meraki.exit_json(**meraki.result) path = meraki.construct_path('delete', net_id=net_id, custom={'hookid': webhook_id}) response = meraki.request(path, method='DELETE') if meraki.status == 204: meraki.result['data'] = response meraki.result['changed'] = True # in the event of a successful module execution, you will want to # simple AnsibleModule.exit_json(), passing the key/value results meraki.exit_json(**meraki.result)
def main(): # define the available arguments/parameters that a user can pass to # the module urls_arg_spec = dict( url=dict(type='str'), comment=dict(type='str'), ) files_arg_spec = dict( sha256=dict(type='str', aliases=['hash']), comment=dict(type='str'), ) argument_spec = meraki_argument_spec() argument_spec.update( state=dict(type='str', choices=['absent', 'present', 'query'], default='query'), net_name=dict(type='str', aliases=['network']), net_id=dict(type='str'), mode=dict(type='str', choices=['enabled', 'disabled']), allowed_urls=dict(type='list', default=None, elements='dict', options=urls_arg_spec), allowed_files=dict(type='list', default=None, elements='dict', options=files_arg_spec), ) # seed the result dict in the object # we primarily care about changed and state # change is if this module effectively modified the target # state will include any data that you want your module to pass back # for consumption, for example, in a subsequent task result = dict(changed=False, ) # the AnsibleModule object will be our abstraction working with Ansible # this includes instantiation, a couple of common attr would be the # args/params passed to the execution, as well as if the module # supports check mode module = AnsibleModule( argument_spec=argument_spec, supports_check_mode=True, ) meraki = MerakiModule(module, function='malware') meraki.params['follow_redirects'] = 'all' query_url = {'malware': '/networks/{net_id}/security/malwareSettings'} update_url = {'malware': '/networks/{net_id}/security/malwareSettings'} meraki.url_catalog['get_one'].update(query_url) meraki.url_catalog['update'] = update_url org_id = meraki.params['org_id'] if org_id is None: org_id = meraki.get_org_id(meraki.params['org_name']) net_id = meraki.params['net_id'] if net_id is None: nets = meraki.get_nets(org_id=org_id) net_id = meraki.get_net_id(net_name=meraki.params['net_name'], data=nets) # Check for argument completeness if meraki.params['state'] == 'present': if meraki.params['allowed_files'] is not None or meraki.params[ 'allowed_urls'] is not None: if meraki.params['mode'] is None: meraki.fail_json( msg= "mode must be set when allowed_files or allowed_urls is set." ) # Assemble payload if meraki.params['state'] == 'present': payload = dict() if meraki.params['mode'] is not None: payload['mode'] = meraki.params['mode'] if meraki.params['allowed_urls'] is not None: payload['allowedUrls'] = meraki.params['allowed_urls'] if meraki.params['allowed_files'] is not None: payload['allowedFiles'] = meraki.params['allowed_files'] if meraki.params['state'] == 'query': path = meraki.construct_path('get_one', net_id=net_id) data = meraki.request(path, method='GET') if meraki.status == 200: meraki.result['data'] = data elif meraki.params['state'] == 'present': path = meraki.construct_path('get_one', net_id=net_id) original = meraki.request(path, method='GET') if meraki.is_update_required(original, payload): if meraki.module.check_mode is True: diff = recursive_diff(original, payload) original.update(payload) meraki.result['diff'] = { 'before': diff[0], 'after': diff[1], } meraki.result['data'] = original meraki.result['changed'] = True meraki.exit_json(**meraki.result) path = meraki.construct_path('update', net_id=net_id) data = meraki.request(path, method='PUT', payload=json.dumps(payload)) if meraki.status == 200: diff = recursive_diff(original, payload) meraki.result['diff'] = { 'before': diff[0], 'after': diff[1], } meraki.result['data'] = data meraki.result['changed'] = True else: meraki.result['data'] = original # in the event of a successful module execution, you will want to # simple AnsibleModule.exit_json(), passing the key/value results meraki.exit_json(**meraki.result)
def main(): # define the available arguments/parameters that a user can pass to # the module application_arg_spec = dict(id=dict(type='str'), name=dict(type='str'), ) rule_arg_spec = dict(policy=dict(type='str', choices=['deny'], default='deny'), type=dict(type='str', choices=['application', 'application_category', 'blacklisted_countries', 'host', 'ip_range', 'port', 'whitelisted_countries']), ip_range=dict(type='str'), application=dict(type='dict', default=None, options=application_arg_spec), host=dict(type='str'), port=dict(type='str'), countries=dict(type='list'), ) argument_spec = meraki_argument_spec() argument_spec.update(state=dict(type='str', choices=['present', 'query'], default='present'), net_name=dict(type='str'), net_id=dict(type='str'), rules=dict(type='list', default=None, elements='dict', options=rule_arg_spec), categories=dict(type='bool'), ) # seed the result dict in the object # we primarily care about changed and state # change is if this module effectively modified the target # state will include any data that you want your module to pass back # for consumption, for example, in a subsequent task result = dict( changed=False, ) # the AnsibleModule object will be our abstraction working with Ansible # this includes instantiation, a couple of common attr would be the # args/params passed to the execution, as well as if the module # supports check mode module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=True, ) meraki = MerakiModule(module, function='mx_l7_firewall') # check for argument completeness if meraki.params['rules']: for rule in meraki.params['rules']: if rule['type'] == 'application' and rule['application'] is None: meraki.fail_json(msg="application argument is required when type is application.") elif rule['type'] == 'application_category' and rule['application'] is None: meraki.fail_json(msg="application argument is required when type is application_category.") elif rule['type'] == 'blacklisted_countries' and rule['countries'] is None: meraki.fail_json(msg="countries argument is required when type is blacklisted_countries.") elif rule['type'] == 'host' and rule['host'] is None: meraki.fail_json(msg="host argument is required when type is host.") elif rule['type'] == 'port' and rule['port'] is None: meraki.fail_json(msg="port argument is required when type is port.") elif rule['type'] == 'whitelisted_countries' and rule['countries'] is None: meraki.fail_json(msg="countries argument is required when type is whitelisted_countries.") meraki.params['follow_redirects'] = 'all' query_urls = {'mx_l7_firewall': '/networks/{net_id}/l7FirewallRules/'} query_category_urls = {'mx_l7_firewall': '/networks/{net_id}/l7FirewallRules/applicationCategories'} update_urls = {'mx_l7_firewall': '/networks/{net_id}/l7FirewallRules/'} meraki.url_catalog['get_all'].update(query_urls) meraki.url_catalog['get_categories'] = (query_category_urls) meraki.url_catalog['update'] = update_urls payload = None # manipulate or modify the state as needed (this is going to be the # part where your module will do what it needs to do) org_id = meraki.params['org_id'] orgs = None if org_id is None: orgs = meraki.get_orgs() for org in orgs: if org['name'] == meraki.params['org_name']: org_id = org['id'] net_id = meraki.params['net_id'] if net_id is None: if orgs is None: orgs = meraki.get_orgs() net_id = meraki.get_net_id(net_name=meraki.params['net_name'], data=meraki.get_nets(org_id=org_id)) if meraki.params['state'] == 'query': if meraki.params['categories'] is True: # Output only applications meraki.result['data'] = get_applications(meraki, net_id) else: meraki.result['data'] = restructure_response(get_rules(meraki, net_id)) elif meraki.params['state'] == 'present': rules = get_rules(meraki, net_id) path = meraki.construct_path('get_all', net_id=net_id) if meraki.params['rules']: payload = {'rules': []} for rule in meraki.params['rules']: payload['rules'].append(assemble_payload(meraki, net_id, rule)) else: payload = dict() ''' The rename_* functions are needed because the key is id and is_update_required() by default ignores id. ''' rules = rename_id_to_appid(rules) payload = rename_id_to_appid(payload) if meraki.is_update_required(rules, payload): rules = rename_appid_to_id(rules) payload = rename_appid_to_id(payload) if meraki.module.check_mode is True: response = restructure_response(payload) diff = recursive_diff(restructure_response(rules), response) meraki.result['diff'] = {'before': diff[0], 'after': diff[1], } meraki.result['data'] = response meraki.result['changed'] = True meraki.exit_json(**meraki.result) response = meraki.request(path, method='PUT', payload=json.dumps(payload)) response = restructure_response(response) if meraki.status == 200: diff = recursive_diff(restructure_response(rules), response) meraki.result['diff'] = {'before': diff[0], 'after': diff[1], } meraki.result['data'] = response meraki.result['changed'] = True else: rules = rename_appid_to_id(rules) payload = rename_appid_to_id(payload) if meraki.module.check_mode is True: meraki.result['data'] = rules meraki.result['changed'] = False meraki.exit_json(**meraki.result) meraki.result['data'] = payload # in the event of a successful module execution, you will want to # simple AnsibleModule.exit_json(), passing the key/value results meraki.exit_json(**meraki.result)
def main(): # define the available arguments/parameters that a user can pass to # the module argument_spec = meraki_argument_spec() argument_spec.update( net_id=dict(type='str'), net_name=dict(type='str', aliases=['network']), state=dict(type='str', default='present', choices=['query', 'present']), service=dict(type='str', default=None, choices=['ICMP', 'SNMP', 'web']), access=dict(type='str', choices=['blocked', 'restricted', 'unrestricted']), allowed_ips=dict(type='list', elements='str'), ) mutually_exclusive = [('net_name', 'net_id')] # the AnsibleModule object will be our abstraction working with Ansible # this includes instantiation, a couple of common attr would be the # args/params passed to the execution, as well as if the module # supports check mode module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=True, mutually_exclusive=mutually_exclusive) meraki = MerakiModule(module, function='firewalled_services') module.params['follow_redirects'] = 'all' net_services_urls = { 'firewalled_services': '/networks/{net_id}/firewalledServices' } services_urls = { 'firewalled_services': '/networks/{net_id}/firewalledServices/{service}' } meraki.url_catalog['network_services'] = net_services_urls meraki.url_catalog['service'] = services_urls # manipulate or modify the state as needed (this is going to be the # part where your module will do what it needs to do) org_id = meraki.params['org_id'] if not org_id: org_id = meraki.get_org_id(meraki.params['org_name']) net_id = meraki.params['net_id'] if net_id is None: nets = meraki.get_nets(org_id=org_id) net_id = meraki.get_net_id(org_id, meraki.params['net_name'], data=nets) if meraki.params['state'] == 'present': if meraki.params['access'] != 'restricted' and meraki.params[ 'allowed_ips'] is not None: meraki.fail_json( msg="allowed_ips is only allowed when access is restricted.") payload = {'access': meraki.params['access']} if meraki.params['access'] == 'restricted': payload['allowedIps'] = meraki.params['allowed_ips'] if meraki.params['state'] == 'query': if meraki.params['service'] is None: path = meraki.construct_path('network_services', net_id=net_id) response = meraki.request(path, method='GET') meraki.result['data'] = response meraki.exit_json(**meraki.result) else: path = meraki.construct_path( 'service', net_id=net_id, custom={'service': meraki.params['service']}) response = meraki.request(path, method='GET') meraki.result['data'] = response meraki.exit_json(**meraki.result) elif meraki.params['state'] == 'present': path = meraki.construct_path( 'service', net_id=net_id, custom={'service': meraki.params['service']}) original = meraki.request(path, method='GET') if meraki.is_update_required(original, payload, optional_ignore=['service']): if meraki.check_mode is True: diff_payload = { 'service': meraki.params['service'] } # Need to add service as it's not in payload diff_payload.update(payload) diff = recursive_diff(original, diff_payload) original.update(payload) meraki.result['diff'] = {'before': diff[0], 'after': diff[1]} meraki.result['data'] = original meraki.result['changed'] = True meraki.exit_json(**meraki.result) path = meraki.construct_path( 'service', net_id=net_id, custom={'service': meraki.params['service']}) response = meraki.request(path, method='PUT', payload=json.dumps(payload)) if meraki.status == 200: diff = recursive_diff(original, response) meraki.result['diff'] = {'before': diff[0], 'after': diff[1]} meraki.result['data'] = response meraki.result['changed'] = True else: meraki.result['data'] = original # in the event of a successful module execution, you will want to # simple AnsibleModule.exit_json(), passing the key/value results meraki.exit_json(**meraki.result)