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']), 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']), ) # 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 = None 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 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 fw_rules = dict(policy=dict(type='str', choices=['allow', 'deny']), protocol=dict(type='str', choices=['tcp', 'udp', 'icmp', 'any']), dest_port=dict(type='str'), dest_cidr=dict(type='str'), comment=dict(type='str'), ) argument_spec = meraki_argument_spec() argument_spec.update(state=dict(type='str', choices=['present', 'query'], default='present'), net_name=dict(type='str'), net_id=dict(type='str'), number=dict(type='str', aliases=['ssid_number']), ssid_name=dict(type='str', aliases=['ssid']), rules=dict(type='list', default=None, elements='dict', options=fw_rules), allow_lan_access=dict(type='bool', default=True), ) # seed the result dict in the object # we primarily care about changed and state # change is if this module effectively modified the target # state will include any data that you want your module to pass back # for consumption, for example, in a subsequent task result = dict( changed=False, ) # the AnsibleModule object will be our abstraction working with Ansible # this includes instantiation, a couple of common attr would be the # args/params passed to the execution, as well as if the module # supports check mode module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=True, ) meraki = MerakiModule(module, function='mr_l3_firewall') meraki.params['follow_redirects'] = 'all' query_urls = {'mr_l3_firewall': '/networks/{net_id}/ssids/'} update_urls = {'mr_l3_firewall': '/networks/{net_id}/ssids/'} meraki.url_catalog['get_all'].update(query_urls) meraki.url_catalog['update'] = update_urls payload = None # if the user is working with this module in only check mode we do not # want to make any changes to the environment, just return the current # state with no modifications # FIXME: Work with Meraki so they can implement a check mode if module.check_mode: meraki.exit_json(**meraki.result) # execute checks for argument completeness # manipulate or modify the state as needed (this is going to be the # part where your module will do what it needs to do) org_id = meraki.params['org_id'] orgs = None if org_id is None: orgs = meraki.get_orgs() for org in orgs: if org['name'] == meraki.params['org_name']: org_id = org['id'] net_id = meraki.params['net_id'] if net_id is None: if orgs is None: orgs = meraki.get_orgs() net_id = meraki.get_net_id(net_name=meraki.params['net_name'], data=meraki.get_nets(org_id=org_id)) number = meraki.params['number'] if meraki.params['ssid_name']: number = get_ssid_number(meraki.params['ssid_name'], get_ssids(meraki, net_id)) if meraki.params['state'] == 'query': meraki.result['data'] = get_rules(meraki, net_id, number) elif meraki.params['state'] == 'present': rules = get_rules(meraki, net_id, number) path = meraki.construct_path('get_all', net_id=net_id) path = path + number + '/l3FirewallRules' if meraki.params['rules']: payload = assemble_payload(meraki) else: payload = dict() update = False try: if len(rules) != len(payload['rules']): # Quick and simple check to avoid more processing update = True if update is False: for r in range(len(rules) - 2): if meraki.is_update_required(rules[r], payload[r]) is True: update = True except KeyError: pass if rules[len(rules) - 2] != meraki.params['allow_lan_access']: update = True if update is True: payload['allowLanAccess'] = meraki.params['allow_lan_access'] response = meraki.request(path, method='PUT', payload=json.dumps(payload)) if meraki.status == 200: meraki.result['data'] = response meraki.result['changed'] = True # 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 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 argument_spec = meraki_argument_spec() argument_spec.update( state=dict(type='str', choices=['absent', 'present', 'query'], default='query'), net_name=dict(type='str', aliases=['network']), net_id=dict(type='str'), serial=dict(type='str'), serial_uplink=dict(type='str'), serial_lldp_cdp=dict(type='str'), lldp_cdp_timespan=dict(type='int'), hostname=dict(type='str', aliases=['name']), model=dict(type='str'), tags=dict(type='str'), lat=dict(type='float', aliases=['latitude']), lng=dict(type='float', aliases=['longitude']), address=dict(type='str'), move_map_marker=dict(type='bool'), note=dict(type='str'), ) # seed the result dict in the object # we primarily care about changed and state # change is if this module effectively modified the target # state will include any data that you want your module to pass back # for consumption, for example, in a subsequent task result = dict(changed=False, ) # the AnsibleModule object will be our abstraction working with Ansible # this includes instantiation, a couple of common attr would be the # args/params passed to the execution, as well as if the module # supports check mode module = AnsibleModule( argument_spec=argument_spec, supports_check_mode=True, ) meraki = MerakiModule(module, function='device') if meraki.params[ 'serial_lldp_cdp'] and not meraki.params['lldp_cdp_timespan']: meraki.fail_json( msg= 'lldp_cdp_timespan is required when querying LLDP and CDP information' ) if meraki.params['net_name'] and meraki.params['net_id']: meraki.fail_json(msg='net_name and net_id are mutually exclusive') meraki.params['follow_redirects'] = 'all' query_urls = {'device': '/networks/{net_id}/devices'} query_org_urls = {'device': '/organizations/{org_id}/inventory'} query_device_urls = {'device': '/networks/{net_id}/devices/'} claim_device_urls = {'device': '/networks/{net_id}/devices/claim'} bind_org_urls = {'device': '/organizations/{org_id}/claim'} update_device_urls = {'device': '/networks/{net_id}/devices/'} delete_device_urls = {'device': '/networks/{net_id}/devices/'} meraki.url_catalog['get_all'].update(query_urls) meraki.url_catalog['get_all_org'] = query_org_urls meraki.url_catalog['get_device'] = query_device_urls meraki.url_catalog['create'] = claim_device_urls meraki.url_catalog['bind_org'] = bind_org_urls meraki.url_catalog['update'] = update_device_urls meraki.url_catalog['delete'] = delete_device_urls payload = None # if the user is working with this module in only check mode we do not # want to make any changes to the environment, just return the current # state with no modifications # FIXME: Work with Meraki so they can implement a check mode if module.check_mode: meraki.exit_json(**meraki.result) # execute checks for argument completeness # manipulate or modify the state as needed (this is going to be the # part where your module will do what it needs to do) org_id = meraki.params['org_id'] if org_id is None: org_id = meraki.get_org_id(meraki.params['org_name']) nets = meraki.get_nets(org_id=org_id) net_id = None if meraki.params['net_id'] or meraki.params['net_name']: net_id = meraki.params['net_id'] if net_id is None: net_id = meraki.get_net_id(net_name=meraki.params['net_name'], data=nets) if meraki.params['state'] == 'query': if meraki.params['net_name'] or meraki.params['net_id']: device = [] if meraki.params['serial']: path = meraki.construct_path( 'get_device', net_id=net_id) + meraki.params['serial'] request = meraki.request(path, method='GET') device.append(request) meraki.result['data'] = device elif meraki.params['serial_uplink']: path = meraki.construct_path( 'get_device', net_id=net_id) + meraki.params['serial_uplink'] + '/uplink' meraki.result['data'] = (meraki.request(path, method='GET')) elif meraki.params['serial_lldp_cdp']: if meraki.params['lldp_cdp_timespan'] > 2592000: meraki.fail_json( msg= 'LLDP/CDP timespan must be less than a month (2592000 seconds)' ) path = meraki.construct_path( 'get_device', net_id=net_id ) + meraki.params['serial_lldp_cdp'] + '/lldp_cdp' path = path + '?timespan=' + str( meraki.params['lldp_cdp_timespan']) device.append(meraki.request(path, method='GET')) meraki.result['data'] = device elif meraki.params['hostname']: path = meraki.construct_path('get_all', net_id=net_id) devices = meraki.request(path, method='GET') for unit in devices: try: if unit['name'] == meraki.params['hostname']: device.append(unit) meraki.result['data'] = device except KeyError: pass elif meraki.params['model']: path = meraki.construct_path('get_all', net_id=net_id) devices = meraki.request(path, method='GET') device_match = [] for device in devices: if device['model'] == meraki.params['model']: device_match.append(device) meraki.result['data'] = device_match else: path = meraki.construct_path('get_all', net_id=net_id) request = meraki.request(path, method='GET') meraki.result['data'] = request else: path = meraki.construct_path('get_all_org', org_id=org_id) devices = meraki.request(path, method='GET') if meraki.params['serial']: for device in devices: if device['serial'] == meraki.params['serial']: meraki.result['data'] = device else: meraki.result['data'] = devices elif meraki.params['state'] == 'present': device = [] if meraki.params['hostname']: query_path = meraki.construct_path('get_all', net_id=net_id) device_list = meraki.request(query_path, method='GET') if is_device_valid(meraki, meraki.params['serial'], device_list): payload = { 'name': meraki.params['hostname'], 'tags': format_tags(meraki.params['tags']), 'lat': meraki.params['lat'], 'lng': meraki.params['lng'], 'address': meraki.params['address'], 'moveMapMarker': meraki.params['move_map_marker'], 'notes': meraki.params['note'], } query_path = meraki.construct_path( 'get_device', net_id=net_id) + meraki.params['serial'] device_data = meraki.request(query_path, method='GET') ignore_keys = [ 'lanIp', 'serial', 'mac', 'model', 'networkId', 'moveMapMarker', 'wan1Ip', 'wan2Ip' ] # meraki.fail_json(msg="Compare", original=device_data, payload=payload, ignore=ignore_keys) if meraki.is_update_required(device_data, payload, optional_ignore=ignore_keys): path = meraki.construct_path( 'update', net_id=net_id) + meraki.params['serial'] updated_device = [] updated_device.append( meraki.request(path, method='PUT', payload=json.dumps(payload))) meraki.result['data'] = updated_device meraki.result['changed'] = True else: meraki.result['data'] = device_data else: if net_id is None: device_list = get_org_devices(meraki, org_id) if is_device_valid(meraki, meraki.params['serial'], device_list) is False: payload = {'serial': meraki.params['serial']} path = meraki.construct_path('bind_org', org_id=org_id) created_device = [] created_device.append( meraki.request(path, method='POST', payload=json.dumps(payload))) meraki.result['data'] = created_device meraki.result['changed'] = True else: query_path = meraki.construct_path('get_all', net_id=net_id) device_list = meraki.request(query_path, method='GET') if is_device_valid(meraki, meraki.params['serial'], device_list) is False: if net_id: payload = {'serial': meraki.params['serial']} path = meraki.construct_path('create', net_id=net_id) created_device = [] created_device.append( meraki.request(path, method='POST', payload=json.dumps(payload))) meraki.result['data'] = created_device meraki.result['changed'] = True elif meraki.params['state'] == 'absent': device = [] query_path = meraki.construct_path('get_all', net_id=net_id) device_list = meraki.request(query_path, method='GET') if is_device_valid(meraki, meraki.params['serial'], device_list) is True: path = meraki.construct_path('delete', net_id=net_id) path = path + meraki.params['serial'] + '/remove' request = meraki.request(path, method='POST') meraki.result['changed'] = True # in the event of a successful module execution, you will want to # simple AnsibleModule.exit_json(), passing the key/value results meraki.exit_json(**meraki.result)
def main(): # define the available arguments/parameters that a user can pass to # the module fixed_ip_arg_spec = dict( mac=dict(type='str'), ip=dict(type='str'), name=dict(type='str'), ) reserved_ip_arg_spec = dict( start=dict(type='str'), end=dict(type='str'), comment=dict(type='str'), ) argument_spec = meraki_argument_spec() argument_spec.update( net_id=dict(type='str'), net_name=dict(type='str'), name=dict(type='str'), subnet=dict(type='str'), gateway_ip=dict(type='str'), state=dict(type='str', default='present', choices=['absent', 'present', 'query']), fixed_ip_assignments=dict(type='list', elements='dict', options=fixed_ip_arg_spec), reserved_ip_ranges=dict(type='list', elements='dict', options=reserved_ip_arg_spec), route_id=dict(type='str'), enabled=dict(type='bool'), ) # the AnsibleModule object will be our abstraction working with Ansible # this includes instantiation, a couple of common attr would be the # args/params passed to the execution, as well as if the module # supports check mode module = AnsibleModule( argument_spec=argument_spec, supports_check_mode=True, ) meraki = MerakiModule(module, function='static_route') module.params['follow_redirects'] = 'all' payload = None query_urls = {'static_route': '/networks/{net_id}/staticRoutes'} query_one_urls = { 'static_route': '/networks/{net_id}/staticRoutes/{route_id}' } create_urls = {'static_route': '/networks/{net_id}/staticRoutes/'} update_urls = { 'static_route': '/networks/{net_id}/staticRoutes/{route_id}' } delete_urls = { 'static_route': '/networks/{net_id}/staticRoutes/{route_id}' } meraki.url_catalog['get_all'].update(query_urls) meraki.url_catalog['get_one'].update(query_one_urls) meraki.url_catalog['create'] = create_urls meraki.url_catalog['update'] = update_urls meraki.url_catalog['delete'] = delete_urls if not meraki.params['org_name'] and not meraki.params['org_id']: meraki.fail_json( msg="Parameters 'org_name' or 'org_id' parameters are required") if not meraki.params['net_name'] and not meraki.params['net_id']: meraki.fail_json( msg="Parameters 'net_name' or 'net_id' parameters are required") if meraki.params['net_name'] and meraki.params['net_id']: meraki.fail_json(msg="'net_name' and 'net_id' are mutually exclusive") # Construct payload if meraki.params['state'] == 'present': payload = dict() if meraki.params['net_name']: payload['name'] = meraki.params['net_name'] # manipulate or modify the state as needed (this is going to be the # part where your module will do what it needs to do) org_id = meraki.params['org_id'] if not org_id: org_id = meraki.get_org_id(meraki.params['org_name']) net_id = meraki.params['net_id'] if net_id is None: nets = meraki.get_nets(org_id=org_id) net_id = meraki.get_net_id(net_name=meraki.params['net_name'], data=nets) if meraki.params['state'] == 'query': if meraki.params['route_id'] is not None: meraki.result['data'] = get_static_route(meraki, net_id, meraki.params['route_id']) else: meraki.result['data'] = get_static_routes(meraki, net_id) elif meraki.params['state'] == 'present': payload = { 'name': meraki.params['name'], 'subnet': meraki.params['subnet'], 'gatewayIp': meraki.params['gateway_ip'], } if meraki.params['fixed_ip_assignments'] is not None: payload['fixedIpAssignments'] = fixed_ip_factory( meraki, meraki.params['fixed_ip_assignments']) if meraki.params['reserved_ip_ranges'] is not None: payload['reservedIpRanges'] = meraki.params['reserved_ip_ranges'] # meraki.fail_json(msg="payload", payload=payload) if meraki.params['enabled'] is not None: payload['enabled'] = meraki.params['enabled'] if meraki.params['route_id']: existing_route = get_static_route(meraki, net_id, meraki.params['route_id']) proposed = existing_route.copy() proposed.update(payload) if module.check_mode: meraki.result['data'] = proposed meraki.result['data'].update(payload) meraki.exit_json(**meraki.result) if meraki.is_update_required(existing_route, proposed, optional_ignore=['id']): path = meraki.construct_path( 'update', net_id=net_id, custom={'route_id': meraki.params['route_id']}) meraki.result['data'] = meraki.request( path, method="PUT", payload=json.dumps(payload)) meraki.result['changed'] = True else: if module.check_mode: meraki.result['data'] = payload meraki.exit_json(**meraki.result) path = meraki.construct_path('create', net_id=net_id) meraki.result['data'] = meraki.request(path, method="POST", payload=json.dumps(payload)) meraki.result['changed'] = True elif meraki.params['state'] == 'absent': if module.check_mode: meraki.exit_json(**meraki.result) path = meraki.construct_path( 'delete', net_id=net_id, custom={'route_id': meraki.params['route_id']}) meraki.result['data'] = meraki.request(path, method='DELETE') meraki.result['changed'] = True # in the event of a successful module execution, you will want to # simple AnsibleModule.exit_json(), passing the key/value results meraki.exit_json(**meraki.result)
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', element='dict', options=one_to_one_spec), one_to_many=dict(type='list', element='dict', options=one_to_many_spec), port_forwarding=dict(type='list', element='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 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 whitelist_arg_spec = dict( rule_id=dict(type='str'), message=dict(type='str'), ) protected_nets_arg_spec = dict( use_default=dict(type='bool'), included_cidr=dict(type='list', element='str'), excluded_cidr=dict(type='list', element='str'), ) 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=['absent', 'present', 'query'], default='present'), whitelisted_rules=dict(type='list', default=None, element='dict', options=whitelist_arg_spec), mode=dict(type='str', choices=['detection', 'disabled', 'prevention']), ids_rulesets=dict(type='str', choices=['connectivity', 'balanced', 'security']), protected_networks=dict(type='dict', default=None, options=protected_nets_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='intrusion_prevention') module.params['follow_redirects'] = 'all' payload = None query_org_urls = { 'intrusion_prevention': '/organizations/{org_id}/security/intrusionSettings' } query_net_urls = { 'intrusion_prevention': '/networks/{net_id}/security/intrusionSettings' } set_org_urls = { 'intrusion_prevention': '/organizations/{org_id}/security/intrusionSettings' } set_net_urls = { 'intrusion_prevention': '/networks/{net_id}/security/intrusionSettings' } meraki.url_catalog['query_org'] = query_org_urls meraki.url_catalog['query_net'] = query_net_urls meraki.url_catalog['set_org'] = set_org_urls meraki.url_catalog['set_net'] = set_net_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['net_name'] and meraki.params['net_id']: meraki.fail_json(msg='net_name and net_id are mutually exclusive') if meraki.params['net_name'] is None and meraki.params[ 'net_id'] is None: # Organization param check if meraki.params['state'] == 'present': if meraki.params['whitelisted_rules'] is None: meraki.fail_json( msg= 'whitelisted_rules is required when state is present and no network is specified.' ) if meraki.params['net_name'] or meraki.params[ 'net_id']: # Network param check if meraki.params['state'] == 'present': if meraki.params['protected_networks'] is not None: if meraki.params['protected_networks'][ 'use_default'] is False and meraki.params[ 'protected_networks']['included_cidr'] is None: meraki.fail_json( msg= "included_cidr is required when use_default is False.") if meraki.params['protected_networks'][ 'use_default'] is False and meraki.params[ 'protected_networks']['excluded_cidr'] is None: meraki.fail_json( msg= "excluded_cidr is required when use_default is False.") 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 and meraki.params['net_name']: nets = meraki.get_nets(org_id=org_id) net_id = meraki.get_net_id(net_name=meraki.params['net_name'], data=nets) # Assemble payload if meraki.params['state'] == 'present': if net_id is None: # Create payload for organization rules = [] for rule in meraki.params['whitelisted_rules']: rules.append({ 'ruleId': rule['rule_id'], 'message': rule['message'], }) payload = {'whitelistedRules': rules} else: # Create payload for network payload = dict() if meraki.params['mode']: payload['mode'] = meraki.params['mode'] if meraki.params['ids_rulesets']: payload['idsRulesets'] = meraki.params['ids_rulesets'] if meraki.params['protected_networks']: payload['protectedNetworks'] = {} if meraki.params['protected_networks']['use_default']: payload['protectedNetworks'].update({ 'useDefault': meraki.params['protected_networks']['use_default'] }) if meraki.params['protected_networks']['included_cidr']: payload['protectedNetworks'].update({ 'includedCidr': meraki.params['protected_networks']['included_cidr'] }) if meraki.params['protected_networks']['excluded_cidr']: payload['protectedNetworks'].update({ 'excludedCidr': meraki.params['protected_networks']['excluded_cidr'] }) elif meraki.params['state'] == 'absent': if net_id is None: # Create payload for organization payload = {'whitelistedRules': []} if meraki.params['state'] == 'query': if net_id is None: # Query settings for organization path = meraki.construct_path('query_org', org_id=org_id) data = meraki.request(path, method='GET') if meraki.status == 200: meraki.result['data'] = data else: # Query settings for network path = meraki.construct_path('query_net', net_id=net_id) data = meraki.request(path, method='GET') elif meraki.params['state'] == 'present': path = meraki.construct_path('query_org', org_id=org_id) original = meraki.request(path, method='GET') if net_id is None: # Set configuration for organization if meraki.is_update_required(original, payload, optional_ignore=['message']): if meraki.module.check_mode is True: original.update(payload) meraki.result['data'] = original meraki.result['changed'] = True meraki.exit_json(**meraki.result) path = meraki.construct_path('set_org', org_id=org_id) data = meraki.request(path, method='PUT', payload=json.dumps(payload)) if meraki.status == 200: meraki.result['data'] = data meraki.result['changed'] = True else: meraki.result['data'] = original meraki.result['changed'] = False else: # Set configuration for network path = meraki.construct_path('query_net', net_id=net_id) original = meraki.request(path, method='GET') if meraki.is_update_required(original, payload): if meraki.module.check_mode is True: payload.update(original) meraki.result['data'] = payload meraki.result['changed'] = True meraki.exit_json(**meraki.result) path = meraki.construct_path('set_net', net_id=net_id) data = meraki.request(path, method='PUT', payload=json.dumps(payload)) if meraki.status == 200: meraki.result['data'] = data meraki.result['changed'] = True else: meraki.result['data'] = original meraki.result['changed'] = False elif meraki.params['state'] == 'absent': if net_id is None: path = meraki.construct_path('query_org', org_id=org_id) original = meraki.request(path, method='GET') if meraki.is_update_required(original, payload): if meraki.module.check_mode is True: payload.update(original) meraki.result['data'] = payload meraki.result['changed'] = True meraki.exit_json(**meraki.result) path = meraki.construct_path('set_org', org_id=org_id) data = meraki.request(path, method='PUT', payload=json.dumps(payload)) if meraki.status == 200: meraki.result['data'] = data meraki.result['changed'] = True else: meraki.result['data'] = original meraki.result['changed'] = False # in the event of a successful module execution, you will want to # simple AnsibleModule.exit_json(), passing the key/value results meraki.exit_json(**meraki.result)
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)
def main(): param_map = {'name': 'name', 'enabled': 'enabled', 'authMode': 'auth_mode', 'encryptionMode': 'encryption_mode', 'psk': 'psk', 'wpaEncryptionMode': 'wpa_encryption_mode', 'splashPage': 'splash_page', 'radiusServers': 'radius_servers', 'radiusCoaEnabled': 'radius_coa_enabled', 'radiusFailoverPolicy': 'radius_failover_policy', 'radiusLoadBalancingPolicy': 'radius_load_balancing_policy', 'radiusAccountingEnabled': 'radius_accounting_enabled', 'radiusAccountingServers': 'radius_accounting_servers', 'ipAssignmentMode': 'ip_assignment_mode', 'useVlanTagging': 'use_vlan_tagging', 'concentratorNetworkId': 'concentrator_network_id', 'vlanId': 'vlan_id', 'defaultVlanId': 'default_vlan_id', 'apTagsAndVlanIds': 'ap_tags_vlan_ids', 'walledGardenEnabled': 'walled_garden_enabled', 'walledGardenRanges': 'walled_garden_ranges', 'minBitrate': 'min_bitrate', 'bandSelection': 'band_selection', 'perClientBandwidthLimitUp': 'per_client_bandwidth_limit_up', 'perClientBandwidthLimitDown': 'per_client_bandwidth_limit_down', } default_payload = {'name': 'Unconfigured SSID', 'auth_mode': 'open', 'splashPage': 'None', 'perClientBandwidthLimitUp': 0, 'perClientBandwidthLimitDown': 0, 'ipAssignmentMode': 'NAT mode', 'enabled': False, 'bandSelection': 'Dual band operation', 'minBitrate': 11, } # define the available arguments/parameters that a user can pass to # the module radius_arg_spec = dict(host=dict(type='str', required=True), port=dict(type='int'), secret=dict(type='str', no_log=True), ) vlan_arg_spec = dict(tags=dict(type='list'), vlan_id=dict(type='int'), ) argument_spec = meraki_argument_spec() argument_spec.update(state=dict(type='str', choices=['absent', 'present', 'query'], default='present'), number=dict(type='int', aliases=['ssid_number']), name=dict(type='str'), org_name=dict(type='str', aliases=['organization']), org_id=dict(type='int'), net_name=dict(type='str'), net_id=dict(type='str'), enabled=dict(type='bool'), auth_mode=dict(type='str', choices=['open', 'psk', 'open-with-radius', '8021x-meraki', '8021x-radius']), encryption_mode=dict(type='str', choices=['wpa', 'eap', 'wpa-eap']), psk=dict(type='str', no_log=True), wpa_encryption_mode=dict(type='str', choices=['WPA1 and WPA2', 'WPA2 only']), splash_page=dict(type='str', choices=['None', 'Click-through splash page', 'Billing', 'Password-protected with Meraki RADIUS', 'Password-protected with custom RADIUS', 'Password-protected with Active Directory', 'Password-protected with LDAP', 'SMS authentication', 'Systems Manager Sentry', 'Facebook Wi-Fi', 'Google OAuth', 'Sponsored guest']), radius_servers=dict(type='list', default=None, element='dict', options=radius_arg_spec), radius_coa_enabled=dict(type='bool'), radius_failover_policy=dict(type='str', choices=['Deny access', 'Allow access']), radius_load_balancing_policy=dict(type='str', choices=['Strict priority order', 'Round robin']), radius_accounting_enabled=dict(type='bool'), radius_accounting_servers=dict(type='list', element='dict', options=radius_arg_spec), ip_assignment_mode=dict(type='str', choices=['NAT mode', 'Bridge mode', 'Layer 3 roaming', 'Layer 3 roaming with a concentrator', 'VPN']), use_vlan_tagging=dict(type='bool'), concentrator_network_id=dict(type='str'), vlan_id=dict(type='int'), default_vlan_id=dict(type='int'), ap_tags_vlan_ids=dict(type='list', default=None, element='dict', options=vlan_arg_spec), walled_garden_enabled=dict(type='bool'), walled_garden_ranges=dict(type='list'), min_bitrate=dict(type='float', choices=[1, 2, 5.5, 6, 9, 11, 12, 18, 24, 36, 48, 54]), band_selection=dict(type='str', choices=['Dual band operation', '5 GHz band only', 'Dual band operation with Band Steering']), per_client_bandwidth_limit_up=dict(type='int'), per_client_bandwidth_limit_down=dict(type='int'), ) # seed the result dict in the object # we primarily care about changed and state # change is if this module effectively modified the target # state will include any data that you want your module to pass back # for consumption, for example, in a subsequent task result = dict( changed=False, ) # the AnsibleModule object will be our abstraction working with Ansible # this includes instantiation, a couple of common attr would be the # args/params passed to the execution, as well as if the module # supports check mode module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=True, ) meraki = MerakiModule(module, function='ssid') meraki.params['follow_redirects'] = 'all' query_urls = {'ssid': '/networks/{net_id}/ssids'} query_url = {'ssid': 'networks/{net_id}/ssids/'} update_url = {'ssid': 'networks/{net_id}/ssids/'} meraki.url_catalog['get_all'].update(query_urls) meraki.url_catalog['get_one'].update(query_url) meraki.url_catalog['update'] = update_url payload = None # if the user is working with this module in only check mode we do not # want to make any changes to the environment, just return the current # state with no modifications # FIXME: Work with Meraki so they can implement a check mode if module.check_mode: meraki.exit_json(**meraki.result) # execute checks for argument completeness if meraki.params['psk']: if meraki.params['auth_mode'] != 'psk': meraki.fail_json(msg='PSK is only allowed when auth_mode is set to psk') if meraki.params['encryption_mode'] != 'wpa': meraki.fail_json(msg='PSK requires encryption_mode be set to wpa') if meraki.params['radius_servers']: if meraki.params['auth_mode'] not in ('open-with-radius', '8021x-radius'): meraki.fail_json(msg='radius_servers requires auth_mode to be open-with-radius or 8021x-radius') if meraki.params['radius_accounting_enabled'] is True: if meraki.params['auth_mode'] not in ('open-with-radius', '8021x-radius'): meraki.fails_json(msg='radius_accounting_enabled is only allowed when auth_mode is open-with-radius or 8021x-radius') if meraki.params['radius_accounting_servers'] is True: if meraki.params['auth_mode'] not in ('open-with-radius', '8021x-radius') or meraki.params['radius_accounting_enabled'] is False: meraki.fail_json(msg='radius_accounting_servers is only allowed when auth_mode is open_with_radius or 8021x-radius and \ radius_accounting_enabled is true') # manipulate or modify the state as needed (this is going to be the # part where your module will do what it needs to do) org_id = meraki.params['org_id'] net_id = meraki.params['net_id'] if org_id is None: org_id = meraki.get_org_id(meraki.params['org_name']) if net_id is None: nets = meraki.get_nets(org_id=org_id) net_id = meraki.get_net_id(org_id, meraki.params['net_name'], data=nets) if meraki.params['state'] == 'query': if meraki.params['name']: ssid_id = get_ssid_number(meraki.params['name'], get_ssids(meraki, net_id)) path = meraki.construct_path('get_one', net_id=net_id) + str(ssid_id) meraki.result['data'] = meraki.request(path, method='GET') elif meraki.params['number']: path = meraki.construct_path('get_one', net_id=net_id) + meraki.params['number'] meraki.result['data'] = meraki.request(path, method='GET') else: meraki.result['data'] = get_ssids(meraki, net_id) elif meraki.params['state'] == 'present': payload = dict() for k, v in param_map.items(): if meraki.params[v] is not None: payload[k] = meraki.params[v] ssids = get_ssids(meraki, net_id) original = ssids[get_ssid_number(meraki.params['name'], ssids)] # meraki.fail_json(msg=meraki.is_update_required(original, payload), original=original, payload=payload) if meraki.is_update_required(original, payload): ssid_id = meraki.params['number'] if ssid_id is None: # Name should be used to lookup number ssid_id = get_ssid_number(meraki.params['name'], ssids) if ssid_id is False: ssid_id = get_available_number(ssids) if ssid_id is False: meraki.fail_json(msg='No unconfigured SSIDs are available. Specify a number.') path = meraki.construct_path('update', net_id=net_id) + str(ssid_id) result = meraki.request(path, 'PUT', payload=json.dumps(payload)) meraki.result['data'] = result meraki.result['changed'] = True elif meraki.params['state'] == 'absent': ssids = get_ssids(meraki, net_id) ssid_id = meraki.params['number'] if ssid_id is None: # Name should be used to lookup number ssid_id = get_ssid_number(meraki.params['name'], ssids) if ssid_id is False: ssid_id = get_available_number(ssids) if ssid_id is False: meraki.fail_json(msg='No SSID found by specified name and no number was referenced.') path = meraki.construct_path('update', net_id=net_id) + str(ssid_id) payload = default_payload payload['name'] = payload['name'] + ' ' + str(ssid_id + 1) # meraki.fail_json(msg='Payload', payload=payload) result = meraki.request(path, 'PUT', payload=json.dumps(payload)) meraki.result['data'] = result meraki.result['changed'] = True # in the event of a successful module execution, you will want to # simple AnsibleModule.exit_json(), passing the key/value results meraki.exit_json(**meraki.result)
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 argument_spec = meraki_argument_spec() argument_spec.update( state=dict(type='str', choices=['absent', 'query', 'present'], default='query'), org_name=dict(type='str', aliases=['organization']), org_id=dict(type='int'), config_template=dict(type='str', aliases=['name']), net_name=dict(type='str'), net_id=dict(type='str'), # config_template_id=dict(type='str', aliases=['id']), auto_bind=dict(type='bool'), ) # seed the result dict in the object # we primarily care about changed and state # change is if this module effectively modified the target # state will include any data that you want your module to pass back # for consumption, for example, in a subsequent task result = dict(changed=False, ) # the AnsibleModule object will be our abstraction working with Ansible # this includes instantiation, a couple of common attr would be the # args/params passed to the execution, as well as if the module # supports check mode module = AnsibleModule( argument_spec=argument_spec, supports_check_mode=True, ) meraki = MerakiModule(module, function='config_template') meraki.params['follow_redirects'] = 'all' query_urls = {'config_template': '/organizations/{org_id}/configTemplates'} delete_urls = { 'config_template': '/organizations/{org_id}/configTemplates' } bind_urls = {'config_template': '/networks/{net_id}/bind'} unbind_urls = {'config_template': '/networks/{net_id}/unbind'} meraki.url_catalog['get_all'].update(query_urls) meraki.url_catalog['delete'] = delete_urls meraki.url_catalog['bind'] = bind_urls meraki.url_catalog['unbind'] = unbind_urls payload = None # if the user is working with this module in only check mode we do not # want to make any changes to the environment, just return the current # state with no modifications # FIXME: Work with Meraki so they can implement a check mode if module.check_mode: meraki.exit_json(**meraki.result) # execute checks for argument completeness # manipulate or modify the state as needed (this is going to be the # part where your module will do what it needs to do) org_id = meraki.params['org_id'] if meraki.params['org_name']: org_id = meraki.get_org_id(meraki.params['org_name']) net_id = meraki.params['net_id'] nets = None if net_id is None: if meraki.params['net_name'] is not None: nets = meraki.get_nets(org_id=org_id) net_id = meraki.get_net_id(net_name=meraki.params['net_name'], data=nets) else: nets = meraki.get_nets(org_id=org_id) if meraki.params['state'] == 'query': meraki.result['data'] = get_config_templates(meraki, org_id) elif meraki.params['state'] == 'present': template_id = get_template_id(meraki, meraki.params['config_template'], get_config_templates(meraki, org_id)) if nets is None: nets = meraki.get_nets(org_id=org_id) if is_network_bound(meraki, nets, net_id, template_id) is False: template_bind = bind(meraki, net_id, template_id) if meraki.status != 200: meraki.fail_json( msg='Unable to bind configuration template to network') meraki.result['changed'] = True meraki.result['data'] = template_bind else: meraki.result['data'] = {} elif meraki.params['state'] == 'absent': if not meraki.params['net_name'] and not meraki.params['net_id']: meraki.result['data'] = delete_template( meraki, org_id, meraki.params['config_template'], get_config_templates(meraki, org_id)) if meraki.status == 200: meraki.result['changed'] = True else: template_id = get_template_id(meraki, meraki.params['config_template'], get_config_templates(meraki, org_id)) if nets is None: nets = meraki.get_nets(org_id=org_id) if is_network_bound(meraki, nets, net_id, template_id) is True: config_unbind = unbind(meraki, net_id) if meraki.status != 200: meraki.fail_json( msg= 'Unable to unbind configuration template from network') meraki.result['changed'] = True meraki.result['data'] = config_unbind else: meraki.result['data'] = {} # 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)
delete_url = {'mxVlan': '/networks/{net_id}/appliancePorts/'} 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['appliance_port_id']: meraki.result['data'] = get_vlans(meraki, net_id) else: path = meraki.construct_path('get_one', net_id=net_id, custom={'appliance_port_id': meraki.params['appliance_port_id']}) response = meraki.request(path, method='GET') meraki.result['data'] = response elif meraki.params['state'] == 'present': payload = {'number': meraki.params['appliance_port_id'], 'vlan': meraki.params['vlan_id'], 'type': meraki.params['type'], 'enabled': meraki.params['enabled'], }
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']) nets = meraki.get_nets(org_id=org_id) net_id = None if meraki.params['net_name']: net_id = meraki.get_net_id(net_name=meraki.params['net_name'], data=nets) elif meraki.params['net_id']: net_id = meraki.params['net_id'] 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: 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: 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): 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 elif meraki.params['state'] == 'absent': if is_vlan_valid(meraki, net_id, meraki.params['vlan_id']): 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 # if the user is working with this module in only check mode we do not # want to make any changes to the environment, just return the current # state with no modifications # FIXME: Work with Meraki so they can implement a check mode if module.check_mode: meraki.exit_json(**meraki.result) # execute checks for argument completeness # manipulate or modify the state as needed (this is going to be the # part where your module will do what it needs to do) # 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'), type=dict(type='list', choices=['wireless', 'switch', 'appliance'], aliases=['net_type']), tags=dict(type='list'), timezone=dict(type='str'), net_name=dict(type='str', aliases=['name', 'network']), state=dict(type='str', choices=['present', 'query', 'absent'], default='present'), enable_vlans=dict(type='bool'), disable_my_meraki=dict(type='bool', removed_in_version=2.13), enable_my_meraki=dict(type='bool'), enable_remote_status_page=dict(type='bool'), ) # the AnsibleModule object will be our abstraction working with Ansible # this includes instantiation, a couple of common attr would be the # args/params passed to the execution, as well as if the module # supports check mode module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=False, mutually_exclusive=[ ('disable_my_meraki', 'enable_my_meraki'), ]) meraki = MerakiModule(module, function='network') module.params['follow_redirects'] = 'all' payload = None create_urls = {'network': '/organizations/{org_id}/networks'} update_urls = {'network': '/networks/{net_id}'} delete_urls = {'network': '/networks/{net_id}'} enable_vlans_urls = {'network': '/networks/{net_id}/vlansEnabledState'} get_vlan_status_urls = {'network': '/networks/{net_id}/vlansEnabledState'} meraki.url_catalog['create'] = create_urls meraki.url_catalog['update'] = update_urls meraki.url_catalog['delete'] = delete_urls meraki.url_catalog['enable_vlans'] = enable_vlans_urls meraki.url_catalog['status_vlans'] = get_vlan_status_urls if not meraki.params['org_name'] and not meraki.params['org_id']: meraki.fail_json(msg='org_name or org_id parameters are required') if meraki.params['state'] != 'query': if not meraki.params['net_name'] and not meraki.params['net_id']: meraki.fail_json( msg= 'net_name or net_id is required for present or absent states') if meraki.params['net_name'] and meraki.params['net_id']: meraki.fail_json(msg='net_name and net_id are mutually exclusive') if not meraki.params['net_name'] and not meraki.params['net_id']: if meraki.params['enable_vlans']: meraki.fail_json( msg= "The parameter 'enable_vlans' requires 'net_name' or 'net_id' to be specified" ) if meraki.params['enable_my_meraki'] is True and meraki.params[ 'enable_remote_status_page'] is False: meraki.fail_json( msg= 'enable_my_meraki must be true when setting enable_remote_status_page' ) # if the user is working with this module in only check mode we do not # want to make any changes to the environment, just return the current # state with no modifications if module.check_mode: return meraki.result # Construct payload if meraki.params['state'] == 'present': payload = dict() if meraki.params['net_name']: payload['name'] = meraki.params['net_name'] if meraki.params['type']: payload['type'] = list_to_string(meraki.params['type']) if meraki.params['tags']: payload['tags'] = construct_tags(meraki.params['tags']) if meraki.params['timezone']: payload['timeZone'] = meraki.params['timezone'] if meraki.params['enable_my_meraki'] is not None: if meraki.params['enable_my_meraki'] is True: payload['disableMyMerakiCom'] = False else: payload['disableMyMerakiCom'] = True elif meraki.params['disable_my_meraki'] is not None: payload['disableMyMerakiCom'] = meraki.params['disable_my_meraki'] if meraki.params['enable_remote_status_page'] is not None: if meraki.params['enable_remote_status_page'] is True: payload['disableRemoteStatusPage'] = False # meraki.fail_json(msg="Debug", payload=payload) else: payload['disableRemoteStatusPage'] = True # manipulate or modify the state as needed (this is going to be the # part where your module will do what it needs to do) org_id = meraki.params['org_id'] if not org_id: org_id = meraki.get_org_id(meraki.params['org_name']) nets = meraki.get_nets(org_id=org_id) # check if network is created net_id = meraki.params['net_id'] net_exists = False if net_id is not None: if is_net_valid(nets, net_id=net_id) is False: meraki.fail_json(msg="Network specified by net_id does not exist.") net_exists = True elif meraki.params['net_name']: if is_net_valid(nets, net_name=meraki.params['net_name']) is True: net_id = meraki.get_net_id(net_name=meraki.params['net_name'], data=nets) net_exists = True if meraki.params['state'] == 'query': if not meraki.params['net_name'] and not meraki.params['net_id']: meraki.result['data'] = nets elif meraki.params['net_name'] or meraki.params['net_id'] is not None: meraki.result['data'] = meraki.get_net(meraki.params['org_name'], meraki.params['net_name'], data=nets) elif meraki.params['state'] == 'present': if net_exists is False: # Network needs to be created if 'type' not in meraki.params or meraki.params['type'] is None: meraki.fail_json( msg="type parameter is required when creating a network.") path = meraki.construct_path('create', org_id=org_id) r = meraki.request(path, method='POST', payload=json.dumps(payload)) if meraki.status == 201: meraki.result['data'] = r meraki.result['changed'] = True else: # Network exists, make changes # meraki.fail_json(msg="nets", nets=nets, net_id=net_id) # meraki.fail_json(msg="compare", original=net, payload=payload) if meraki.params[ 'enable_vlans'] is not None: # Modify VLANs configuration status_path = meraki.construct_path('status_vlans', net_id=net_id) status = meraki.request(status_path, method='GET') payload = {'enabled': meraki.params['enable_vlans']} # meraki.fail_json(msg="here", payload=payload) if meraki.is_update_required(status, payload): path = meraki.construct_path('enable_vlans', net_id=net_id) r = meraki.request(path, method='PUT', payload=json.dumps(payload)) if meraki.status == 200: meraki.result['data'] = r meraki.result['changed'] = True meraki.exit_json(**meraki.result) else: meraki.result['data'] = status meraki.exit_json(**meraki.result) net = meraki.get_net(meraki.params['org_name'], net_id=net_id, data=nets) if meraki.is_update_required(net, payload): path = meraki.construct_path('update', net_id=net_id) # meraki.fail_json(msg="Payload", path=path, payload=payload) r = meraki.request(path, method='PUT', payload=json.dumps(payload)) if meraki.status == 200: meraki.result['data'] = r meraki.result['changed'] = True else: meraki.result['data'] = net elif meraki.params['state'] == 'absent': if is_net_valid(nets, net_id=net_id) is True: path = meraki.construct_path('delete', net_id=net_id) r = meraki.request(path, method='DELETE') if meraki.status == 204: meraki.result['changed'] = True # in the event of a successful module execution, you will want to # simple AnsibleModule.exit_json(), passing the key/value results meraki.exit_json(**meraki.result)
def main(): # define the available arguments/parameters that a user can pass to # the module argument_spec = meraki_argument_spec() argument_spec.update( net_id=dict(type='str'), type=dict(type='str', choices=['wireless', 'switch', 'appliance', 'combined'], aliases=['net_type']), tags=dict(type='str'), timezone=dict(type='str'), net_name=dict(type='str', aliases=['name', 'network']), state=dict(type='str', choices=['present', 'query', 'absent'], default='present'), ) # the AnsibleModule object will be our abstraction working with Ansible # this includes instantiation, a couple of common attr would be the # args/params passed to the execution, as well as if the module # supports check mode module = AnsibleModule( argument_spec=argument_spec, supports_check_mode=False, ) meraki = MerakiModule(module, function='network') module.params['follow_redirects'] = 'all' payload = None create_urls = {'network': '/organizations/{org_id}/networks'} update_urls = {'network': '/networks/{net_id}'} delete_urls = {'network': '/networks/{net_id}'} meraki.url_catalog['create'] = create_urls meraki.url_catalog['update'] = update_urls meraki.url_catalog['delete'] = delete_urls if not meraki.params['org_name'] and not meraki.params['org_id']: meraki.fail_json(msg='org_name or org_id parameters are required') if meraki.params['state'] != 'query': if not meraki.params['net_name'] or 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 if module.check_mode: return meraki.result # Construct payload if meraki.params['state'] == 'present': payload = { 'name': meraki.params['net_name'], 'type': meraki.params['type'], } if meraki.params['tags']: payload['tags'] = construct_tags(meraki.params['tags']) if meraki.params['timezone']: payload['timeZone'] = meraki.params['timezone'] if meraki.params['type'] == 'combined': payload['type'] = 'switch wireless appliance' # 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['org_name']: nets = meraki.get_nets(org_name=meraki.params['org_name']) elif meraki.params['org_id']: nets = meraki.get_nets(org_id=meraki.params['org_id']) if meraki.params['state'] == 'query': if not meraki.params['net_name'] and not meraki.params['net_id']: meraki.result['data'] = nets elif meraki.params['net_name'] or meraki.params['net_id'] is not None: meraki.result['data'] = meraki.get_net(meraki.params['org_name'], meraki.params['net_name'], nets) elif meraki.params['state'] == 'present': if meraki.params[ 'net_name']: # FIXME: Idempotency check is ugly here, improve if is_net_valid(meraki, meraki.params['net_name'], nets) is False: if meraki.params[ 'org_name']: # FIXME: This can be cleaned up...maybe path = meraki.construct_path( 'create', org_name=meraki.params['org_name']) elif meraki.params['org_id']: path = meraki.construct_path( 'create', org_id=meraki.params['org_id']) r = meraki.request(path, method='POST', payload=json.dumps(payload)) meraki.result['data'] = r meraki.result['changed'] = True else: net = meraki.get_net(meraki.params['org_name'], meraki.params['net_name'], data=nets) if meraki.is_update_required(net, payload): path = meraki.construct_path( 'update', net_id=meraki.get_net_id( net_name=meraki.params['net_name'], data=nets)) r = meraki.request(path, method='PUT', payload=json.dumps(payload)) meraki.result['data'] = r meraki.result['changed'] = True elif meraki.params['state'] == 'absent': if is_net_valid(meraki, meraki.params['net_name'], nets) is True: net_id = meraki.get_net_id(org_name=meraki.params['org_name'], net_name=meraki.params['net_name'], data=nets) path = meraki.construct_path('delete', net_id=net_id) r = meraki.request(path, method='DELETE') if meraki.status == 204: meraki.result['changed'] = True # in the event of a successful module execution, you will want to # simple AnsibleModule.exit_json(), passing the key/value results meraki.exit_json(**meraki.result)
def main(): # define the available arguments/parameters that a user can pass to # the module user_arg_spec = dict( username=dict(type='str'), passphrase=dict(type='str', no_log=True), ) argument_spec = meraki_argument_spec() argument_spec.update( state=dict(type='str', choices=['present', 'query'], default='present'), v2c_enabled=dict(type='bool'), v3_enabled=dict(type='bool'), v3_auth_mode=dict(type='str', choices=['SHA', 'MD5']), v3_auth_pass=dict(type='str', no_log=True), v3_priv_mode=dict(type='str', choices=['DES', 'AES128']), v3_priv_pass=dict(type='str', no_log=True), peer_ips=dict(type='str'), access=dict(type='str', choices=['none', 'community', 'users']), community_string=dict(type='str', no_log=True), users=dict(type='list', default=None, elements='', options=user_arg_spec), net_name=dict(type='str'), net_id=dict(type='str'), ) # the AnsibleModule object will be our abstraction working with Ansible # this includes instantiation, a couple of common attr would be the # args/params passed to the execution, as well as if the module # supports check mode module = AnsibleModule( argument_spec=argument_spec, supports_check_mode=True, ) meraki = MerakiModule(module, function='snmp') meraki.params['follow_redirects'] = 'all' query_urls = {'snmp': '/organizations/{org_id}/snmp'} query_net_urls = {'snmp': '/networks/{net_id}/snmpSettings'} update_urls = {'snmp': '/organizations/{org_id}/snmp'} update_net_urls = {'snmp': '/networks/{net_id}/snmpSettings'} meraki.url_catalog['get_all'].update(query_urls) meraki.url_catalog['query_net_all'] = query_net_urls meraki.url_catalog['create'] = update_urls meraki.url_catalog['create_net'] = update_net_urls payload = None if not meraki.params['org_name'] and not meraki.params['org_id']: meraki.fail_json(msg='org_name or org_id is required') org_id = meraki.params['org_id'] if org_id is None: org_id = meraki.get_org_id(meraki.params['org_name']) net_id = meraki.params['net_id'] if net_id is None and meraki.params['net_name']: nets = meraki.get_nets(org_id=org_id) net_id = meraki.get_net_id(org_id, meraki.params['net_name'], data=nets) if meraki.params['state'] == 'present': if net_id is not None: payload = {'access': meraki.params['access']} if meraki.params['community_string'] is not None: payload['communityString'] = meraki.params['community_string'] elif meraki.params['users'] is not None: payload['users'] = meraki.params['users'] if meraki.params['state'] == 'query': if net_id is None: meraki.result['data'] = get_snmp(meraki, org_id) else: path = meraki.construct_path('query_net_all', net_id=net_id) response = meraki.request(path, method='GET') if meraki.status == 200: meraki.result['data'] = response elif meraki.params['state'] == 'present': if net_id is None: meraki.result['data'] = set_snmp(meraki, org_id) else: path = meraki.construct_path('query_net_all', net_id=net_id) original = meraki.request(path, method='GET') if meraki.is_update_required(original, payload): path = meraki.construct_path('create_net', net_id=net_id) response = meraki.request(path, method='PUT', payload=json.dumps(payload)) if meraki.status == 200: if response['access'] == 'none': meraki.result['data'] = {} else: meraki.result['data'] = response meraki.result['changed'] = True else: meraki.result['data'] = original # in the event of a successful module execution, you will want to # simple AnsibleModule.exit_json(), passing the key/value results meraki.exit_json(**meraki.result)
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 bandwidth_arg_spec = dict( limit_up=dict(type='int'), limit_down=dict(type='int'), ) interface_arg_spec = dict(bandwidth_limits=dict( type='dict', default=None, options=bandwidth_arg_spec), ) 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'), wan1=dict(type='dict', default=None, options=interface_arg_spec), wan2=dict(type='dict', default=None, options=interface_arg_spec), cellular=dict(type='dict', default=None, options=interface_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='mx_uplink') meraki.params['follow_redirects'] = 'all' query_urls = {'mx_uplink': '/networks/{net_id}/uplinkSettings'} update_bw_url = {'mx_uplink': '/networks/{net_id}/uplinkSettings'} meraki.url_catalog['get_all'].update(query_urls) meraki.url_catalog['update_bw'] = update_bw_url payload = dict() 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) response = meraki.request(path, method='GET') data = clean_custom_format(meraki_struct_to_custom_format(response)) meraki.result['data'] = data elif meraki.params['state'] == 'present': path = meraki.construct_path('get_all', net_id=net_id) original = meraki.request(path, method='GET') payload = {'bandwidthLimits': {}} for interface in INT_NAMES: if meraki.params[interface] is not None: if meraki.params[interface]['bandwidth_limits'] is not None: payload['bandwidthLimits'][interface] = None payload['bandwidthLimits'][interface] = { 'limitUp': meraki.params[interface]['bandwidth_limits'] ['limit_up'], 'limitDown': meraki.params[interface]['bandwidth_limits'] ['limit_down'], } if payload['bandwidthLimits'][interface]['limitUp'] == 0: payload['bandwidthLimits'][interface]['limitUp'] = None if payload['bandwidthLimits'][interface]['limitDown'] == 0: payload['bandwidthLimits'][interface][ 'limitDown'] = None if meraki.is_update_required(original, payload): if meraki.module.check_mode is True: diff = recursive_diff( clean_custom_format( meraki_struct_to_custom_format(original)), clean_custom_format( meraki_struct_to_custom_format(payload))) original.update(payload) meraki.result['data'] = clean_custom_format( meraki_struct_to_custom_format(original)) meraki.result['diff'] = { 'before': diff[0], 'after': diff[1], } meraki.result['changed'] = True meraki.exit_json(**meraki.result) path = meraki.construct_path('update_bw', net_id=net_id) response = meraki.request(path, method='PUT', payload=json.dumps(payload)) if meraki.status == 200: formatted_original = clean_custom_format( meraki_struct_to_custom_format(original)) formatted_response = clean_custom_format( meraki_struct_to_custom_format(response)) diff = recursive_diff(formatted_original, formatted_response) meraki.result['diff'] = { 'before': diff[0], 'after': diff[1], } meraki.result['data'] = formatted_response meraki.result['changed'] = True else: meraki.result['data'] = clean_custom_format( meraki_struct_to_custom_format(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)