def main(): argument_spec = mso_argument_spec() argument_spec.update( tenant=dict(type='str', required=True), schema=dict(type='str', required=True), template=dict(type='str', aliases=['name']), display_name=dict(type='str'), state=dict(type='str', default='present', choices=['absent', 'present', 'query']), ) module = AnsibleModule( argument_spec=argument_spec, supports_check_mode=True, required_if=[ ['state', 'absent', ['template']], ['state', 'present', ['template']], ], ) tenant = module.params.get('tenant') schema = module.params.get('schema') template = module.params.get('template') display_name = module.params.get('display_name') state = module.params.get('state') mso = MSOModule(module) # Get schema schema_obj = mso.get_obj('schemas', displayName=schema) mso.existing = {} if schema_obj: # Schema exists schema_path = 'schemas/{id}'.format(**schema_obj) # Get template templates = [t.get('name') for t in schema_obj.get('templates')] if template: if template in templates: template_idx = templates.index(template) mso.existing = schema_obj.get('templates')[template_idx] else: mso.existing = schema_obj.get('templates') else: schema_path = 'schemas' if state == 'query': if not mso.existing: if template: mso.fail_json(msg="Template '{0}' not found".format(template)) else: mso.existing = [] mso.exit_json() template_path = '/templates/{0}'.format(template) ops = [] mso.previous = mso.existing if state == 'absent': mso.proposed = mso.sent = {} if not schema_obj: # There was no schema to begin with pass elif len(templates) == 1 and mso.existing: # There is only one tenant, remove schema mso.existing = {} if not module.check_mode: mso.request(schema_path, method='DELETE') elif mso.existing: # Remove existing template mso.existing = {} ops.append(dict(op='remove', path=template_path)) elif state == 'present': tenant_id = mso.lookup_tenant(tenant) if display_name is None: display_name = mso.existing.get('displayName', template) if not schema_obj: # Schema does not exist, so we have to create it payload = dict( displayName=schema, templates=[ dict( name=template, displayName=display_name, tenantId=tenant_id, ) ], sites=[], ) mso.existing = payload.get('templates')[0] if not module.check_mode: mso.request(schema_path, method='POST', data=payload) elif mso.existing: # Template exists, so we have to update it payload = dict( name=template, displayName=display_name, tenantId=tenant_id, ) mso.sanitize(payload, collate=True) ops.append( dict(op='replace', path=template_path + '/displayName', value=display_name)) ops.append( dict(op='replace', path=template_path + '/tenantId', value=tenant_id)) mso.existing = mso.proposed else: # Template does not exist, so we have to add it payload = dict( name=template, displayName=display_name, tenantId=tenant_id, ) mso.sanitize(payload, collate=True) ops.append(dict(op='add', path='/templates/-', value=payload)) mso.existing = mso.proposed if not module.check_mode: mso.request(schema_path, method='PATCH', data=ops) mso.exit_json()
def main(): argument_spec = mso_argument_spec() argument_spec.update( user=dict(type='str', aliases=['name']), user_password=dict(type='str', no_log=True), first_name=dict(type='str'), last_name=dict(type='str'), email=dict(type='str'), phone=dict(type='str'), # TODO: What possible options do we have ? account_status=dict(type='str', choices=['active']), domain=dict(type='str'), roles=dict(type='list'), state=dict(type='str', default='present', choices=['absent', 'present', 'query']), ) module = AnsibleModule( argument_spec=argument_spec, supports_check_mode=True, required_if=[ ['state', 'absent', ['user']], ['state', 'present', ['user']], ], ) user_name = module.params['user'] user_password = module.params['user_password'] first_name = module.params['first_name'] last_name = module.params['last_name'] email = module.params['email'] phone = module.params['phone'] account_status = module.params['account_status'] state = module.params['state'] mso = MSOModule(module) roles = mso.lookup_roles(module.params['roles']) domain = mso.lookup_domain(module.params['domain']) user_id = None path = 'users' # Query for existing object(s) if user_name: mso.existing = mso.get_obj(path, username=user_name) if mso.existing: user_id = mso.existing['id'] # If we found an existing object, continue with it path = 'users/{id}'.format(id=user_id) else: mso.existing = mso.query_objs(path) if state == 'query': pass elif state == 'absent': mso.previous = mso.existing if mso.existing: if module.check_mode: mso.existing = {} else: mso.existing = mso.request(path, method='DELETE') elif state == 'present': mso.previous = mso.existing payload = dict( id=user_id, username=user_name, password=user_password, firstName=first_name, lastName=last_name, emailAddress=email, phoneNumber=phone, accountStatus=account_status, domainId=domain, roles=roles, # active=True, # remote=True, ) mso.sanitize(payload, collate=True) if mso.sent.get('accountStatus') is None: mso.sent['accountStatus'] = 'active' if mso.existing: if not issubset(mso.sent, mso.existing): # NOTE: Since MSO always returns '******' as password, we need to assume a change if 'password' in mso.proposed: mso.module.warn( "A password change is assumed, as the MSO REST API does not return passwords we do not know." ) mso.result['changed'] = True if module.check_mode: mso.existing = mso.proposed else: mso.existing = mso.request(path, method='PUT', data=mso.sent) else: if module.check_mode: mso.existing = mso.proposed else: mso.existing = mso.request(path, method='POST', data=mso.sent) mso.exit_json()
def main(): argument_spec = mso_argument_spec() argument_spec.update( schema=dict(type='str', required=True), template=dict(type='str', required=True), anp=dict(type='str', required=True), epg=dict(type='str', aliases=[ 'name' ]), # This parameter is not required for querying all objects bd=dict(type='dict', options=mso_reference_spec()), vrf=dict(type='dict', options=mso_reference_spec()), display_name=dict(type='str'), useg_epg=dict(type='bool'), intra_epg_isolation=dict(type='str', choices=['enforced', 'unenforced']), intersite_multicast_source=dict(type='bool'), proxy_arp=dict(type='bool'), subnets=dict(type='list', elements='dict', options=mso_subnet_spec()), state=dict(type='str', default='present', choices=['absent', 'present', 'query']), preferred_group=dict(type='bool'), ) module = AnsibleModule( argument_spec=argument_spec, supports_check_mode=True, required_if=[ ['state', 'absent', ['epg']], ['state', 'present', ['epg']], ], ) schema = module.params.get('schema') template = module.params.get('template').replace(' ', '') anp = module.params.get('anp') epg = module.params.get('epg') display_name = module.params.get('display_name') bd = module.params.get('bd') if bd is not None and bd.get('template') is not None: bd['template'] = bd.get('template').replace(' ', '') vrf = module.params.get('vrf') if vrf is not None and vrf.get('template') is not None: vrf['template'] = vrf.get('template').replace(' ', '') useg_epg = module.params.get('useg_epg') intra_epg_isolation = module.params.get('intra_epg_isolation') intersite_multicast_source = module.params.get( 'intersite_multicast_source') proxy_arp = module.params.get('proxy_arp') subnets = module.params.get('subnets') state = module.params.get('state') preferred_group = module.params.get('preferred_group') mso = MSOModule(module) # Get schema_id schema_obj = mso.get_obj('schemas', displayName=schema) if schema_obj: schema_id = schema_obj.get('id') else: mso.fail_json( msg="Provided schema '{0}' does not exist".format(schema)) schema_path = 'schemas/{id}'.format(**schema_obj) # Get template templates = [t.get('name') for t in schema_obj.get('templates')] if template not in templates: mso.fail_json( msg="Provided template '{0}' does not exist. Existing templates: {1}" .format(template, ', '.join(templates))) template_idx = templates.index(template) # Get ANP anps = [ a.get('name') for a in schema_obj.get('templates')[template_idx]['anps'] ] if anp not in anps: mso.fail_json( msg="Provided anp '{0}' does not exist. Existing anps: {1}".format( anp, ', '.join(anps))) anp_idx = anps.index(anp) # Get EPG epgs = [ e.get('name') for e in schema_obj.get('templates')[template_idx] ['anps'][anp_idx]['epgs'] ] if epg is not None and epg in epgs: epg_idx = epgs.index(epg) mso.existing = schema_obj.get( 'templates')[template_idx]['anps'][anp_idx]['epgs'][epg_idx] if state == 'query': if epg is None: mso.existing = schema_obj.get( 'templates')[template_idx]['anps'][anp_idx]['epgs'] elif not mso.existing: mso.fail_json(msg="EPG '{epg}' not found".format(epg=epg)) if 'bdRef' in mso.existing: mso.existing['bdRef'] = mso.dict_from_ref(mso.existing['bdRef']) if 'vrfRef' in mso.existing: mso.existing['vrfRef'] = mso.dict_from_ref(mso.existing['vrfRef']) mso.exit_json() epgs_path = '/templates/{0}/anps/{1}/epgs'.format(template, anp) epg_path = '/templates/{0}/anps/{1}/epgs/{2}'.format(template, anp, epg) ops = [] mso.previous = mso.existing if state == 'absent': if mso.existing: mso.sent = mso.existing = {} ops.append(dict(op='remove', path=epg_path)) elif state == 'present': bd_ref = mso.make_reference(bd, 'bd', schema_id, template) vrf_ref = mso.make_reference(vrf, 'vrf', schema_id, template) mso.stdout = str(subnets) subnets = mso.make_subnets(subnets) if display_name is None and not mso.existing: display_name = epg payload = dict( name=epg, displayName=display_name, uSegEpg=useg_epg, intraEpg=intra_epg_isolation, mCastSource=intersite_multicast_source, proxyArp=proxy_arp, # FIXME: Missing functionality # uSegAttrs=[], subnets=subnets, bdRef=bd_ref, preferredGroup=preferred_group, vrfRef=vrf_ref, ) mso.sanitize(payload, collate=True) if mso.existing: # Clean contractRef to fix api issue for contract in mso.sent.get('contractRelationships'): contract['contractRef'] = mso.dict_from_ref( contract.get('contractRef')) ops.append(dict(op='replace', path=epg_path, value=mso.sent)) else: ops.append(dict(op='add', path=epgs_path + '/-', value=mso.sent)) mso.existing = mso.proposed if 'epgRef' in mso.previous: del mso.previous['epgRef'] if 'bdRef' in mso.previous and mso.previous['bdRef'] != '': mso.previous['bdRef'] = mso.dict_from_ref(mso.previous['bdRef']) if 'vrfRef' in mso.previous and mso.previous['bdRef'] != '': mso.previous['vrfRef'] = mso.dict_from_ref(mso.previous['vrfRef']) if not module.check_mode and mso.proposed != mso.previous: mso.request(schema_path, method='PATCH', data=ops) mso.exit_json()
def main(): argument_spec = mso_argument_spec() argument_spec.update( schema=dict(type='str', required=True), site=dict(type='str', required=True), template=dict(type='str', required=True), bd=dict(type='str', required=True), l3out=dict(type='str', aliases=['name']), # This parameter is not required for querying all objects state=dict(type='str', default='present', choices=['absent', 'present', 'query']), ) module = AnsibleModule( argument_spec=argument_spec, supports_check_mode=True, required_if=[ ['state', 'absent', ['l3out']], ['state', 'present', ['l3out']], ], ) schema = module.params['schema'] site = module.params['site'] template = module.params['template'] bd = module.params['bd'] l3out = module.params['l3out'] state = module.params['state'] mso = MSOModule(module) # Get schema_id schema_obj = mso.get_obj('schemas', displayName=schema) if not schema_obj: mso.fail_json(msg="Provided schema '{0}' does not exist".format(schema)) schema_path = 'schemas/{id}'.format(**schema_obj) schema_id = schema_obj['id'] # Get site site_id = mso.lookup_site(site) # Get site_idx sites = [(s['siteId'], s['templateName']) for s in schema_obj['sites']] if (site_id, template) not in sites: mso.fail_json(msg="Provided site/template '{0}-{1}' does not exist. Existing sites/templates: {2}".format(site, template, ', '.join(sites))) # Schema-access uses indexes site_idx = sites.index((site_id, template)) # Path-based access uses site_id-template site_template = '{0}-{1}'.format(site_id, template) # Get BD bd_ref = mso.bd_ref(schema_id=schema_id, template=template, bd=bd) bds = [v['bdRef'] for v in schema_obj['sites'][site_idx]['bds']] if bd_ref not in bds: mso.fail_json(msg="Provided BD '{0}' does not exist. Existing BDs: {1}".format(bd, ', '.join(bds))) bd_idx = bds.index(bd_ref) # Get L3out l3outs = schema_obj['sites'][site_idx]['bds'][bd_idx]['l3Outs'] if l3out is not None and l3out in l3outs: l3out_idx = l3outs.index(l3out) # FIXME: Changes based on index are DANGEROUS l3out_path = '/sites/{0}/bds/{1}/l3Outs/{2}'.format(site_template, bd, l3out_idx) mso.existing = schema_obj['sites'][site_idx]['bds'][bd_idx]['l3Outs'][l3out_idx] if state == 'query': if l3out is None: mso.existing = schema_obj['sites'][site_idx]['bds'][bd_idx]['l3Outs'] elif not mso.existing: mso.fail_json(msg="L3out '{l3out}' not found".format(l3out=l3out)) mso.exit_json() l3outs_path = '/sites/{0}/bds/{1}/l3Outs'.format(site_template, bd) ops = [] mso.previous = mso.existing if state == 'absent': if mso.existing: mso.sent = mso.existing = {} ops.append(dict(op='remove', path=l3out_path)) elif state == 'present': mso.sent = l3out if not mso.existing: ops.append(dict(op='add', path=l3outs_path + '/-', value=l3out)) mso.existing = mso.sent if not module.check_mode: mso.request(schema_path, method='PATCH', data=ops) mso.exit_json()
def main(): argument_spec = mso_argument_spec() argument_spec.update( schema=dict(type='str', required=True), template=dict(type='str', required=True), vrf=dict(type='str', required=True), contract=dict(type='dict', options=mso_contractref_spec()), state=dict(type='str', default='present', choices=['absent', 'present', 'query']), ) module = AnsibleModule( argument_spec=argument_spec, supports_check_mode=True, required_if=[ ['state', 'absent', ['contract']], ['state', 'present', ['contract']], ], ) schema = module.params.get('schema') template = module.params.get('template').replace(' ', '') vrf = module.params.get('vrf') contract = module.params.get('contract') if contract is not None and contract.get('template') is not None: contract['template'] = contract.get('template').replace(' ', '') state = module.params.get('state') mso = MSOModule(module) if contract: if contract.get('schema') is None: contract['schema'] = schema contract['schema_id'] = mso.lookup_schema(contract.get('schema')) if contract.get('template') is None: contract['template'] = template # Get schema_id schema_obj = mso.get_obj('schemas', displayName=schema) if not schema_obj: mso.fail_json( msg="Provided schema '{0}' does not exist".format(schema)) schema_path = 'schemas/{id}'.format(**schema_obj) # Get template templates = [t.get('name') for t in schema_obj.get('templates')] if template not in templates: mso.fail_json( msg="Provided template '{0}' does not exist. Existing templates: {1}" .format(template, ', '.join(templates))) template_idx = templates.index(template) # Get VRF vrfs = [ e.get('name') for e in schema_obj.get('templates')[template_idx]['vrfs'] ] if vrf not in vrfs: mso.fail_json( msg="Provided vrf '{vrf}' does not exist. Existing vrfs: {vrfs}". format(vrf=vrf, vrfs=', '.join(vrfs))) vrf_idx = vrfs.index(vrf) vrf_obj = schema_obj.get('templates')[template_idx]['vrfs'][vrf_idx] if not vrf_obj.get('vzAnyEnabled'): mso.fail_json( msg="vzAny attribute on vrf '{0}' is disabled.".format(vrf)) # Get Contract if contract: provider_contracts = [ c.get('contractRef') for c in schema_obj.get('templates') [template_idx]['vrfs'][vrf_idx]['vzAnyProviderContracts'] ] consumer_contracts = [ c.get('contractRef') for c in schema_obj.get('templates') [template_idx]['vrfs'][vrf_idx]['vzAnyConsumerContracts'] ] contract_ref = mso.contract_ref(**contract) if contract_ref in provider_contracts and contract.get( 'type') == 'provider': contract_idx = provider_contracts.index(contract_ref) contract_path = '/templates/{0}/vrfs/{1}/vzAnyProviderContracts/{2}'.format( template, vrf, contract_idx) mso.existing = schema_obj.get('templates')[template_idx]['vrfs'][ vrf_idx]['vzAnyProviderContracts'][contract_idx] if contract_ref in consumer_contracts and contract.get( 'type') == 'consumer': contract_idx = consumer_contracts.index(contract_ref) contract_path = '/templates/{0}/vrfs/{1}/vzAnyConsumerContracts/{2}'.format( template, vrf, contract_idx) mso.existing = schema_obj.get('templates')[template_idx]['vrfs'][ vrf_idx]['vzAnyConsumerContracts'][contract_idx] if mso.existing.get('contractRef'): mso.existing['contractRef'] = mso.dict_from_ref( mso.existing.get('contractRef')) mso.existing['relationshipType'] = contract.get('type') if state == 'query': if not contract: provider_contracts = [ dict(contractRef=mso.dict_from_ref(c.get('contractRef')), relationshipType='provider') for c in schema_obj.get('templates')[template_idx]['vrfs'] [vrf_idx]['vzAnyProviderContracts'] ] consumer_contracts = [ dict(contractRef=mso.dict_from_ref(c.get('contractRef')), relationshipType='consumer') for c in schema_obj.get('templates')[template_idx]['vrfs'] [vrf_idx]['vzAnyConsumerContracts'] ] mso.existing = provider_contracts + consumer_contracts elif not mso.existing: mso.fail_json( msg="Contract '{0}' not found".format(contract.get('name'))) mso.exit_json() if contract.get('type') == 'provider': contracts_path = '/templates/{0}/vrfs/{1}/vzAnyProviderContracts/-'.format( template, vrf) if contract.get('type') == 'consumer': contracts_path = '/templates/{0}/vrfs/{1}/vzAnyConsumerContracts/-'.format( template, vrf) ops = [] mso.previous = mso.existing if state == 'absent': if mso.existing: mso.sent = mso.existing = {} ops.append(dict(op='remove', path=contract_path)) elif state == 'present': payload = dict(contractRef=dict( contractName=contract.get('name'), templateName=contract.get('template'), schemaId=contract.get('schema_id'), ), ) mso.sanitize(payload, collate=True) if mso.existing: ops.append(dict(op='replace', path=contract_path, value=mso.sent)) else: ops.append(dict(op='add', path=contracts_path, value=mso.sent)) mso.existing = mso.proposed mso.existing['relationshipType'] = contract.get('type') if not module.check_mode and mso.proposed != mso.previous: mso.request(schema_path, method='PATCH', data=ops) mso.exit_json()
def main(): argument_spec = mso_argument_spec() argument_spec.update( schema=dict(type='str', required=True), template=dict(type='str', required=True), external_epg=dict(type='str', required=True), state=dict(type='str', default='present', choices=['absent', 'present', 'query']), subnet=dict(type='str', required=True), scope=dict(type='list', default=[]), aggregate=dict(type='list', default=[]), ) module = AnsibleModule( argument_spec=argument_spec, supports_check_mode=True, required_if=[ ['state', 'absent', ['subnet']], ['state', 'present', ['subnet']], ], ) schema = module.params['schema'] template = module.params['template'] external_epg = module.params['external_epg'] subnet = module.params['subnet'] scope = module.params['scope'] aggregate = module.params['aggregate'] state = module.params['state'] mso = MSOModule(module) # Get schema schema_obj = mso.get_obj('schemas', displayName=schema) if not schema_obj: mso.fail_json( msg="Provided schema '{0}' does not exist".format(schema)) schema_path = 'schemas/{id}'.format(**schema_obj) # Get template templates = [t['name'] for t in schema_obj['templates']] if template not in templates: mso.fail_json( msg= "Provided template '{template}' does not exist. Existing templates: {templates}" .format(template=template, templates=', '.join(templates))) template_idx = templates.index(template) # Get EPG external_epgs = [ e['name'] for e in schema_obj['templates'][template_idx]['externalEpgs'] ] if external_epg not in external_epgs: mso.fail_json( msg= "Provided External EPG '{epg}' does not exist. Existing epgs: {epgs}" .format(epg=external_epg, epgs=', '.join(external_epgs))) epg_idx = external_epgs.index(external_epg) # Get Subnet subnets = [ s['ip'] for s in schema_obj['templates'][template_idx]['externalEpgs'] [epg_idx]['subnets'] ] if subnet in subnets: subnet_idx = subnets.index(subnet) # FIXME: Changes based on index are DANGEROUS subnet_path = '/templates/{0}/externalEpgs/{1}/subnets/{2}'.format( template, external_epg, subnet_idx) mso.existing = schema_obj['templates'][template_idx]['externalEpgs'][ epg_idx]['subnets'][subnet_idx] if state == 'query': if subnet is None: mso.existing = schema_obj['templates'][template_idx][ 'externalEpgs'][epg_idx]['subnets'] elif not mso.existing: mso.fail_json(msg="Subnet '{subnet}' not found".format( subnet=subnet)) mso.exit_json() subnets_path = '/templates/{0}/externalEpgs/{1}/subnets'.format( template, external_epg) ops = [] mso.previous = mso.existing if state == 'absent': if mso.existing: mso.existing = {} ops.append(dict(op='remove', path=subnet_path)) elif state == 'present': payload = dict( ip=subnet, scope=scope, aggregate=aggregate, ) mso.sanitize(payload, collate=True) if mso.existing: ops.append(dict(op='replace', path=subnet_path, value=mso.sent)) else: ops.append(dict(op='add', path=subnets_path + '/-', value=mso.sent)) mso.existing = mso.proposed if not module.check_mode: mso.request(schema_path, method='PATCH', data=ops) mso.exit_json()
def main(): argument_spec = mso_argument_spec() argument_spec.update( schema=dict(type='str', required=True), template=dict(type='str', required=True), bd=dict(type='str', aliases=[ 'name' ]), # This parameter is not required for querying all objects display_name=dict(type='str'), description=dict(type='str'), intersite_bum_traffic=dict(type='bool'), optimize_wan_bandwidth=dict(type='bool'), layer2_stretch=dict(type='bool', default='true'), layer2_unknown_unicast=dict(type='str', choices=['flood', 'proxy']), layer3_multicast=dict(type='bool'), vrf=dict(type='dict', options=mso_reference_spec()), dhcp_policy=dict(type='dict', options=mso_dhcp_spec()), dhcp_policies=dict(type='list', elements='dict', options=mso_dhcp_spec()), subnets=dict(type='list', elements='dict', options=mso_bd_subnet_spec()), unknown_multicast_flooding=dict( type='str', choices=['optimized_flooding', 'flood']), multi_destination_flooding=dict( type='str', choices=['flood_in_bd', 'drop', 'encap-flood']), ipv6_unknown_multicast_flooding=dict( type='str', choices=['optimized_flooding', 'flood']), arp_flooding=dict(type='bool'), virtual_mac_address=dict(type='str'), unicast_routing=dict(type='bool', default=False), state=dict(type='str', default='present', choices=['absent', 'present', 'query']), ) module = AnsibleModule( argument_spec=argument_spec, supports_check_mode=True, required_if=[ ['state', 'absent', ['bd']], ['state', 'present', ['bd', 'vrf']], ], ) schema = module.params.get('schema') template = module.params.get('template').replace(' ', '') bd = module.params.get('bd') display_name = module.params.get('display_name') description = module.params.get('description') intersite_bum_traffic = module.params.get('intersite_bum_traffic') optimize_wan_bandwidth = module.params.get('optimize_wan_bandwidth') layer2_stretch = module.params.get('layer2_stretch') layer2_unknown_unicast = module.params.get('layer2_unknown_unicast') layer3_multicast = module.params.get('layer3_multicast') vrf = module.params.get('vrf') if vrf is not None and vrf.get('template') is not None: vrf['template'] = vrf.get('template').replace(' ', '') dhcp_policy = module.params.get('dhcp_policy') dhcp_policies = module.params.get('dhcp_policies') subnets = module.params.get('subnets') unknown_multicast_flooding = module.params.get( 'unknown_multicast_flooding') multi_destination_flooding = module.params.get( 'multi_destination_flooding') ipv6_unknown_multicast_flooding = module.params.get( 'ipv6_unknown_multicast_flooding') arp_flooding = module.params.get('arp_flooding') virtual_mac_address = module.params.get('virtual_mac_address') unicast_routing = module.params.get('unicast_routing') state = module.params.get('state') mso = MSOModule(module) # Map choices if unknown_multicast_flooding == 'optimized_flooding': unknown_multicast_flooding = 'opt-flood' if ipv6_unknown_multicast_flooding == 'optimized_flooding': ipv6_unknown_multicast_flooding = 'opt-flood' if multi_destination_flooding == 'flood_in_bd': multi_destination_flooding = 'bd-flood' if layer2_unknown_unicast == 'flood': arp_flooding = True # Get schema objects schema_id, schema_path, schema_obj = mso.query_schema(schema) # Get template templates = [t.get('name') for t in schema_obj.get('templates')] if template not in templates: mso.fail_json( msg="Provided template '{0}' does not exist. Existing templates: {1}" .format(template, ', '.join(templates))) template_idx = templates.index(template) # Get BDs bds = [ b.get('name') for b in schema_obj.get('templates')[template_idx]['bds'] ] if bd is not None and bd in bds: bd_idx = bds.index(bd) mso.existing = schema_obj.get('templates')[template_idx]['bds'][bd_idx] if state == 'query': if bd is None: mso.existing = schema_obj.get('templates')[template_idx]['bds'] elif not mso.existing: mso.fail_json(msg="BD '{bd}' not found".format(bd=bd)) mso.exit_json() bds_path = '/templates/{0}/bds'.format(template) bd_path = '/templates/{0}/bds/{1}'.format(template, bd) ops = [] mso.previous = mso.existing if state == 'absent': if mso.existing: mso.sent = mso.existing = {} ops.append(dict(op='remove', path=bd_path)) elif state == 'present': vrf_ref = mso.make_reference(vrf, 'vrf', schema_id, template) subnets = mso.make_subnets(subnets) dhcp_label = mso.make_dhcp_label(dhcp_policy) dhcp_labels = mso.make_dhcp_label(dhcp_policies) if display_name is None and not mso.existing: display_name = bd if subnets is None and not mso.existing: subnets = [] payload = dict( name=bd, displayName=display_name, intersiteBumTrafficAllow=intersite_bum_traffic, optimizeWanBandwidth=optimize_wan_bandwidth, l2UnknownUnicast=layer2_unknown_unicast, l2Stretch=layer2_stretch, l3MCast=layer3_multicast, subnets=subnets, vrfRef=vrf_ref, dhcpLabel=dhcp_label, unkMcastAct=unknown_multicast_flooding, multiDstPktAct=multi_destination_flooding, v6unkMcastAct=ipv6_unknown_multicast_flooding, vmac=virtual_mac_address, arpFlood=arp_flooding, ) if dhcp_labels: payload.update(dhcpLabels=dhcp_labels) if unicast_routing: payload.update(unicastRouting=unicast_routing) if description: payload.update(description=description) mso.sanitize(payload, collate=True, required=['dhcpLabel', 'dhcpLabels']) if mso.existing: ops.append(dict(op='replace', path=bd_path, value=mso.sent)) else: ops.append(dict(op='add', path=bds_path + '/-', value=mso.sent)) mso.existing = mso.proposed if 'bdRef' in mso.previous: del mso.previous['bdRef'] if 'vrfRef' in mso.previous: mso.previous['vrfRef'] = mso.vrf_dict_from_ref( mso.previous.get('vrfRef')) if not module.check_mode and mso.proposed != mso.previous: mso.request(schema_path, method='PATCH', data=ops) mso.exit_json()
def main(): argument_spec = mso_argument_spec() argument_spec.update( schema=dict(type='str', required=True), template=dict(type='str', required=True), bd=dict(type='str', required=True), subnet=dict(type='str', aliases=['ip']), description=dict(type='str'), is_virtual_ip=dict(type='bool', default=False), scope=dict(type='str', default='private', choices=['private', 'public']), shared=dict(type='bool', default=False), no_default_gateway=dict(type='bool', default=False), querier=dict(type='bool', default=False), state=dict(type='str', default='present', choices=['absent', 'present', 'query']), ) module = AnsibleModule( argument_spec=argument_spec, supports_check_mode=True, required_if=[ ['state', 'absent', ['subnet']], ['state', 'present', ['subnet']], ], ) schema = module.params.get('schema') template = module.params.get('template').replace(' ', '') bd = module.params.get('bd') subnet = module.params.get('subnet') description = module.params.get('description') is_virtual_ip = module.params.get('is_virtual_ip') scope = module.params.get('scope') shared = module.params.get('shared') no_default_gateway = module.params.get('no_default_gateway') querier = module.params.get('querier') state = module.params.get('state') mso = MSOModule(module) # Get schema schema_id, schema_path, schema_obj = mso.query_schema(schema) # Get template templates = [t.get('name') for t in schema_obj.get('templates')] if template not in templates: mso.fail_json( msg="Provided template '{0}' does not exist. Existing templates: {1}" .format(template, ', '.join(templates))) template_idx = templates.index(template) # Get BD bds = [ b.get('name') for b in schema_obj.get('templates')[template_idx]['bds'] ] if bd not in bds: mso.fail_json( msg="Provided BD '{0}' does not exist. Existing BDs: {1}".format( bd, ', '.join(bds))) bd_idx = bds.index(bd) # Get Subnet subnets = [ s.get('ip') for s in schema_obj.get('templates')[template_idx]['bds'] [bd_idx]['subnets'] ] if subnet in subnets: subnet_idx = subnets.index(subnet) # FIXME: Changes based on index are DANGEROUS subnet_path = '/templates/{0}/bds/{1}/subnets/{2}'.format( template, bd, subnet_idx) mso.existing = schema_obj.get( 'templates')[template_idx]['bds'][bd_idx]['subnets'][subnet_idx] if state == 'query': if subnet is None: mso.existing = schema_obj.get( 'templates')[template_idx]['bds'][bd_idx]['subnets'] elif not mso.existing: mso.fail_json(msg="Subnet IP '{subnet}' not found".format( subnet=subnet)) mso.exit_json() subnets_path = '/templates/{0}/bds/{1}/subnets'.format(template, bd) ops = [] mso.previous = mso.existing if state == 'absent': if mso.existing: mso.sent = mso.existing = {} ops.append(dict(op='remove', path=subnet_path)) elif state == 'present': if not mso.existing: if description is None: description = subnet payload = dict( ip=subnet, description=description, virtual=is_virtual_ip, scope=scope, shared=shared, noDefaultGateway=no_default_gateway, querier=querier, ) mso.sanitize(payload, collate=True) if mso.existing: ops.append(dict(op='replace', path=subnet_path, value=mso.sent)) else: ops.append(dict(op='add', path=subnets_path + '/-', value=mso.sent)) mso.existing = mso.proposed if not module.check_mode: mso.request(schema_path, method='PATCH', data=ops) mso.exit_json()
def main(): argument_spec = mso_argument_spec() argument_spec.update( schema=dict(type='str', required=True), site=dict(type='str', required=True), template=dict(type='str', required=True), vrf=dict(type='str', required=True), region=dict(type='str', aliases=['name']), # This parameter is not required for querying all objects vpn_gateway_router=dict(type='bool'), container_overlay=dict(type='bool'), underlay_context_profile=dict(type='dict', options=dict( vrf=dict(type='str', required=True), region=dict(type='str', required=True), )), state=dict(type='str', default='present', choices=['absent', 'present', 'query']), ) module = AnsibleModule( argument_spec=argument_spec, supports_check_mode=True, required_if=[ ['state', 'absent', ['region']], ['state', 'present', ['region']], ], ) schema = module.params.get('schema') site = module.params.get('site') template = module.params.get('template').replace(' ', '') vrf = module.params.get('vrf') region = module.params.get('region') vpn_gateway_router = module.params.get('vpn_gateway_router') container_overlay = module.params.get('container_overlay') underlay_context_profile = module.params.get('underlay_context_profile') state = module.params.get('state') mso = MSOModule(module) # Get schema objects schema_id, schema_path, schema_obj = mso.query_schema(schema) # Get site site_id = mso.lookup_site(site) # Get site_idx if 'sites' not in schema_obj: mso.fail_json(msg="No site associated with template '{0}'. Associate the site with the template using mso_schema_site.".format(template)) sites = [(s.get('siteId'), s.get('templateName')) for s in schema_obj.get('sites')] if (site_id, template) not in sites: mso.fail_json(msg="Provided site-template association '{0}-{1}' does not exist.".format(site, template)) # Schema-access uses indexes site_idx = sites.index((site_id, template)) # Path-based access uses site_id-template site_template = '{0}-{1}'.format(site_id, template) # Get VRF vrf_ref = mso.vrf_ref(schema_id=schema_id, template=template, vrf=vrf) vrfs = [v.get('vrfRef') for v in schema_obj.get('sites')[site_idx]['vrfs']] vrfs_name = [mso.dict_from_ref(v).get('vrfName') for v in vrfs] if vrf_ref not in vrfs: mso.fail_json(msg="Provided vrf '{0}' does not exist. Existing vrfs: {1}".format(vrf, ', '.join(vrfs_name))) vrf_idx = vrfs.index(vrf_ref) # Get Region regions = [r.get('name') for r in schema_obj.get('sites')[site_idx]['vrfs'][vrf_idx]['regions']] if region is not None and region in regions: region_idx = regions.index(region) region_path = '/sites/{0}/vrfs/{1}/regions/{2}'.format(site_template, vrf, region) mso.existing = schema_obj.get('sites')[site_idx]['vrfs'][vrf_idx]['regions'][region_idx] if state == 'query': if region is None: mso.existing = schema_obj.get('sites')[site_idx]['vrfs'][vrf_idx]['regions'] elif not mso.existing: mso.fail_json(msg="Region '{region}' not found".format(region=region)) mso.exit_json() regions_path = '/sites/{0}/vrfs/{1}/regions'.format(site_template, vrf) ops = [] mso.previous = mso.existing if state == 'absent': if mso.existing: mso.sent = mso.existing = {} ops.append(dict(op='remove', path=region_path)) elif state == 'present': payload = dict( name=region, isVpnGatewayRouter=vpn_gateway_router, ) if container_overlay: payload['contextProfileType'] = 'container-overlay' if mso.existing: underlay_dict = dict( vrfRef=dict( schemaId=schema_id, templateName=template, vrfName=underlay_context_profile['vrf'] ), regionName=underlay_context_profile['region'] ) payload['underlayCtxProfile'] = underlay_dict mso.sanitize(payload, collate=True) if mso.existing: ops.append(dict(op='replace', path=region_path, value=mso.sent)) else: ops.append(dict(op='add', path=regions_path + '/-', value=mso.sent)) mso.existing = mso.proposed if not module.check_mode: mso.request(schema_path, method='PATCH', data=ops) mso.exit_json()
def main(): argument_spec = mso_argument_spec() argument_spec.update( schema=dict(type='str', aliases=['name']), templates=dict(type='list'), sites=dict(type='list'), # messages=dict(type='dict'), # associations=dict(type='list'), # health_faults=dict(type='list'), # references=dict(type='dict'), # policy_states=dict(type='list'), state=dict(type='str', default='present', choices=['absent', 'present', 'query']), ) module = AnsibleModule( argument_spec=argument_spec, supports_check_mode=True, required_if=[ ['state', 'absent', ['schema']], ['state', 'present', ['schema', 'templates']], ], ) schema = module.params.get('schema') templates = module.params.get('templates') sites = module.params.get('sites') state = module.params.get('state') mso = MSOModule(module) schema_id = None path = 'schemas' # Query for existing object(s) if schema: mso.existing = mso.get_obj(path, displayName=schema) if mso.existing: schema_id = mso.existing.get('id') path = 'schemas/{id}'.format(id=schema_id) else: mso.existing = mso.query_objs(path) if state == 'query': pass elif state == 'absent': mso.previous = mso.existing if mso.existing: if module.check_mode: mso.existing = {} else: mso.existing = mso.request(path, method='DELETE') elif state == 'present': mso.previous = mso.existing payload = dict( id=schema_id, displayName=schema, templates=templates, sites=sites, ) mso.sanitize(payload, collate=True) if mso.existing: if mso.check_changed(): if module.check_mode: mso.existing = mso.proposed else: mso.existing = mso.request(path, method='PUT', data=mso.sent) else: if module.check_mode: mso.existing = mso.proposed else: mso.existing = mso.request(path, method='POST', data=mso.sent) mso.exit_json()
def main(): argument_spec = mso_argument_spec() argument_spec.update( schema=dict(type='str', required=True), site=dict(type='str', required=True), template=dict(type='str', required=True), anp=dict(type='str', aliases=[ 'name' ]), # This parameter is not required for querying all objects state=dict(type='str', default='present', choices=['absent', 'present', 'query']), ) module = AnsibleModule( argument_spec=argument_spec, supports_check_mode=True, required_if=[ ['state', 'absent', ['anp']], ['state', 'present', ['anp']], ], ) schema = module.params.get('schema') site = module.params.get('site') template = module.params.get('template') anp = module.params.get('anp') state = module.params.get('state') mso = MSOModule(module) # Get schema_id schema_obj = mso.get_obj('schemas', displayName=schema) if not schema_obj: mso.fail_json( msg="Provided schema '{0}' does not exist".format(schema)) schema_path = 'schemas/{id}'.format(**schema_obj) schema_id = schema_obj.get('id') # Get site site_id = mso.lookup_site(site) # Get site_idx sites = [(s.get('siteId'), s.get('templateName')) for s in schema_obj.get('sites')] if (site_id, template) not in sites: mso.fail_json( msg= "Provided site/template '{0}-{1}' does not exist. Existing sites/templates: {2}" .format(site, template, ', '.join(sites))) # Schema-access uses indexes site_idx = sites.index((site_id, template)) # Path-based access uses site_id-template site_template = '{0}-{1}'.format(site_id, template) # Get ANP anp_ref = mso.anp_ref(schema_id=schema_id, template=template, anp=anp) anps = [a.get('anpRef') for a in schema_obj.get('sites')[site_idx]['anps']] if anp is not None and anp_ref in anps: anp_idx = anps.index(anp_ref) anp_path = '/sites/{0}/anps/{1}'.format(site_template, anp) mso.existing = schema_obj.get('sites')[site_idx]['anps'][anp_idx] if state == 'query': if anp is None: mso.existing = schema_obj.get('sites')[site_idx]['anps'] elif not mso.existing: mso.fail_json(msg="ANP '{anp}' not found".format(anp=anp)) mso.exit_json() anps_path = '/sites/{0}/anps'.format(site_template) ops = [] mso.previous = mso.existing if state == 'absent': if mso.existing: mso.sent = mso.existing = {} ops.append(dict(op='remove', path=anp_path)) elif state == 'present': payload = dict(anpRef=dict( schemaId=schema_id, templateName=template, anpName=anp, ), ) mso.sanitize(payload, collate=True) if not mso.existing: ops.append(dict(op='add', path=anps_path + '/-', value=mso.sent)) mso.existing = mso.proposed if not module.check_mode: mso.request(schema_path, method='PATCH', data=ops) mso.exit_json()
def main(): argument_spec = mso_argument_spec() argument_spec.update( schema=dict(type='str', required=True), template=dict(type='str', required=True), anp=dict(type='str', required=True), epg=dict(type='str', required=True), contract=dict(type='dict', options=mso_contractref_spec()), state=dict(type='str', default='present', choices=['absent', 'present', 'query']), ) module = AnsibleModule( argument_spec=argument_spec, supports_check_mode=True, required_if=[ ['state', 'absent', ['contract']], ['state', 'present', ['contract']], ], ) schema = module.params.get('schema') template = module.params.get('template').replace(' ', '') anp = module.params.get('anp') epg = module.params.get('epg') contract = module.params.get('contract') if contract is not None and contract.get('template') is not None: contract['template'] = contract.get('template').replace(' ', '') state = module.params.get('state') mso = MSOModule(module) if contract: if contract.get('schema') is None: contract['schema'] = schema contract['schema_id'] = mso.lookup_schema(contract.get('schema')) if contract.get('template') is None: contract['template'] = template # Get schema schema_id, schema_path, schema_obj = mso.query_schema(schema) # Get template templates = [t.get('name') for t in schema_obj.get('templates')] if template not in templates: mso.fail_json( msg="Provided template '{0}' does not exist. Existing templates: {1}" .format(template, ', '.join(templates))) template_idx = templates.index(template) # Get ANP anps = [ a.get('name') for a in schema_obj.get('templates')[template_idx]['anps'] ] if anp not in anps: mso.fail_json( msg="Provided anp '{0}' does not exist. Existing anps: {1}".format( anp, ', '.join(anps))) anp_idx = anps.index(anp) # Get EPG epgs = [ e.get('name') for e in schema_obj.get('templates')[template_idx] ['anps'][anp_idx]['epgs'] ] if epg not in epgs: mso.fail_json( msg="Provided epg '{epg}' does not exist. Existing epgs: {epgs}". format(epg=epg, epgs=', '.join(epgs))) epg_idx = epgs.index(epg) # Get Contract if contract: contracts = [(c.get('contractRef'), c.get('relationshipType')) for c in schema_obj.get('templates')[template_idx]['anps'] [anp_idx]['epgs'][epg_idx]['contractRelationships']] contract_ref = mso.contract_ref(**contract) if (contract_ref, contract.get('type')) in contracts: contract_idx = contracts.index( (contract_ref, contract.get('type'))) contract_path = '/templates/{0}/anps/{1}/epgs/{2}/contractRelationships/{3}'.format( template, anp, epg, contract_idx) mso.existing = schema_obj.get( 'templates')[template_idx]['anps'][anp_idx]['epgs'][epg_idx][ 'contractRelationships'][contract_idx] if state == 'query': if not contract: mso.existing = schema_obj.get('templates')[template_idx]['anps'][ anp_idx]['epgs'][epg_idx]['contractRelationships'] elif not mso.existing: mso.fail_json(msg="Contract '{0}' not found".format(contract_ref)) if 'contractRef' in mso.existing: mso.existing['contractRef'] = mso.dict_from_ref( mso.existing.get('contractRef')) mso.exit_json() contracts_path = '/templates/{0}/anps/{1}/epgs/{2}/contractRelationships'.format( template, anp, epg) ops = [] mso.previous = mso.existing if state == 'absent': if mso.existing: mso.sent = mso.existing = {} ops.append(dict(op='remove', path=contract_path)) elif state == 'present': payload = dict( relationshipType=contract.get('type'), contractRef=dict( contractName=contract.get('name'), templateName=contract.get('template'), schemaId=contract.get('schema_id'), ), ) mso.sanitize(payload, collate=True) if mso.existing: ops.append(dict(op='replace', path=contract_path, value=mso.sent)) else: ops.append( dict(op='add', path=contracts_path + '/-', value=mso.sent)) mso.existing = mso.proposed if 'contractRef' in mso.previous: mso.previous['contractRef'] = mso.dict_from_ref( mso.previous.get('contractRef')) if not module.check_mode and mso.proposed != mso.previous: mso.request(schema_path, method='PATCH', data=ops) mso.exit_json()
def main(): argument_spec = mso_argument_spec() argument_spec.update( schema=dict(type='str', required=True), template=dict(type='str', required=True), contract=dict(type='str', required=True), contract_display_name=dict(type='str'), contract_scope=dict( type='str', choices=['application-profile', 'global', 'tenant', 'vrf']), contract_filter_type=dict(type='str', choices=['both-way', 'one-way']), filter=dict(type='str', aliases=[ 'name' ]), # This parameter is not required for querying all objects filter_directives=dict(type='list', choices=['log', 'none']), filter_template=dict(type='str'), filter_schema=dict(type='str'), filter_type=dict(type='str', default='both-way', choices=FILTER_KEYS.keys(), aliases=['type']), state=dict(type='str', default='present', choices=['absent', 'present', 'query']), ) module = AnsibleModule( argument_spec=argument_spec, supports_check_mode=True, required_if=[ ['state', 'absent', ['filter']], ['state', 'present', ['filter']], ], ) schema = module.params['schema'] template = module.params['template'] contract = module.params['contract'] contract_display_name = module.params['contract_display_name'] contract_filter_type = module.params['contract_filter_type'] contract_scope = module.params['contract_scope'] filter_name = module.params['filter'] filter_directives = module.params['filter_directives'] filter_template = module.params['filter_template'] filter_schema = module.params['filter_schema'] filter_type = module.params['filter_type'] state = module.params['state'] contract_ftype = 'bothWay' if contract_filter_type == 'both-way' else 'oneWay' if contract_filter_type == 'both-way' and filter_type != 'both-way': module.warn( "You are adding 'one-way' filters to a 'both-way' contract") elif contract_filter_type != 'both-way' and filter_type == 'both-way': module.warn( "You are adding 'both-way' filters to a 'one-way' contract") if filter_template is None: filter_template = template if filter_schema is None: filter_schema = schema filter_key = FILTER_KEYS[filter_type] mso = MSOModule(module) filter_schema_id = mso.lookup_schema(filter_schema) # Get schema object schema_obj = mso.get_obj('schemas', displayName=schema) if schema_obj: schema_id = schema_obj['id'] else: mso.fail_json( msg="Provided schema '{0}' does not exist".format(schema)) schema_path = 'schemas/{id}'.format(**schema_obj) # Get template templates = [t['name'] for t in schema_obj['templates']] if template not in templates: mso.fail_json( msg="Provided template '{0}' does not exist. Existing templates: {1}" .format(template, ', '.join(templates))) template_idx = templates.index(template) # Get contracts mso.existing = {} contract_idx = None filter_idx = None contracts = [ c['name'] for c in schema_obj['templates'][template_idx]['contracts'] ] if contract in contracts: contract_idx = contracts.index(contract) filters = [ f['filterRef'] for f in schema_obj['templates'][template_idx] ['contracts'][contract_idx][filter_key] ] filter_ref = mso.filter_ref(schema_id=filter_schema_id, template=filter_template, filter=filter_name) if filter_ref in filters: filter_idx = filters.index(filter_ref) filter_path = '/templates/{0}/contracts/{1}/{2}/{3}'.format( template, contract, filter_key, filter_name) mso.existing = schema_obj['templates'][template_idx]['contracts'][ contract_idx][filter_key][filter_idx] if state == 'query': if contract_idx is None: mso.fail_json( msg= "Provided contract '{0}' does not exist. Existing contracts: {1}" .format(contract, ', '.join(contracts))) if filter_name is None: mso.existing = schema_obj['templates'][template_idx]['contracts'][ contract_idx][filter_key] elif not mso.existing: mso.fail_json(msg="FilterRef '{filter_ref}' not found".format( filter_ref=filter_ref)) mso.exit_json() ops = [] contract_path = '/templates/{0}/contracts/{1}'.format(template, contract) filters_path = '/templates/{0}/contracts/{1}/{2}'.format( template, contract, filter_key) mso.previous = mso.existing if state == 'absent': mso.proposed = mso.sent = {} if contract_idx is None: # There was no contract to begin with pass elif filter_idx is None: # There was no filter to begin with pass elif len(filters) == 1: # There is only one filter, remove contract mso.existing = {} ops.append(dict(op='remove', path=contract_path)) else: # Remove filter mso.existing = {} ops.append(dict(op='remove', path=filter_path)) elif state == 'present': if filter_directives is None: filter_directives = ['none'] payload = dict( filterRef=dict( filterName=filter_name, templateName=filter_template, schemaId=filter_schema_id, ), directives=filter_directives, ) mso.sanitize(payload, collate=True) mso.existing = mso.sent if contract_idx is None: # Contract does not exist, so we have to create it if contract_display_name is None: contract_display_name = contract if contract_filter_type is None: contract_ftype = 'bothWay' if contract_scope is None: contract_scope = 'context' payload = { 'name': contract, 'displayName': contract_display_name, 'filterType': contract_ftype, 'scope': contract_scope, } ops.append( dict(op='add', path='/templates/{0}/contracts/-'.format(template), value=payload)) else: # Contract exists, but may require an update if contract_display_name is not None: ops.append( dict(op='replace', path=contract_path + '/displayName', value=contract_display_name)) if contract_filter_type is not None: ops.append( dict(op='replace', path=contract_path + '/filterType', value=contract_ftype)) if contract_scope is not None: ops.append( dict(op='replace', path=contract_path + '/scope', value=contract_scope)) if filter_idx is None: # Filter does not exist, so we have to add it ops.append(dict(op='add', path=filters_path + '/-', value=mso.sent)) else: # Filter exists, we have to update it ops.append(dict(op='replace', path=filter_path, value=mso.sent)) if not module.check_mode: mso.request(schema_path, method='PATCH', data=ops) mso.exit_json()
def main(): argument_spec = mso_argument_spec() argument_spec.update( schema=dict(type='str', required=True), site=dict(type='str', required=True), template=dict(type='str', required=True), anp=dict(type='str', required=True), epg=dict(type='str', required=True), state=dict(type='str', default='present', choices=['absent', 'present', 'query']), ) argument_spec.update(mso_epg_subnet_spec()) module = AnsibleModule( argument_spec=argument_spec, supports_check_mode=True, required_if=[ ['state', 'absent', ['subnet']], ['state', 'present', ['subnet']], ], ) schema = module.params.get('schema') site = module.params.get('site') template = module.params.get('template').replace(' ', '') anp = module.params.get('anp') epg = module.params.get('epg') subnet = module.params.get('subnet') description = module.params.get('description') scope = module.params.get('scope') shared = module.params.get('shared') no_default_gateway = module.params.get('no_default_gateway') state = module.params.get('state') mso = MSOModule(module) # Get schema objects schema_id, schema_path, schema_obj = mso.query_schema(schema) # Get site site_id = mso.lookup_site(site) # Get site_idx if 'sites' not in schema_obj: mso.fail_json(msg="No site associated with template '{0}'. Associate the site with the template using mso_schema_site.".format(template)) sites = [(s.get('siteId'), s.get('templateName')) for s in schema_obj.get('sites')] if (site_id, template) not in sites: mso.fail_json(msg="Provided site/template '{0}-{1}' does not exist. Existing sites/templates: {2}".format(site, template, ', '.join(sites))) # Schema-access uses indexes site_idx = sites.index((site_id, template)) # Path-based access uses site_id-template site_template = '{0}-{1}'.format(site_id, template) # Get ANP anp_ref = mso.anp_ref(schema_id=schema_id, template=template, anp=anp) anps = [a.get('anpRef') for a in schema_obj.get('sites')[site_idx]['anps']] if anp_ref not in anps: mso.fail_json(msg="Provided anp '{0}' does not exist. Existing anps: {1}".format(anp, ', '.join(anps))) anp_idx = anps.index(anp_ref) # Get EPG epg_ref = mso.epg_ref(schema_id=schema_id, template=template, anp=anp, epg=epg) epgs = [e.get('epgRef') for e in schema_obj.get('sites')[site_idx]['anps'][anp_idx]['epgs']] if epg_ref not in epgs: mso.fail_json(msg="Provided epg '{0}' does not exist. Existing epgs: {1}".format(epg, ', '.join(epgs))) epg_idx = epgs.index(epg_ref) # Get Subnet subnets = [s.get('ip') for s in schema_obj.get('sites')[site_idx]['anps'][anp_idx]['epgs'][epg_idx]['subnets']] if subnet in subnets: subnet_idx = subnets.index(subnet) # FIXME: Changes based on index are DANGEROUS subnet_path = '/sites/{0}/anps/{1}/epgs/{2}/subnets/{3}'.format(site_template, anp, epg, subnet_idx) mso.existing = schema_obj.get('sites')[site_idx]['anps'][anp_idx]['epgs'][epg_idx]['subnets'][subnet_idx] if state == 'query': if subnet is None: mso.existing = schema_obj.get('sites')[site_idx]['anps'][anp_idx]['epgs'][epg_idx]['subnets'] elif not mso.existing: mso.fail_json(msg="Subnet '{subnet}' not found".format(subnet=subnet)) mso.exit_json() subnets_path = '/sites/{0}/anps/{1}/epgs/{2}/subnets'.format(site_template, anp, epg) ops = [] mso.previous = mso.existing if state == 'absent': if mso.existing: mso.sent = mso.existing = {} ops.append(dict(op='remove', path=subnet_path)) elif state == 'present': if not mso.existing: if description is None: description = subnet if scope is None: scope = 'private' if shared is None: shared = False if no_default_gateway is None: no_default_gateway = False payload = dict( ip=subnet, description=description, scope=scope, shared=shared, noDefaultGateway=no_default_gateway, ) mso.sanitize(payload, collate=True) if mso.existing: ops.append(dict(op='replace', path=subnet_path, value=mso.sent)) else: ops.append(dict(op='add', path=subnets_path + '/-', value=mso.sent)) mso.existing = mso.proposed if not module.check_mode: mso.request(schema_path, method='PATCH', data=ops) mso.exit_json()
def main(): argument_spec = mso_argument_spec() argument_spec.update( schema=dict(type='str', required=True), template=dict(type='str', required=True), externalepg=dict(type='str', aliases=[ 'name' ]), # This parameter is not required for querying all objects display_name=dict(type='str'), vrf=dict(type='dict', options=mso_reference_spec()), state=dict(type='str', default='present', choices=['absent', 'present', 'query']), ) module = AnsibleModule( argument_spec=argument_spec, supports_check_mode=True, required_if=[ ['state', 'absent', ['externalepg']], ['state', 'present', ['externalepg', 'vrf']], ], ) schema = module.params['schema'] template = module.params['template'] externalepg = module.params['externalepg'] display_name = module.params['display_name'] vrf = module.params['vrf'] state = module.params['state'] mso = MSOModule(module) # Get schema_id schema_obj = mso.get_obj('schemas', displayName=schema) if schema_obj: schema_id = schema_obj['id'] else: mso.fail_json( msg="Provided schema '{0}' does not exist".format(schema)) schema_path = 'schemas/{id}'.format(**schema_obj) # Get template templates = [t['name'] for t in schema_obj['templates']] if template not in templates: mso.fail_json( msg="Provided template '{0}' does not exist. Existing templates: {1}" .format(template, ', '.join(templates))) template_idx = templates.index(template) # Get external EPGs externalepgs = [ e['name'] for e in schema_obj['templates'][template_idx]['externalEpgs'] ] if externalepg is not None and externalepg in externalepgs: externalepg_idx = externalepgs.index(externalepg) mso.existing = schema_obj['templates'][template_idx]['externalEpgs'][ externalepg_idx] if state == 'query': if externalepg is None: mso.existing = schema_obj['templates'][template_idx][ 'externalEpgs'] elif not mso.existing: mso.fail_json(msg="External EPG '{externalepg}' not found".format( externalepg=externalepg)) mso.exit_json() eepgs_path = '/templates/{0}/externalEpgs'.format(template) eepg_path = '/templates/{0}/externalEpgs/{1}'.format(template, externalepg) ops = [] mso.previous = mso.existing if state == 'absent': if mso.existing: mso.sent = mso.existing = {} ops.append(dict(op='remove', path=eepg_path)) elif state == 'present': vrf_ref = mso.make_reference(vrf, 'vrf', schema_id, template) if display_name is None and not mso.existing: display_name = externalepg payload = dict( name=externalepg, displayName=display_name, vrfRef=vrf_ref, # FIXME subnets=[], contractRelationships=[], ) mso.sanitize(payload, collate=True) if mso.existing: ops.append(dict(op='replace', path=eepg_path, value=mso.sent)) else: ops.append(dict(op='add', path=eepgs_path + '/-', value=mso.sent)) mso.existing = mso.proposed if not module.check_mode: mso.request(schema_path, method='PATCH', data=ops) mso.exit_json()
def main(): argument_spec = mso_argument_spec() argument_spec.update( schema=dict(type='str', required=True), template=dict(type='str', required=True), external_epg=dict(type='str', aliases=['name', 'externalepg']), # This parameter is not required for querying all objects display_name=dict(type='str'), vrf=dict(type='dict', options=mso_reference_spec()), l3out=dict(type='dict', options=mso_reference_spec()), anp=dict(type='dict', options=mso_reference_spec()), preferred_group=dict(type='bool'), state=dict(type='str', default='present', choices=['absent', 'present', 'query']), ) module = AnsibleModule( argument_spec=argument_spec, supports_check_mode=True, required_if=[ ['state', 'absent', ['external_epg']], ['state', 'present', ['external_epg', 'vrf']], ], ) schema = module.params.get('schema') template = module.params.get('template') external_epg = module.params.get('external_epg') display_name = module.params.get('display_name') vrf = module.params.get('vrf') l3out = module.params.get('l3out') anp = module.params.get('anp') preferred_group = module.params.get('preferred_group') state = module.params.get('state') mso = MSOModule(module) # Get schema_id schema_obj = mso.get_obj('schemas', displayName=schema) if schema_obj: schema_id = schema_obj.get('id') else: mso.fail_json(msg="Provided schema '{0}' does not exist".format(schema)) schema_path = 'schemas/{id}'.format(**schema_obj) # Get template templates = [t.get('name') for t in schema_obj.get('templates')] if template not in templates: mso.fail_json(msg="Provided template '{0}' does not exist. Existing templates: {1}".format(template, ', '.join(templates))) template_idx = templates.index(template) # Get external EPGs external_epgs = [e.get('name') for e in schema_obj.get('templates')[template_idx]['externalEpgs']] if external_epg is not None and external_epg in external_epgs: external_epg_idx = external_epgs.index(external_epg) mso.existing = schema_obj.get('templates')[template_idx]['externalEpgs'][external_epg_idx] if 'externalEpgRef' in mso.existing: del mso.existing['externalEpgRef'] if 'vrfRef' in mso.existing: mso.existing['vrfRef'] = mso.dict_from_ref(mso.existing.get('vrfRef')) if 'l3outRef' in mso.existing: mso.existing['l3outRef'] = mso.dict_from_ref(mso.existing.get('l3outRef')) if 'anpRef' in mso.existing: mso.existing['anpRef'] = mso.dict_from_ref(mso.existing.get('anpRef')) if state == 'query': if external_epg is None: mso.existing = schema_obj.get('templates')[template_idx]['externalEpgs'] elif not mso.existing: mso.fail_json(msg="External EPG '{external_epg}' not found".format(external_epg=external_epg)) mso.exit_json() eepgs_path = '/templates/{0}/externalEpgs'.format(template) eepg_path = '/templates/{0}/externalEpgs/{1}'.format(template, external_epg) ops = [] mso.previous = mso.existing if state == 'absent': if mso.existing: mso.sent = mso.existing = {} ops.append(dict(op='remove', path=eepg_path)) elif state == 'present': vrf_ref = mso.make_reference(vrf, 'vrf', schema_id, template) l3out_ref = mso.make_reference(l3out, 'l3out', schema_id, template) anp_ref = mso.make_reference(anp, 'anp', schema_id, template) if display_name is None and not mso.existing: display_name = external_epg payload = dict( name=external_epg, displayName=display_name, vrfRef=vrf_ref, l3outRef=l3out_ref, preferredGroup=preferred_group, ) if anp is not None: payload['anpRef'] = anp_ref mso.sanitize(payload, collate=True) if mso.existing: # clean contractRef to fix api issue for contract in mso.sent.get('contractRelationships'): contract['contractRef'] = mso.dict_from_ref(contract.get('contractRef')) ops.append(dict(op='replace', path=eepg_path, value=mso.sent)) else: ops.append(dict(op='add', path=eepgs_path + '/-', value=mso.sent)) mso.existing = mso.proposed if not module.check_mode: mso.request(schema_path, method='PATCH', data=ops) mso.exit_json()
def main(): argument_spec = mso_argument_spec() argument_spec.update( schema=dict(type='str', required=True), template=dict(type='str', required=True), anp=dict(type='str', required=True), epg=dict(type='str', aliases=['name']), # This parameter is not required for querying all objects description=dict(type='str'), bd=dict(type='dict', options=mso_reference_spec()), vrf=dict(type='dict', options=mso_reference_spec()), display_name=dict(type='str'), useg_epg=dict(type='bool'), intra_epg_isolation=dict(type='str', choices=['enforced', 'unenforced']), intersite_multicast_source=dict(type='bool'), proxy_arp=dict(type='bool'), subnets=dict(type='list', elements='dict', options=mso_epg_subnet_spec()), qos_level=dict(type='str'), epg_type=dict(type='str', choices=['application', 'service']), deployment_type=dict(type='str', choices=['cloud_native', 'cloud_native_managed', 'third_party']), service_type=dict(type='str'), access_type=dict(type='str', choices=['private', 'public', 'public_and_private']), state=dict(type='str', default='present', choices=['absent', 'present', 'query']), preferred_group=dict(type='bool'), ) module = AnsibleModule( argument_spec=argument_spec, supports_check_mode=True, required_if=[ ['state', 'absent', ['epg']], ['state', 'present', ['epg']], ], ) schema = module.params.get('schema') template = module.params.get('template').replace(' ', '') anp = module.params.get('anp') epg = module.params.get('epg') description = module.params.get('description') display_name = module.params.get('display_name') bd = module.params.get('bd') if bd is not None and bd.get('template') is not None: bd['template'] = bd.get('template').replace(' ', '') vrf = module.params.get('vrf') if vrf is not None and vrf.get('template') is not None: vrf['template'] = vrf.get('template').replace(' ', '') useg_epg = module.params.get('useg_epg') intra_epg_isolation = module.params.get('intra_epg_isolation') intersite_multicast_source = module.params.get('intersite_multicast_source') proxy_arp = module.params.get('proxy_arp') subnets = module.params.get('subnets') qos_level = module.params.get('qos_level') epg_type = module.params.get('epg_type') deployment_type = module.params.get('deployment_type') service_type = module.params.get('service_type') access_type = module.params.get('access_type') state = module.params.get('state') preferred_group = module.params.get('preferred_group') mso = MSOModule(module) # Get schema objects schema_id, schema_path, schema_obj = mso.query_schema(schema) # Get template templates = [t.get('name') for t in schema_obj.get('templates')] if template not in templates: mso.fail_json(msg="Provided template '{0}' does not exist. Existing templates: {1}".format(template, ', '.join(templates))) template_idx = templates.index(template) # Get ANP anps = [a.get('name') for a in schema_obj.get('templates')[template_idx]['anps']] if anp not in anps: mso.fail_json(msg="Provided anp '{0}' does not exist. Existing anps: {1}".format(anp, ', '.join(anps))) anp_idx = anps.index(anp) # Get EPG epgs = [e.get('name') for e in schema_obj.get('templates')[template_idx]['anps'][anp_idx]['epgs']] if epg is not None and epg in epgs: epg_idx = epgs.index(epg) mso.existing = schema_obj.get('templates')[template_idx]['anps'][anp_idx]['epgs'][epg_idx] if state == 'query': if epg is None: mso.existing = schema_obj.get('templates')[template_idx]['anps'][anp_idx]['epgs'] elif not mso.existing: mso.fail_json(msg="EPG '{epg}' not found".format(epg=epg)) if 'bdRef' in mso.existing: mso.existing['bdRef'] = mso.dict_from_ref(mso.existing['bdRef']) if 'vrfRef' in mso.existing: mso.existing['vrfRef'] = mso.dict_from_ref(mso.existing['vrfRef']) mso.exit_json() epgs_path = '/templates/{0}/anps/{1}/epgs'.format(template, anp) epg_path = '/templates/{0}/anps/{1}/epgs/{2}'.format(template, anp, epg) service_path = '{0}/cloudServiceEpgConfig'.format(epg_path) ops = [] cloud_service_epg_config = {} mso.previous = mso.existing if state == 'absent': if mso.existing: mso.sent = mso.existing = {} ops.append(dict(op='remove', path=epg_path)) elif state == 'present': bd_ref = mso.make_reference(bd, 'bd', schema_id, template) vrf_ref = mso.make_reference(vrf, 'vrf', schema_id, template) subnets = mso.make_subnets(subnets, is_bd_subnet=False) if display_name is None and not mso.existing: display_name = epg payload = dict( name=epg, displayName=display_name, uSegEpg=useg_epg, intraEpg=intra_epg_isolation, mCastSource=intersite_multicast_source, proxyArp=proxy_arp, # FIXME: Missing functionality # uSegAttrs=[], subnets=subnets, bdRef=bd_ref, preferredGroup=preferred_group, vrfRef=vrf_ref, ) if description is not None: payload.update(description=description) if qos_level is not None: payload.update(prio=qos_level) if epg_type is not None: payload.update(epgType=epg_type) mso.sanitize(payload, collate=True) if mso.existing: # Clean contractRef to fix api issue for contract in mso.sent.get('contractRelationships'): contract['contractRef'] = mso.dict_from_ref(contract.get('contractRef')) ops.append(dict(op='replace', path=epg_path, value=mso.sent)) else: ops.append(dict(op='add', path=epgs_path + '/-', value=mso.sent)) if epg_type == 'service': access_type_map = { 'private': 'Private', 'public': 'Public', 'public_and_private': 'PublicAndPrivate', } deployment_type_map = { 'cloud_native': 'CloudNative', 'cloud_native_managed': 'CloudNativeManaged', 'third_party': 'Third-party', } if cloud_service_epg_config != {}: cloud_service_epg_config.update(dict( deploymentType=deployment_type_map[deployment_type], serviceType=service_type, accessType=access_type_map[access_type])) ops.append(dict(op='replace', path=service_path, value=cloud_service_epg_config)) else: cloud_service_epg_config.update(dict( deploymentType=deployment_type_map[deployment_type], serviceType=service_type, accessType=access_type_map[access_type])) ops.append(dict(op='add', path=service_path, value=cloud_service_epg_config)) mso.existing = mso.proposed if 'epgRef' in mso.previous: del mso.previous['epgRef'] if 'bdRef' in mso.previous and mso.previous['bdRef'] != '': mso.previous['bdRef'] = mso.dict_from_ref(mso.previous['bdRef']) if 'vrfRef' in mso.previous and mso.previous['bdRef'] != '': mso.previous['vrfRef'] = mso.dict_from_ref(mso.previous['vrfRef']) if not module.check_mode and mso.proposed != mso.previous: mso.request(schema_path, method='PATCH', data=ops) mso.exit_json()
def main(): argument_spec = mso_argument_spec() argument_spec.update( location_type=dict(type='str', default='local', choices=['local', 'remote']), description=dict(type='str'), backup=dict(type='str', aliases=['name']), remote_location=dict(type='str'), remote_path=dict(type='str'), state=dict(type='str', default='present', choices=['absent', 'present', 'query']), ) module = AnsibleModule( argument_spec=argument_spec, supports_check_mode=True, required_if=[['location_type', 'remote', ['remote_location']], ['state', 'absent', ['backup']], ['state', 'present', ['backup']]]) description = module.params.get('description') location_type = module.params.get('location_type') state = module.params.get('state') backup = module.params.get('backup') remote_location = module.params.get('remote_location') remote_path = module.params.get('remote_path') mso = MSOModule(module) backup_names = [] mso.existing = mso.query_objs('backups/backupRecords', key='backupRecords') if backup: if mso.existing: data = mso.existing mso.existing = [] for backup_info in data: if backup == backup_info.get('name').split( '_')[0] or backup == backup_info.get('name'): mso.existing.append(backup_info) backup_names.append(backup_info.get('name')) if state == 'query': mso.exit_json() if state == 'absent': mso.previous = mso.existing if len(mso.existing) > 1: mso.module.fail_json( msg= "Multiple backups with same name found. Existing backups with similar names: {0}" .format(', '.join(backup_names))) elif len(mso.existing) == 1: if module.check_mode: mso.existing = {} else: mso.existing = mso.request('backups/backupRecords/{id}'.format( id=mso.existing[0].get('id')), method='DELETE') mso.exit_json() path = 'backups' if state == 'present': mso.previous = mso.existing payload = dict(name=backup, description=description, locationType=location_type) if location_type == 'remote': remote_location_info = mso.lookup_remote_location(remote_location) payload.update(remoteLocationId=remote_location_info.get('id')) if remote_path: remote_path = '{0}/{1}'.format( remote_location_info.get('path'), remote_path) payload.update(remotePath=remote_path) mso.proposed = payload if module.check_mode: mso.existing = mso.proposed else: mso.existing = mso.request(path, method='POST', data=payload) mso.exit_json()
def main(): argument_spec = mso_argument_spec() argument_spec.update( schema=dict(type='str', required=True), site=dict(type='str', required=True), template=dict(type='str', required=True), vrf=dict(type='str', required=True), region=dict(type='str', required=True), cidr=dict(type='str', required=True), subnet=dict(type='str', aliases=[ 'ip' ]), # This parameter is not required for querying all objects zone=dict(type='str', aliases=['name']), vgw=dict(type='bool'), state=dict(type='str', default='present', choices=['absent', 'present', 'query']), ) module = AnsibleModule( argument_spec=argument_spec, supports_check_mode=True, required_if=[ ['state', 'absent', ['subnet']], ['state', 'present', ['subnet']], ], ) schema = module.params.get('schema') site = module.params.get('site') template = module.params.get('template') vrf = module.params.get('vrf') region = module.params.get('region') cidr = module.params.get('cidr') subnet = module.params.get('subnet') zone = module.params.get('zone') vgw = module.params.get('vgw') state = module.params.get('state') mso = MSOModule(module) # Get schema_id schema_obj = mso.get_obj('schemas', displayName=schema) if not schema_obj: mso.fail_json( msg="Provided schema '{0}' does not exist".format(schema)) schema_path = 'schemas/{id}'.format(**schema_obj) schema_id = schema_obj.get('id') # Get template templates = [t.get('name') for t in schema_obj.get('templates')] if template not in templates: mso.fail_json( msg="Provided template '{0}' does not exist. Existing templates: {1}" .format(template, ', '.join(templates))) # Get site site_id = mso.lookup_site(site) # Get site_idx if 'sites' not in schema_obj: mso.fail_json( msg= "No site associated with template '{0}'. Associate the site with the template using mso_schema_site." .format(template)) sites = [(s.get('siteId'), s.get('templateName')) for s in schema_obj.get('sites')] sites_list = [ s.get('siteId') + '/' + s.get('templateName') for s in schema_obj.get('sites') ] if (site_id, template) not in sites: mso.fail_json( msg="Provided site/siteId/template '{0}/{1}/{2}' does not exist. " "Existing siteIds/templates: {3}".format(site, site_id, template, ', '.join(sites_list))) # Schema-access uses indexes site_idx = sites.index((site_id, template)) # Path-based access uses site_id-template site_template = '{0}-{1}'.format(site_id, template) # Get VRF vrf_ref = mso.vrf_ref(schema_id=schema_id, template=template, vrf=vrf) vrfs = [v.get('vrfRef') for v in schema_obj.get('sites')[site_idx]['vrfs']] # If vrf not at site level but exists at template level if vrf_ref not in vrfs: mso.fail_json( msg="Provided vrf '{0}' does not exist at site level." " Use mso_schema_site_vrf_region_cidr to create it.".format(vrf)) vrf_idx = vrfs.index(vrf_ref) # Get Region regions = [ r.get('name') for r in schema_obj.get('sites')[site_idx]['vrfs'][vrf_idx]['regions'] ] if region not in regions: mso.fail_json( msg="Provided region '{0}' does not exist. Existing regions: {1}." " Use mso_schema_site_vrf_region_cidr to create it.".format( region, ', '.join(regions))) region_idx = regions.index(region) # Get CIDR cidrs = [ c.get('ip') for c in schema_obj.get('sites')[site_idx]['vrfs'][vrf_idx] ['regions'][region_idx]['cidrs'] ] if cidr not in cidrs: mso.fail_json( msg="Provided CIDR IP '{0}' does not exist. Existing CIDR IPs: {1}." " Use mso_schema_site_vrf_region_cidr to create it.".format( cidr, ', '.join(cidrs))) cidr_idx = cidrs.index(cidr) # Get Subnet subnets = [ s.get('ip') for s in schema_obj.get('sites')[site_idx]['vrfs'][vrf_idx] ['regions'][region_idx]['cidrs'][cidr_idx]['subnets'] ] if subnet is not None and subnet in subnets: subnet_idx = subnets.index(subnet) # FIXME: Changes based on index are DANGEROUS subnet_path = '/sites/{0}/vrfs/{1}/regions/{2}/cidrs/{3}/subnets/{4}'.format( site_template, vrf, region, cidr_idx, subnet_idx) mso.existing = schema_obj.get('sites')[site_idx]['vrfs'][vrf_idx][ 'regions'][region_idx]['cidrs'][cidr_idx]['subnets'][subnet_idx] if state == 'query': if subnet is None: mso.existing = schema_obj.get('sites')[site_idx]['vrfs'][vrf_idx][ 'regions'][region_idx]['cidrs'][cidr_idx]['subnets'] elif not mso.existing: mso.fail_json(msg="Subnet IP '{subnet}' not found".format( subnet=subnet)) mso.exit_json() subnets_path = '/sites/{0}/vrfs/{1}/regions/{2}/cidrs/{3}/subnets'.format( site_template, vrf, region, cidr_idx) ops = [] mso.previous = mso.existing if state == 'absent': if mso.existing: mso.sent = mso.existing = {} ops.append(dict(op='remove', path=subnet_path)) elif state == 'present': payload = dict(ip=subnet, zone="") if zone is not None: payload['zone'] = zone elif vgw is True: payload['usage'] = 'gateway' mso.sanitize(payload, collate=True) if mso.existing: ops.append(dict(op='replace', path=subnet_path, value=mso.sent)) else: ops.append(dict(op='add', path=subnets_path + '/-', value=mso.sent)) mso.existing = mso.proposed if not module.check_mode: mso.request(schema_path, method='PATCH', data=ops) mso.exit_json()
def main(): argument_spec = mso_argument_spec() argument_spec.update( source_schema=dict(type='str'), destination_schema=dict(type='str'), state=dict(type='str', default='clone', choices=['clone']), ) module = AnsibleModule( argument_spec=argument_spec, supports_check_mode=True, required_if=[ ['state', 'clone', ['destination_schema']], ], ) source_schema = module.params.get('source_schema') destination_schema = module.params.get('destination_schema') state = module.params.get('state') mso = MSOModule(module) # Get source schema details source_schema_path = "schemas/{0}".format(mso.lookup_schema(source_schema)) source_schema_obj = mso.query_obj(source_schema_path, displayName=source_schema) source_data = source_schema_obj.get('templates') source_data = json.loads( json.dumps(source_data).replace('/{0}'.format(source_schema_path), '')) path = 'schemas' # Check if source and destination schema are named differently if source_schema == destination_schema: mso.fail_json( msg="Source and Destination schema cannot have same names.") # Query for existing object(s) if destination_schema: mso.existing = mso.get_obj(path, displayName=destination_schema) if mso.existing: mso.fail_json( msg= "Schema with the name '{0}' already exists. Please use another name." .format(destination_schema)) if state == 'clone': mso.previous = mso.existing payload = dict( displayName=destination_schema, templates=source_data, ) mso.sanitize(payload, collate=True) if not mso.existing: if module.check_mode: mso.existing = mso.proposed else: mso.existing = mso.request(path, method='POST', data=mso.sent) mso.exit_json()
def main(): argument_spec = mso_argument_spec() argument_spec.update( schema=dict(type='str', required=True), template=dict(type='str', required=True), bd=dict(type='str', aliases=[ 'name' ]), # This parameter is not required for querying all objects display_name=dict(type='str'), intersite_bum_traffic=dict(type='bool'), optimize_wan_bandwidth=dict(type='bool'), layer2_stretch=dict(type='bool'), layer2_unknown_unicast=dict(type='str', choices=['flood', 'proxy']), layer3_multicast=dict(type='bool'), vrf=dict(type='dict', options=mso_reference_spec()), dhcp_policy=dict(type='dict', options=mso_dhcp_spec()), subnets=dict(type='list', options=mso_subnet_spec()), state=dict(type='str', default='present', choices=['absent', 'present', 'query']), ) module = AnsibleModule( argument_spec=argument_spec, supports_check_mode=True, required_if=[ ['state', 'absent', ['bd']], ['state', 'present', ['bd', 'vrf']], ], ) schema = module.params.get('schema') template = module.params.get('template') bd = module.params.get('bd') display_name = module.params.get('display_name') intersite_bum_traffic = module.params.get('intersite_bum_traffic') optimize_wan_bandwidth = module.params.get('optimize_wan_bandwidth') layer2_stretch = module.params.get('layer2_stretch') layer2_unknown_unicast = module.params.get('layer2_unknown_unicast') layer3_multicast = module.params.get('layer3_multicast') vrf = module.params.get('vrf') dhcp_policy = module.params.get('dhcp_policy') subnets = module.params.get('subnets') state = module.params.get('state') mso = MSOModule(module) # Get schema_id schema_obj = mso.get_obj('schemas', displayName=schema) if schema_obj: schema_id = schema_obj.get('id') else: mso.fail_json( msg="Provided schema '{0}' does not exist".format(schema)) schema_path = 'schemas/{id}'.format(**schema_obj) # Get template templates = [t.get('name') for t in schema_obj.get('templates')] if template not in templates: mso.fail_json( msg="Provided template '{0}' does not exist. Existing templates: {1}" .format(template, ', '.join(templates))) template_idx = templates.index(template) # Get BDs bds = [ b.get('name') for b in schema_obj.get('templates')[template_idx]['bds'] ] if bd is not None and bd in bds: bd_idx = bds.index(bd) mso.existing = schema_obj.get('templates')[template_idx]['bds'][bd_idx] if state == 'query': if bd is None: mso.existing = schema_obj.get('templates')[template_idx]['bds'] elif not mso.existing: mso.fail_json(msg="BD '{bd}' not found".format(bd=bd)) mso.exit_json() bds_path = '/templates/{0}/bds'.format(template) bd_path = '/templates/{0}/bds/{1}'.format(template, bd) ops = [] mso.previous = mso.existing if state == 'absent': if mso.existing: mso.sent = mso.existing = {} ops.append(dict(op='remove', path=bd_path)) elif state == 'present': vrf_ref = mso.make_reference(vrf, 'vrf', schema_id, template) subnets = mso.make_subnets(subnets) dhcp_label = mso.make_dhcp_label(dhcp_policy) if display_name is None and not mso.existing: display_name = bd if subnets is None and not mso.existing: subnets = [] payload = dict( name=bd, displayName=display_name, intersiteBumTrafficAllow=intersite_bum_traffic, optimizeWanBandwidth=optimize_wan_bandwidth, l2UnknownUnicast=layer2_unknown_unicast, l2Stretch=layer2_stretch, l3MCast=layer3_multicast, subnets=subnets, vrfRef=vrf_ref, dhcpLabel=dhcp_label, ) mso.sanitize(payload, collate=True) if mso.existing: ops.append(dict(op='replace', path=bd_path, value=mso.sent)) else: ops.append(dict(op='add', path=bds_path + '/-', value=mso.sent)) mso.existing = mso.proposed if 'bdRef' in mso.previous: del mso.previous['bdRef'] if 'vrfRef' in mso.previous: mso.previous['vrfRef'] = mso.vrf_dict_from_ref( mso.previous.get('vrfRef')) if not module.check_mode and mso.proposed != mso.previous: mso.request(schema_path, method='PATCH', data=ops) mso.exit_json()
def main(): location_arg_spec = dict( latitude=dict(type='float'), longitude=dict(type='float'), ) argument_spec = mso_argument_spec() argument_spec.update( apic_password=dict(type='str', no_log=True), apic_site_id=dict(type='str'), apic_username=dict(type='str', default='admin'), apic_login_domain=dict(type='str'), labels=dict(type='list', elements='str'), location=dict(type='dict', options=location_arg_spec), site=dict(type='str', aliases=['name']), state=dict(type='str', default='present', choices=['absent', 'present', 'query']), urls=dict(type='list', elements='str'), ) module = AnsibleModule( argument_spec=argument_spec, supports_check_mode=True, required_if=[ ['state', 'absent', ['site']], ['state', 'present', ['apic_site_id', 'site']], ], ) apic_username = module.params.get('apic_username') apic_password = module.params.get('apic_password') apic_site_id = module.params.get('apic_site_id') site = module.params.get('site') location = module.params.get('location') if location is not None: latitude = module.params.get('location')['latitude'] longitude = module.params.get('location')['longitude'] state = module.params.get('state') urls = module.params.get('urls') apic_login_domain = module.params.get('apic_login_domain') mso = MSOModule(module) site_id = None path = 'sites' api_version = 'v1' if mso.platform == 'nd': api_version = 'v2' # Convert labels labels = mso.lookup_labels(module.params.get('labels'), 'site') # Query for mso.existing object(s) if site: if mso.platform == 'nd': site_info = mso.get_obj(path, api_version=api_version, common=dict(name=site)) path = 'sites/manage' if site_info: # If we found an existing object, continue with it site_id = site_info.get('id') if site_id is not None and site_id != '': # Checking if site is managed by MSO mso.existing = site_info path = 'sites/manage/{id}'.format(id=site_id) else: mso.existing = mso.get_obj(path, name=site) if mso.existing: # If we found an existing object, continue with it site_id = mso.existing.get('id') path = 'sites/{id}'.format(id=site_id) else: mso.existing = mso.query_objs(path, api_version=api_version) if state == 'query': pass elif state == 'absent': mso.previous = mso.existing if mso.existing: if module.check_mode: mso.existing = {} else: mso.request(path, method='DELETE', qs=dict(force='true'), api_version=api_version) mso.existing = {} elif state == 'present': mso.previous = mso.existing if mso.platform == 'nd': if mso.existing: payload = mso.existing else: if site_info: payload = site_info payload['common']['siteId'] = apic_site_id else: mso.fail_json( msg= "Site '{0}' is not a valid Site configured at ND-level. Add Site to ND first." .format(site)) else: payload = dict( apicSiteId=apic_site_id, id=site_id, name=site, urls=urls, labels=labels, username=apic_username, password=apic_password, ) if location is not None: payload['location'] = dict( lat=latitude, long=longitude, ) if apic_login_domain is not None and apic_login_domain not in [ '', 'local', 'Local' ]: payload['username'] = '******'.format( apic_login_domain, apic_username) mso.sanitize(payload, collate=True) if mso.existing: if mso.check_changed(): if module.check_mode: mso.existing = mso.proposed else: mso.existing = mso.request(path, method='PUT', data=mso.sent, api_version=api_version) else: if module.check_mode: mso.existing = mso.proposed else: mso.existing = mso.request(path, method='POST', data=mso.sent, api_version=api_version) if 'password' in mso.existing: mso.existing['password'] = '******' mso.exit_json()
def main(): argument_spec = mso_argument_spec() argument_spec.update( schema=dict(type='str', required=True), template=dict(type='str', required=True), l3out=dict(type='str', aliases=[ 'name' ]), # This parameter is not required for querying all objects display_name=dict(type='str'), vrf=dict(type='dict', options=mso_reference_spec()), state=dict(type='str', default='present', choices=['absent', 'present', 'query']), ) module = AnsibleModule( argument_spec=argument_spec, supports_check_mode=True, required_if=[ ['state', 'absent', ['l3out']], ['state', 'present', ['l3out', 'vrf']], ], ) schema = module.params.get('schema') template = module.params.get('template') l3out = module.params.get('l3out') display_name = module.params.get('display_name') vrf = module.params.get('vrf') state = module.params.get('state') mso = MSOModule(module) # Get schema_id schema_obj = mso.get_obj('schemas', displayName=schema) if schema_obj: schema_id = schema_obj.get('id') else: mso.fail_json( msg="Provided schema '{0}' does not exist".format(schema)) schema_path = 'schemas/{id}'.format(**schema_obj) # Get template templates = [t.get('name') for t in schema_obj.get('templates')] if template not in templates: mso.fail_json( msg="Provided template '{0}' does not exist. Existing templates: {1}" .format(template, ', '.join(templates))) template_idx = templates.index(template) # Get L3out l3outs = [ l.get('name') for l in schema_obj.get('templates')[template_idx]['intersiteL3outs'] ] if l3out is not None and l3out in l3outs: l3out_idx = l3outs.index(l3out) mso.existing = schema_obj.get( 'templates')[template_idx]['intersiteL3outs'][l3out_idx] if state == 'query': if l3out is None: mso.existing = schema_obj.get( 'templates')[template_idx]['intersiteL3outs'] elif not mso.existing: mso.fail_json(msg="L3out '{l3out}' not found".format(l3out=l3out)) mso.exit_json() l3outs_path = '/templates/{0}/intersiteL3outs'.format(template) l3out_path = '/templates/{0}/intersiteL3outs/{1}'.format(template, l3out) ops = [] mso.previous = mso.existing if state == 'absent': if mso.existing: mso.sent = mso.existing = {} ops.append(dict(op='remove', path=l3out_path)) elif state == 'present': vrf_ref = mso.make_reference(vrf, 'vrf', schema_id, template) if display_name is None and not mso.existing: display_name = l3out payload = dict( name=l3out, displayName=display_name, vrfRef=vrf_ref, ) mso.sanitize(payload, collate=True) if mso.existing: ops.append(dict(op='replace', path=l3out_path, value=mso.sent)) else: ops.append(dict(op='add', path=l3outs_path + '/-', value=mso.sent)) mso.existing = mso.proposed if not module.check_mode: mso.request(schema_path, method='PATCH', data=ops) mso.exit_json()
def main(): argument_spec = mso_argument_spec() argument_spec.update( schema=dict(type='str', required=True), site=dict(type='str', required=True), template=dict(type='str', required=True), anp=dict(type='str', required=True), epg=dict(type='str', required=True), domain_association_type=dict(type='str', choices=['vmmDomain', 'l3ExtDomain', 'l2ExtDomain', 'physicalDomain', 'fibreChannelDomain']), domain_profile=dict(type='str'), deployment_immediacy=dict(type='str', choices=['immediate', 'lazy']), resolution_immediacy=dict(type='str', choices=['immediate', 'lazy', 'pre-provision']), state=dict(type='str', default='present', choices=['absent', 'present', 'query']), micro_seg_vlan_type=dict(type='str'), micro_seg_vlan=dict(type='int'), port_encap_vlan_type=dict(type='str'), port_encap_vlan=dict(type='int'), vlan_encap_mode=dict(type='str', choices=['static', 'dynamic']), allow_micro_segmentation=dict(type='bool'), switch_type=dict(type='str'), switching_mode=dict(type='str'), enhanced_lagpolicy_name=dict(type='str'), enhanced_lagpolicy_dn=dict(type='str'), ) module = AnsibleModule( argument_spec=argument_spec, supports_check_mode=True, required_if=[ ['state', 'absent', ['domain_association_type', 'domain_profile', 'deployment_immediacy', 'resolution_immediacy']], ['state', 'present', ['domain_association_type', 'domain_profile', 'deployment_immediacy', 'resolution_immediacy']], ], ) schema = module.params.get('schema') site = module.params.get('site') template = module.params.get('template') anp = module.params.get('anp') epg = module.params.get('epg') domain_association_type = module.params.get('domain_association_type') domain_profile = module.params.get('domain_profile') deployment_immediacy = module.params.get('deployment_immediacy') resolution_immediacy = module.params.get('resolution_immediacy') state = module.params.get('state') micro_seg_vlan_type = module.params.get('micro_seg_vlan_type') micro_seg_vlan = module.params.get('micro_seg_vlan') port_encap_vlan_type = module.params.get('port_encap_vlan_type') port_encap_vlan = module.params.get('port_encap_vlan') vlan_encap_mode = module.params.get('vlan_encap_mode') allow_micro_segmentation = module.params.get('allow_micro_segmentation') switch_type = module.params.get('switch_type') switching_mode = module.params.get('switching_mode') enhanced_lagpolicy_name = module.params.get('enhanced_lagpolicy_name') enhanced_lagpolicy_dn = module.params.get('enhanced_lagpolicy_dn') mso = MSOModule(module) # Get schema_id schema_obj = mso.get_obj('schemas', displayName=schema) if not schema_obj: mso.fail_json(msg="Provided schema '{0}' does not exist".format(schema)) schema_path = 'schemas/{id}'.format(**schema_obj) schema_id = schema_obj.get('id') # Get template templates = [t.get('name') for t in schema_obj.get('templates')] if template not in templates: mso.fail_json(msg="Provided template '{0}' does not exist. Existing templates: {1}".format(template, ', '.join(templates))) template_idx = templates.index(template) # Get site site_id = mso.lookup_site(site) # Get site_idx sites = [(s.get('siteId'), s.get('templateName')) for s in schema_obj.get('sites')] sites_list = [s.get('siteId') + '/' + s.get('templateName') for s in schema_obj.get('sites')] if (site_id, template) not in sites: mso.fail_json(msg="Provided site/siteId/template '{0}/{1}/{2}' does not exist. " "Existing siteIds/templates: {3}".format(site, site_id, template, ', '.join(sites_list))) # Schema-access uses indexes site_idx = sites.index((site_id, template)) # Path-based access uses site_id-template site_template = '{0}-{1}'.format(site_id, template) payload = dict() ops = [] op_path = '' # Get ANP anp_ref = mso.anp_ref(schema_id=schema_id, template=template, anp=anp) anps = [a.get('anpRef') for a in schema_obj['sites'][site_idx]['anps']] anps_path = '/sites/{0}/anps'.format(site_template) anps_in_temp = [a.get('name') for a in schema_obj['templates'][template_idx]['anps']] if anp not in anps_in_temp: mso.fail_json(msg="Provided anp '{0}' does not exist. Existing anps: {1}".format(anp, ', '.join(anps))) else: # Update anp index at template level template_anp_idx = anps_in_temp.index(anp) # If anp not at site level but exists at template level if anp_ref not in anps: op_path = '/sites/{0}/anps/-'.format(site_template) payload.update( anpRef=dict( schemaId=schema_id, templateName=template, anpName=anp, ), ) else: # Update anp index at site level anp_idx = anps.index(anp_ref) # Get EPG epg_ref = mso.epg_ref(schema_id=schema_id, template=template, anp=anp, epg=epg) # If anp exists at site level if 'anpRef' not in payload: epgs = [e.get('epgRef') for e in schema_obj['sites'][site_idx]['anps'][anp_idx]['epgs']] epgs_path = '/sites/{0}/anps/{1}/epgs'.format(site_template, anp) # If anp already at site level AND if epg not at site level (or) anp not at site level? if ('anpRef' not in payload and epg_ref not in epgs) or 'anpRef' in payload: epgs_in_temp = [e.get('name') for e in schema_obj['templates'][template_idx]['anps'][template_anp_idx]['epgs']] # If EPG not at template level - Fail if epg not in epgs_in_temp: mso.fail_json(msg="Provided EPG '{0}' does not exist. Existing EPGs: {1} epgref {2}".format(epg, ', '.join(epgs_in_temp), epg_ref)) # EPG at template level but not at site level. Create payload at site level for EPG else: new_epg = dict( epgRef=dict( schemaId=schema_id, templateName=template, anpName=anp, epgName=epg, ) ) # If anp not in payload then, anp already exists at site level. New payload will only have new EPG payload if 'anpRef' not in payload: op_path = '/sites/{0}/anps/{1}/epgs/-'.format(site_template, anp) payload = new_epg else: # If anp in payload, anp exists at site level. Update payload with EPG payload payload['epgs'] = [new_epg] # Update index of EPG at site level else: epg_idx = epgs.index(epg_ref) if domain_association_type == 'vmmDomain': domain_dn = 'uni/vmmp-VMware/dom-{0}'.format(domain_profile) elif domain_association_type == 'l3ExtDomain': domain_dn = 'uni/l3dom-{0}'.format(domain_profile) elif domain_association_type == 'l2ExtDomain': domain_dn = 'uni/l2dom-{0}'.format(domain_profile) elif domain_association_type == 'physicalDomain': domain_dn = 'uni/phys-{0}'.format(domain_profile) elif domain_association_type == 'fibreChannelDomain': domain_dn = 'uni/fc-{0}'.format(domain_profile) else: domain_dn = '' # Get Domains # If anp at site level and epg is at site level if 'anpRef' not in payload and 'epgRef' not in payload: domains = [dom.get('dn') for dom in schema_obj['sites'][site_idx]['anps'][anp_idx]['epgs'][epg_idx]['domainAssociations']] if domain_dn in domains: domain_idx = domains.index(domain_dn) domain_path = '/sites/{0}/anps/{1}/epgs/{2}/domainAssociations/{3}'.format(site_template, anp, epg, domain_idx) mso.existing = schema_obj['sites'][site_idx]['anps'][anp_idx]['epgs'][epg_idx]['domainAssociations'][domain_idx] if state == 'query': if domain_association_type is None or domain_profile is None: mso.existing = schema_obj.get('sites')[site_idx]['anps'][anp_idx]['epgs'][epg_idx]['domainAssociations'] elif not mso.existing: mso.fail_json(msg="Domain association '{domain_association_type}/{domain_profile}' not found".format( domain_association_type=domain_association_type, domain_profile=domain_profile)) mso.exit_json() domains_path = '/sites/{0}/anps/{1}/epgs/{2}/domainAssociations'.format(site_template, anp, epg) ops = [] new_domain = dict( dn=domain_dn, domainType=domain_association_type, deploymentImmediacy=deployment_immediacy, resolutionImmediacy=resolution_immediacy, ) if domain_association_type == 'vmmDomain': vmmDomainProperties = {} if micro_seg_vlan_type and micro_seg_vlan: microSegVlan = dict(vlanType=micro_seg_vlan_type, vlan=micro_seg_vlan) vmmDomainProperties['microSegVlan'] = microSegVlan elif not micro_seg_vlan_type and micro_seg_vlan: mso.fail_json(msg="micro_seg_vlan_type is required when micro_seg_vlan is provided.") elif micro_seg_vlan_type and not micro_seg_vlan: mso.fail_json(msg="micro_seg_vlan is required when micro_seg_vlan_type is provided.") if port_encap_vlan_type and port_encap_vlan: portEncapVlan = dict(vlanType=port_encap_vlan_type, vlan=port_encap_vlan) vmmDomainProperties['portEncapVlan'] = portEncapVlan elif not port_encap_vlan_type and port_encap_vlan: mso.fail_json(msg="port_encap_vlan_type is required when port_encap_vlan is provided.") elif port_encap_vlan_type and not port_encap_vlan: mso.fail_json(msg="port_encap_vlan is required when port_encap_vlan_type is provided.") if vlan_encap_mode: vmmDomainProperties['vlanEncapMode'] = vlan_encap_mode if allow_micro_segmentation: vmmDomainProperties['allowMicroSegmentation'] = allow_micro_segmentation if switch_type: vmmDomainProperties['switchType'] = switch_type if switching_mode: vmmDomainProperties['switchingMode'] = switching_mode if enhanced_lagpolicy_name and enhanced_lagpolicy_dn: enhancedLagPol = dict(name=enhanced_lagpolicy_name, dn=enhanced_lagpolicy_dn) epgLagPol = dict(enhancedLagPol=enhancedLagPol) vmmDomainProperties['epgLagPol'] = epgLagPol elif not enhanced_lagpolicy_name and enhanced_lagpolicy_dn: mso.fail_json(msg="enhanced_lagpolicy_name is required when enhanced_lagpolicy_dn is provided.") elif enhanced_lagpolicy_name and not enhanced_lagpolicy_dn: mso.fail_json(msg="enhanced_lagpolicy_dn is required when enhanced_lagpolicy_name is provided.") if vmmDomainProperties: new_domain['vmmDomainProperties'] = vmmDomainProperties # If payload is empty, anp and EPG already exist at site level if not payload: op_path = domains_path + '/-' payload = new_domain # If payload exists else: # If anp already exists at site level...(AND payload != epg as well?) if 'anpRef' not in payload: payload['domainAssociations'] = [new_domain] else: payload['epgs'][0]['domainAssociations'] = [new_domain] mso.previous = mso.existing if state == 'absent': if mso.existing: mso.sent = mso.existing = {} ops.append(dict(op='remove', path=domain_path)) elif state == 'present': mso.sanitize(payload, collate=True) if mso.existing: ops.append(dict(op='replace', path=domain_path, value=mso.sent)) else: ops.append(dict(op='add', path=op_path, value=mso.sent)) mso.existing = new_domain if not module.check_mode: mso.request(schema_path, method='PATCH', data=ops) mso.exit_json()
def main(): argument_spec = mso_argument_spec() argument_spec.update( schema=dict(type='str', required=True), site=dict(type='str', required=True), template=dict(type='str', required=True), vrf=dict(type='str', required=True), region=dict(type='str', required=True), cidr=dict(type='str', aliases=[ 'ip' ]), # This parameter is not required for querying all objects primary=dict(type='bool', default=True), state=dict(type='str', default='present', choices=['absent', 'present', 'query']), ) module = AnsibleModule( argument_spec=argument_spec, supports_check_mode=True, required_if=[ ['state', 'absent', ['cidr']], ['state', 'present', ['cidr']], ], ) schema = module.params.get('schema') site = module.params.get('site') template = module.params.get('template').replace(' ', '') vrf = module.params.get('vrf') region = module.params.get('region') cidr = module.params.get('cidr') primary = module.params.get('primary') state = module.params.get('state') mso = MSOModule(module) # Get schema objects schema_id, schema_path, schema_obj = mso.query_schema(schema) # Get template templates = [t.get('name') for t in schema_obj.get('templates')] if template not in templates: mso.fail_json( msg="Provided template '{0}' does not exist. Existing templates: {1}" .format(template, ', '.join(templates))) template_idx = templates.index(template) payload = dict() op_path = '' new_cidr = dict( ip=cidr, primary=primary, ) # Get site site_id = mso.lookup_site(site) # Get site_idx all_sites = schema_obj.get('sites') sites = [] if all_sites is not None: sites = [(s.get('siteId'), s.get('templateName')) for s in all_sites] # Get VRF vrf_ref = mso.vrf_ref(schema_id=schema_id, template=template, vrf=vrf) template_vrfs = [ a.get('name') for a in schema_obj['templates'][template_idx]['vrfs'] ] if vrf not in template_vrfs: mso.fail_json( msg="Provided vrf '{0}' does not exist. Existing vrfs: {1}".format( vrf, ', '.join(template_vrfs))) # if site-template does not exist, create it if (site_id, template) not in sites: op_path = '/sites/-' payload.update(siteId=site_id, templateName=template, vrfs=[ dict(vrfRef=dict( schemaId=schema_id, templateName=template, vrfName=vrf, ), regions=[dict(name=region, cidrs=[new_cidr])]) ]) else: # Schema-access uses indexes site_idx = sites.index((site_id, template)) # Path-based access uses site_id-template site_template = '{0}-{1}'.format(site_id, template) # If vrf not at site level but exists at template level vrfs = [ v.get('vrfRef') for v in schema_obj.get('sites')[site_idx]['vrfs'] ] if vrf_ref not in vrfs: op_path = '/sites/{0}/vrfs/-'.format(site_template) payload.update(vrfRef=dict( schemaId=schema_id, templateName=template, vrfName=vrf, ), regions=[dict(name=region, cidrs=[new_cidr])]) else: # Update vrf index at site level vrf_idx = vrfs.index(vrf_ref) # Get Region regions = [ r.get('name') for r in schema_obj.get('sites')[site_idx] ['vrfs'][vrf_idx]['regions'] ] if region not in regions: op_path = '/sites/{0}/vrfs/{1}/regions/-'.format( site_template, vrf) payload.update(name=region, cidrs=[new_cidr]) else: region_idx = regions.index(region) # Get CIDR cidrs = [ c.get('ip') for c in schema_obj.get('sites')[site_idx] ['vrfs'][vrf_idx]['regions'][region_idx]['cidrs'] ] if cidr is not None: if cidr in cidrs: cidr_idx = cidrs.index(cidr) # FIXME: Changes based on index are DANGEROUS cidr_path = '/sites/{0}/vrfs/{1}/regions/{2}/cidrs/{3}'.format( site_template, vrf, region, cidr_idx) mso.existing = schema_obj.get( 'sites')[site_idx]['vrfs'][vrf_idx]['regions'][ region_idx]['cidrs'][cidr_idx] op_path = '/sites/{0}/vrfs/{1}/regions/{2}/cidrs/-'.format( site_template, vrf, region) payload = new_cidr if state == 'query': if (site_id, template) not in sites: mso.fail_json( msg= "Provided site-template association '{0}-{1}' does not exist.". format(site, template)) elif vrf_ref not in vrfs: mso.fail_json( msg="Provided vrf '{0}' does not exist at site level.".format( vrf)) elif not regions or region not in regions: mso.fail_json( msg="Provided region '{0}' does not exist. Existing regions: {1}" .format(region, ', '.join(regions))) elif cidr is None and not payload: mso.existing = schema_obj.get('sites')[site_idx]['vrfs'][vrf_idx][ 'regions'][region_idx]['cidrs'] elif not mso.existing: mso.fail_json(msg="CIDR IP '{cidr}' not found".format(cidr=cidr)) mso.exit_json() ops = [] mso.previous = mso.existing if state == 'absent': if mso.existing: mso.sent = mso.existing = {} ops.append(dict(op='remove', path=cidr_path)) elif state == 'present': mso.sanitize(payload, collate=True) if mso.existing: ops.append(dict(op='replace', path=cidr_path, value=mso.sent)) else: ops.append(dict(op='add', path=op_path, value=mso.sent)) mso.existing = new_cidr if not module.check_mode and mso.previous != mso.existing: mso.request(schema_path, method='PATCH', data=ops) mso.exit_json()
def main(): argument_spec = mso_argument_spec() argument_spec.update( schema=dict(type='str', required=True), template=dict(type='str', required=True), anp=dict(type='str', required=True), epg=dict(type='str', required=True), state=dict(type='str', default='present', choices=['absent', 'present', 'query']), ) argument_spec.update(mso_subnet_spec()) module = AnsibleModule( argument_spec=argument_spec, supports_check_mode=True, required_if=[ ['state', 'absent', ['subnet']], ['state', 'present', ['subnet']], ], ) schema = module.params.get('schema') template = module.params.get('template') anp = module.params.get('anp') epg = module.params.get('epg') subnet = module.params.get('subnet') description = module.params.get('description') scope = module.params.get('scope') shared = module.params.get('shared') no_default_gateway = module.params.get('no_default_gateway') querier = module.params.get('querier') state = module.params.get('state') mso = MSOModule(module) # Get schema schema_obj = mso.get_obj('schemas', displayName=schema) if not schema_obj: mso.fail_json( msg="Provided schema '{0}' does not exist".format(schema)) schema_path = 'schemas/{id}'.format(**schema_obj) # Get template templates = [t.get('name') for t in schema_obj.get('templates')] if template not in templates: mso.fail_json( msg= "Provided template '{template}' does not exist. Existing templates: {templates}" .format(template=template, templates=', '.join(templates))) template_idx = templates.index(template) # Get ANP anps = [ a.get('name') for a in schema_obj.get('templates')[template_idx]['anps'] ] if anp not in anps: mso.fail_json( msg="Provided anp '{anp}' does not exist. Existing anps: {anps}". format(anp=anp, anps=', '.join(anps))) anp_idx = anps.index(anp) # Get EPG epgs = [ e.get('name') for e in schema_obj.get('templates')[template_idx] ['anps'][anp_idx]['epgs'] ] if epg not in epgs: mso.fail_json( msg="Provided epg '{epg}' does not exist. Existing epgs: {epgs}". format(epg=epg, epgs=', '.join(epgs))) epg_idx = epgs.index(epg) # Get Subnet subnets = [ s.get('ip') for s in schema_obj.get('templates')[template_idx]['anps'] [anp_idx]['epgs'][epg_idx]['subnets'] ] if subnet in subnets: subnet_idx = subnets.index(subnet) # FIXME: Changes based on index are DANGEROUS subnet_path = '/templates/{0}/anps/{1}/epgs/{2}/subnets/{3}'.format( template, anp, epg, subnet_idx) mso.existing = schema_obj.get('templates')[template_idx]['anps'][ anp_idx]['epgs'][epg_idx]['subnets'][subnet_idx] if state == 'query': if subnet is None: mso.existing = schema_obj.get('templates')[template_idx]['anps'][ anp_idx]['epgs'][epg_idx]['subnets'] elif not mso.existing: mso.fail_json(msg="Subnet '{subnet}' not found".format( subnet=subnet)) mso.exit_json() subnets_path = '/templates/{0}/anps/{1}/epgs/{2}/subnets'.format( template, anp, epg) ops = [] mso.previous = mso.existing if state == 'absent': if mso.existing: mso.existing = {} ops.append(dict(op='remove', path=subnet_path)) elif state == 'present': if not mso.existing: if description is None: description = subnet if scope is None: scope = 'private' if shared is None: shared = False if no_default_gateway is None: no_default_gateway = False if querier is None: querier = False payload = dict( ip=subnet, description=description, scope=scope, shared=shared, noDefaultGateway=no_default_gateway, querier=querier, ) mso.sanitize(payload, collate=True) if mso.existing: ops.append(dict(op='replace', path=subnet_path, value=mso.sent)) else: ops.append(dict(op='add', path=subnets_path + '/-', value=mso.sent)) mso.existing = mso.proposed if not module.check_mode: mso.request(schema_path, method='PATCH', data=ops) mso.exit_json()
def main(): argument_spec = mso_argument_spec() argument_spec.update( schema=dict(type='str', required=True), template=dict(type='str', required=True), contract=dict(type='str', required=True), description=dict(type='str'), contract_display_name=dict(type='str'), contract_scope=dict( type='str', choices=['application-profile', 'global', 'tenant', 'vrf']), contract_filter_type=dict(type='str', default='both-way', choices=['both-way', 'one-way']), filter=dict(type='str', aliases=[ 'name' ]), # This parameter is not required for querying all objects filter_directives=dict(type='list', elements='str', choices=['log', 'none', 'policy_compression']), filter_template=dict(type='str'), filter_schema=dict(type='str'), filter_type=dict(type='str', default='both-way', choices=list(FILTER_KEYS), aliases=['type']), qos_level=dict(type='str'), action=dict(type='str', choices=['permit', 'deny']), priority=dict(type='str', choices=[ 'default', 'lowest_priority', 'medium_priority', 'highest_priority' ]), state=dict(type='str', default='present', choices=['absent', 'present', 'query']), ) module = AnsibleModule( argument_spec=argument_spec, supports_check_mode=True, required_if=[ ['state', 'absent', ['filter']], ['state', 'present', ['filter']], ], ) schema = module.params.get('schema') template = module.params.get('template').replace(' ', '') contract = module.params.get('contract') contract_display_name = module.params.get('contract_display_name') description = module.params.get('description') contract_filter_type = module.params.get('contract_filter_type') contract_scope = module.params.get('contract_scope') filter_name = module.params.get('filter') filter_directives = module.params.get('filter_directives') filter_template = module.params.get('filter_template') if filter_template is not None: filter_template = filter_template.replace(' ', '') filter_schema = module.params.get('filter_schema') filter_type = module.params.get('filter_type') qos_level = module.params.get('qos_level') action = module.params.get('action') priority = module.params.get('priority') state = module.params.get('state') mso = MSOModule(module) contract_ftype = 'bothWay' if contract_filter_type == 'both-way' else 'oneWay' if contract_filter_type == 'both-way' and filter_type != 'both-way': mso.fail_json( msg="You are adding 'one-way' filters to a 'both-way' contract") elif contract_filter_type != 'both-way' and filter_type == 'both-way': mso.fail_json( msg="You are adding 'both-way' filters to a 'one-way' contract") if filter_template is None: filter_template = template if filter_schema is None: filter_schema = schema filter_key = FILTER_KEYS.get(filter_type) # Get schema schema_id, schema_path, schema_obj = mso.query_schema(schema) # Get template templates = [t.get('name') for t in schema_obj.get('templates')] if template not in templates: mso.fail_json( msg="Provided template '{0}' does not exist. Existing templates: {1}" .format(template, ', '.join(templates))) template_idx = templates.index(template) filter_schema_id = mso.lookup_schema(filter_schema) # Get contracts mso.existing = {} contract_idx = None filter_idx = None contracts = [ c.get('name') for c in schema_obj.get('templates')[template_idx]['contracts'] ] if contract in contracts: contract_idx = contracts.index(contract) contract_obj = schema_obj.get( 'templates')[template_idx]['contracts'][contract_idx] filters = [ f.get('filterRef') for f in schema_obj.get('templates') [template_idx]['contracts'][contract_idx][filter_key] ] filter_ref = mso.filter_ref(schema_id=filter_schema_id, template=filter_template, filter=filter_name) if filter_ref in filters: filter_idx = filters.index(filter_ref) filter_path = '/templates/{0}/contracts/{1}/{2}/{3}'.format( template, contract, filter_key, filter_name) filter = contract_obj.get(filter_key)[filter_idx] mso.existing = mso.update_filter_obj(contract_obj, filter, filter_type) if state == 'query': if contract_idx is None: mso.fail_json( msg= "Provided contract '{0}' does not exist. Existing contracts: {1}" .format(contract, ', '.join(contracts))) if filter_name is None: mso.existing = contract_obj.get(filter_key) for filter in mso.existing: filter = mso.update_filter_obj(contract_obj, filter, filter_type) elif not mso.existing: mso.fail_json(msg="FilterRef '{filter_ref}' not found".format( filter_ref=filter_ref)) mso.exit_json() ops = [] contract_path = '/templates/{0}/contracts/{1}'.format(template, contract) filters_path = '/templates/{0}/contracts/{1}/{2}'.format( template, contract, filter_key) mso.previous = mso.existing if state == 'absent': mso.proposed = mso.sent = {} if contract_idx is None: # There was no contract to begin with pass elif filter_idx is None: # There was no filter to begin with pass elif len(filters) == 1: # There is only one filter, remove contract mso.existing = {} ops.append(dict(op='remove', path=contract_path)) else: # Remove filter mso.existing = {} ops.append(dict(op='remove', path=filter_path)) elif state == 'present': if filter_directives is None: filter_directives = ['none'] if 'policy_compression' in filter_directives: filter_directives.remove('policy_compression') filter_directives.append('no_stats') payload = dict( filterRef=dict( filterName=filter_name, templateName=filter_template, schemaId=filter_schema_id, ), directives=filter_directives, ) if action is not None: payload.update(action=action) if action == 'deny' and priority is not None: priority_map = { 'lowest_priority': 'level1', 'medium_priority': 'level2', 'highest_priority': 'level3', } payload.update(priorityOverride=priority_map[priority]) mso.sanitize( payload, collate=True, unwanted=['filterType', 'contractScope', 'contractFilterType']) mso.existing = mso.sent if contract_scope is None or contract_scope == 'vrf': contract_scope = 'context' if contract_idx is None: # Contract does not exist, so we have to create it if contract_display_name is None: contract_display_name = contract payload = { 'name': contract, 'displayName': contract_display_name, 'filterType': contract_ftype, 'scope': contract_scope, } if description is not None: payload.update(description=description) if qos_level is not None: payload.update(prio=qos_level) ops.append( dict(op='add', path='/templates/{0}/contracts/-'.format(template), value=payload)) else: # Contract exists, but may require an update if contract_display_name is not None: ops.append( dict(op='replace', path=contract_path + '/displayName', value=contract_display_name)) ops.append( dict(op='replace', path=contract_path + '/filterType', value=contract_ftype)) ops.append( dict(op='replace', path=contract_path + '/scope', value=contract_scope)) if contract_display_name: mso.existing['displayName'] = contract_display_name else: mso.existing['displayName'] = contract_obj.get('displayName') mso.existing['filterType'] = filter_type mso.existing['contractScope'] = contract_scope mso.existing['contractFilterType'] = contract_ftype if filter_idx is None: # Filter does not exist, so we have to add it ops.append(dict(op='add', path=filters_path + '/-', value=mso.sent)) else: # Filter exists, we have to update it ops.append(dict(op='replace', path=filter_path, value=mso.sent)) if not module.check_mode and mso.existing != mso.previous: mso.request(schema_path, method='PATCH', data=ops) mso.exit_json()
def main(): argument_spec = mso_argument_spec() argument_spec.update( schema=dict(type='str', required=True), site=dict(type='str', required=True), template=dict(type='str', required=True), bd=dict(type='str', aliases=[ 'name' ]), # This parameter is not required for querying all objects host_route=dict(type='bool'), svi_mac=dict(type='str'), state=dict(type='str', default='present', choices=['absent', 'present', 'query']), ) module = AnsibleModule( argument_spec=argument_spec, supports_check_mode=True, required_if=[ ['state', 'absent', ['bd']], ['state', 'present', ['bd']], ], ) schema = module.params.get('schema') site = module.params.get('site') template = module.params.get('template').replace(' ', '') bd = module.params.get('bd') host_route = module.params.get('host_route') svi_mac = module.params.get('svi_mac') state = module.params.get('state') mso = MSOModule(module) # Get schema objects schema_id, schema_path, schema_obj = mso.query_schema(schema) # Get template templates = [t.get('name') for t in schema_obj.get('templates')] if template not in templates: mso.fail_json( msg="Provided template '{0}' does not exist. Existing templates: {1}" .format(template, ', '.join(templates))) # Get site site_id = mso.lookup_site(site) # Get site_idx if 'sites' not in schema_obj: mso.fail_json( msg= "No site associated with template '{0}'. Associate the site with the template using mso_schema_site." .format(template)) sites = [(s.get('siteId'), s.get('templateName')) for s in schema_obj.get('sites')] if (site_id, template) not in sites: mso.fail_json( msg="Provided site-template association '{0}-{1}' does not exist.". format(site, template)) # Schema-access uses indexes site_idx = sites.index((site_id, template)) # Path-based access uses site_id-template site_template = '{0}-{1}'.format(site_id, template) # Get BD bd_ref = mso.bd_ref(schema_id=schema_id, template=template, bd=bd) bds = [v.get('bdRef') for v in schema_obj.get('sites')[site_idx]['bds']] if bd is not None and bd_ref in bds: bd_idx = bds.index(bd_ref) bd_path = '/sites/{0}/bds/{1}'.format(site_template, bd) mso.existing = schema_obj.get('sites')[site_idx]['bds'][bd_idx] mso.existing['bdRef'] = mso.dict_from_ref(mso.existing.get('bdRef')) if state == 'query': if bd is None: mso.existing = schema_obj.get('sites')[site_idx]['bds'] for bd in mso.existing: bd['bdRef'] = mso.dict_from_ref(bd.get('bdRef')) elif not mso.existing: mso.fail_json(msg="BD '{bd}' not found".format(bd=bd)) mso.exit_json() bds_path = '/sites/{0}/bds'.format(site_template) ops = [] mso.previous = mso.existing if state == 'absent': if mso.existing: mso.sent = mso.existing = {} ops.append(dict(op='remove', path=bd_path)) elif state == 'present': if not mso.existing: if host_route is None: host_route = False payload = dict( bdRef=dict( schemaId=schema_id, templateName=template, bdName=bd, ), hostBasedRouting=host_route, ) if svi_mac is not None: payload.update(mac=svi_mac) mso.sanitize(payload, collate=True) if mso.existing: ops.append(dict(op='replace', path=bd_path, value=mso.sent)) else: ops.append(dict(op='add', path=bds_path + '/-', value=mso.sent)) mso.existing = mso.proposed if not module.check_mode and mso.existing != mso.previous: mso.request(schema_path, method='PATCH', data=ops) mso.exit_json()
def main(): argument_spec = mso_argument_spec() argument_spec.update( schema=dict(type='str', required=True), site=dict(type='str', required=True), template=dict(type='str', required=True), anp=dict(type='str', required=True), epg=dict(type='str', required=True), type=dict(type='str', default='port', choices=['port', 'vpc', 'dpc']), pod=dict(type='str' ), # This parameter is not required for querying all objects leaf=dict(type='str' ), # This parameter is not required for querying all objects fex=dict(type='str' ), # This parameter is not required for querying all objects path=dict(type='str' ), # This parameter is not required for querying all objects vlan=dict(type='int' ), # This parameter is not required for querying all objects primary_micro_segment_vlan=dict( type='int' ), # This parameter is not required for querying all objects deployment_immediacy=dict(type='str', default='lazy', choices=['immediate', 'lazy']), mode=dict(type='str', default='untagged', choices=['native', 'regular', 'untagged']), state=dict(type='str', default='present', choices=['absent', 'present', 'query']), ) module = AnsibleModule( argument_spec=argument_spec, supports_check_mode=True, required_if=[ ['state', 'absent', ['type', 'pod', 'leaf', 'path', 'vlan']], ['state', 'present', ['type', 'pod', 'leaf', 'path', 'vlan']], ], ) schema = module.params.get('schema') site = module.params.get('site') template = module.params.get('template').replace(' ', '') anp = module.params.get('anp') epg = module.params.get('epg') path_type = module.params.get('type') pod = module.params.get('pod') leaf = module.params.get('leaf') fex = module.params.get('fex') path = module.params.get('path') vlan = module.params.get('vlan') primary_micro_segment_vlan = module.params.get( 'primary_micro_segment_vlan') deployment_immediacy = module.params.get('deployment_immediacy') mode = module.params.get('mode') state = module.params.get('state') if path_type == 'port' and fex is not None: # Select port path for fex if fex param is used portpath = 'topology/{0}/paths-{1}/extpaths-{2}/pathep-[{3}]'.format( pod, leaf, fex, path) elif path_type == 'vpc': portpath = 'topology/{0}/protpaths-{1}/pathep-[{2}]'.format( pod, leaf, path) else: portpath = 'topology/{0}/paths-{1}/pathep-[{2}]'.format( pod, leaf, path) mso = MSOModule(module) # Get schema_id schema_obj = mso.get_obj('schemas', displayName=schema) if not schema_obj: mso.fail_json( msg="Provided schema '{0}' does not exist".format(schema)) schema_path = 'schemas/{id}'.format(**schema_obj) schema_id = schema_obj.get('id') # Get template templates = [t.get('name') for t in schema_obj.get('templates')] if template not in templates: mso.fail_json( msg="Provided template '{0}' does not exist. Existing templates: {1}" .format(template, ', '.join(templates))) template_idx = templates.index(template) # Get site site_id = mso.lookup_site(site) # Get site_idx if 'sites' not in schema_obj: mso.fail_json( msg= "No site associated with template '{0}'. Associate the site with the template using mso_schema_site." .format(template)) sites = [(s.get('siteId'), s.get('templateName')) for s in schema_obj.get('sites')] sites_list = [ s.get('siteId') + '/' + s.get('templateName') for s in schema_obj.get('sites') ] if (site_id, template) not in sites: mso.fail_json( msg="Provided site/siteId/template '{0}/{1}/{2}' does not exist. " "Existing siteIds/templates: {3}".format(site, site_id, template, ', '.join(sites_list))) # Schema-access uses indexes site_idx = sites.index((site_id, template)) # Path-based access uses site_id-template site_template = '{0}-{1}'.format(site_id, template) payload = dict() ops = [] op_path = '' # Get ANP anp_ref = mso.anp_ref(schema_id=schema_id, template=template, anp=anp) anps = [a.get('anpRef') for a in schema_obj['sites'][site_idx]['anps']] anps_in_temp = [ a.get('name') for a in schema_obj['templates'][template_idx]['anps'] ] if anp not in anps_in_temp: mso.fail_json( msg="Provided anp '{0}' does not exist. Existing anps: {1}".format( anp, ', '.join(anps))) else: # Update anp index at template level template_anp_idx = anps_in_temp.index(anp) # If anp not at site level but exists at template level if anp_ref not in anps: op_path = '/sites/{0}/anps/-'.format(site_template) payload.update(anpRef=dict( schemaId=schema_id, templateName=template, anpName=anp, ), ) else: # Update anp index at site level anp_idx = anps.index(anp_ref) # Get EPG epg_ref = mso.epg_ref(schema_id=schema_id, template=template, anp=anp, epg=epg) # If anp exists at site level if 'anpRef' not in payload: epgs = [ e.get('epgRef') for e in schema_obj['sites'][site_idx]['anps'][anp_idx]['epgs'] ] # If anp already at site level AND if epg not at site level (or) anp not at site level if ('anpRef' not in payload and epg_ref not in epgs) or 'anpRef' in payload: epgs_in_temp = [ e.get('name') for e in schema_obj['templates'][template_idx] ['anps'][template_anp_idx]['epgs'] ] # If EPG not at template level - Fail if epg not in epgs_in_temp: mso.fail_json( msg= "Provided EPG '{0}' does not exist. Existing EPGs: {1} epgref {2}" .format(epg, ', '.join(epgs_in_temp), epg_ref)) # EPG at template level but not at site level. Create payload at site level for EPG else: new_epg = dict(epgRef=dict( schemaId=schema_id, templateName=template, anpName=anp, epgName=epg, )) # If anp not in payload then, anp already exists at site level. New payload will only have new EPG payload if 'anpRef' not in payload: op_path = '/sites/{0}/anps/{1}/epgs/-'.format( site_template, anp) payload = new_epg else: # If anp in payload, anp exists at site level. Update payload with EPG payload payload['epgs'] = [new_epg] # Update index of EPG at site level else: epg_idx = epgs.index(epg_ref) # Get Leaf # If anp at site level and epg is at site level if 'anpRef' not in payload and 'epgRef' not in payload: portpaths = [ p.get('path') for p in schema_obj.get('sites')[site_idx]['anps'] [anp_idx]['epgs'][epg_idx]['staticPorts'] ] if portpath in portpaths: portpath_idx = portpaths.index(portpath) port_path = '/sites/{0}/anps/{1}/epgs/{2}/staticPorts/{3}'.format( site_template, anp, epg, portpath_idx) mso.existing = schema_obj.get('sites')[site_idx]['anps'][anp_idx][ 'epgs'][epg_idx]['staticPorts'][portpath_idx] if state == 'query': if leaf is None or vlan is None: mso.existing = schema_obj.get('sites')[site_idx]['anps'][anp_idx][ 'epgs'][epg_idx]['staticPorts'] elif not mso.existing: mso.fail_json(msg="Static port '{portpath}' not found".format( portpath=portpath)) mso.exit_json() ports_path = '/sites/{0}/anps/{1}/epgs/{2}/staticPorts'.format( site_template, anp, epg) ops = [] new_leaf = dict( deploymentImmediacy=deployment_immediacy, mode=mode, path=portpath, portEncapVlan=vlan, type=path_type, microSegVlan=primary_micro_segment_vlan, ) # If payload is empty, anp and EPG already exist at site level if not payload: op_path = ports_path + '/-' payload = new_leaf # If payload exists else: # If anp already exists at site level if 'anpRef' not in payload: payload['staticPorts'] = [new_leaf] else: payload['epgs'][0]['staticPorts'] = [new_leaf] mso.previous = mso.existing if state == 'absent': if mso.existing: mso.sent = mso.existing = {} ops.append(dict(op='remove', path=port_path)) elif state == 'present': mso.sanitize(payload, collate=True) if mso.existing: ops.append(dict(op='replace', path=port_path, value=mso.sent)) else: ops.append(dict(op='add', path=op_path, value=mso.sent)) mso.existing = new_leaf if not module.check_mode: mso.request(schema_path, method='PATCH', data=ops) mso.exit_json()
def main(): argument_spec = mso_argument_spec() argument_spec.update( schema=dict(type='str', required=True), site=dict(type='str', aliases=['name']), template=dict(type='str'), state=dict(type='str', default='present', choices=['absent', 'present', 'query']), ) module = AnsibleModule( argument_spec=argument_spec, supports_check_mode=True, required_if=[ ['state', 'absent', ['site', 'template']], ['state', 'present', ['site', 'template']], ], ) schema = module.params.get('schema') site = module.params.get('site') template = module.params.get('template') if template is not None: template = template.replace(' ', '') state = module.params.get('state') mso = MSOModule(module) # Get schema schema_id, schema_path, schema_obj = mso.query_schema(schema) # Get site site_id = mso.lookup_site(site) mso.existing = {} if 'sites' in schema_obj: sites = [(s.get('siteId'), s.get('templateName')) for s in schema_obj.get('sites')] if template: if (site_id, template) in sites: site_idx = sites.index((site_id, template)) site_path = '/sites/{0}'.format(site_idx) mso.existing = schema_obj.get('sites')[site_idx] else: mso.existing = schema_obj.get('sites') if state == 'query': if not mso.existing: if template: mso.fail_json(msg="Template '{0}' not found".format(template)) else: mso.existing = [] mso.exit_json() sites_path = '/sites' ops = [] mso.previous = mso.existing if state == 'absent': if mso.existing: # Remove existing site mso.sent = mso.existing = {} ops.append(dict(op='remove', path=site_path)) elif state == 'present': if not mso.existing: # Add new site payload = dict( siteId=site_id, templateName=template, anps=[], bds=[], contracts=[], externalEpgs=[], intersiteL3outs=[], serviceGraphs=[], vrfs=[], ) mso.sanitize(payload, collate=True) ops.append(dict(op='add', path=sites_path + '/-', value=mso.sent)) mso.existing = mso.proposed if not module.check_mode: mso.request(schema_path, method='PATCH', data=ops) mso.exit_json()