def main(): argument_spec = mso_argument_spec() argument_spec.update( schema=dict(type='str', required=True), template=dict(type='str', required=True, aliases=['name']), site=dict(type='str'), state=dict(type='str', default='deploy', choices=['deploy', 'status', 'undeploy']), ) module = AnsibleModule( argument_spec=argument_spec, supports_check_mode=True, required_if=[ ['state', 'undeploy', ['site']], ], ) schema = module.params.get('schema') template = module.params.get('template').replace(' ', '') site = module.params.get('site') state = module.params.get('state') mso = MSOModule(module) # Get schema id schema_id = mso.lookup_schema(schema) payload = dict( schemaId=schema_id, templateName=template, ) qs = None if state == 'deploy': path = 'execute/schema/{0}/template/{1}'.format(schema_id, template) elif state == 'status': path = 'status/schema/{0}/template/{1}'.format(schema_id, template) elif state == 'undeploy': path = 'execute/schema/{0}/template/{1}'.format(schema_id, template) site_id = mso.lookup_site(site) qs = dict(undeploy=site_id) if not module.check_mode: status = mso.request(path, method='GET', data=payload, qs=qs) mso.exit_json(**status) else: 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), site=dict(type='str', required=True), l3out=dict(type='str'), external_epg=dict(type='str', aliases=['name']), 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', 'l3out']], ], ) schema = module.params.get('schema') template = module.params.get('template') site = module.params.get('site') external_epg = module.params.get('external_epg') l3out = module.params.get('l3out') 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: if template in templates: template_idx = templates.index(template) path = 'tenants/{0}'.format( schema_obj.get('templates')[template_idx]['tenantId']) tenant_name = mso.request(path, method='GET').get('name') else: mso.fail_json( msg= "Provided template '{template}' does not exist. Existing templates: {templates}" .format(template=template, templates=', '.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 template '{0}' does not exist. Existing templates: {1}" .format(template, ', '.join(templates))) # 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() op_path = '/sites/{0}/externalEpgs/-'.format(site_template) # Get External EPG ext_epg_ref = mso.ext_epg_ref(schema_id=schema_id, template=template, external_epg=external_epg) external_epgs = [ e.get('externalEpgRef') for e in schema_obj.get('sites')[site_idx]['externalEpgs'] ] if ext_epg_ref in external_epgs: external_epg_idx = external_epgs.index(ext_epg_ref) # Get External EPG mso.existing = schema_obj['sites'][site_idx]['externalEpgs'][ external_epg_idx] op_path = '/sites/{0}/externalEpgs/{1}'.format(site_template, external_epg) ops = [] if state == 'query': if external_epg is None: mso.existing = schema_obj.get('sites')[site_idx]['externalEpgs'] elif not mso.existing: mso.fail_json(msg="External EPG '{external_epg}' not found".format( external_epg=external_epg)) mso.exit_json() mso.previous = mso.existing if state == 'absent': if mso.existing: mso.sent = mso.existing = {} ops.append(dict(op='remove', path=op_path)) elif state == 'present': l3out_dn = 'uni/tn-{0}/out-{1}'.format(tenant_name, l3out) payload = dict( externalEpgRef=dict( schemaId=schema_id, templateName=template, externalEpgName=external_epg, ), l3outDn=l3out_dn, l3outRef=dict( schemaId=schema_id, templateName=template, l3outName=l3out, ), ) mso.sanitize(payload, collate=True) if mso.existing: ops.append(dict(op='replace', path=op_path, value=mso.sent)) else: ops.append(dict(op='add', path=op_path, value=mso.sent)) mso.existing = mso.proposed 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), 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') 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', 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 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) 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), 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['schema'] site = module.params['site'] template = module.params['template'] anp = module.params['anp'] 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 ANP anp_ref = mso.anp_ref(schema_id=schema_id, template=template, anp=anp) anps = [a['anpRef'] for a in schema_obj['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['sites'][site_idx]['anps'][anp_idx] if state == 'query': if anp is None: mso.existing = schema_obj['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), site=dict(type='str', required=True), external_epg=dict(type='str', required=True), selector=dict(type='str'), expressions=dict(type='list', elements='dict', options=mso_expression_spec_ext_epg()), state=dict(type='str', default='present', choices=['absent', 'present', 'query']), ) module = AnsibleModule( argument_spec=argument_spec, supports_check_mode=True, ) schema = module.params.get('schema') template = module.params.get('template') site = module.params.get('site') external_epg = module.params.get('external_epg') selector = module.params.get('selector') expressions = module.params.get('expressions') 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 '{template}' does not exist. Existing templates: {templates}" .format(template=template, templates=', '.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) payload = dict() op_path = '' # Get External EPG ext_epg_ref = mso.ext_epg_ref(schema_id=schema_id, template=template, external_epg=external_epg) external_epgs = [ e.get('externalEpgRef') for e in schema_obj.get('sites')[site_idx]['externalEpgs'] ] if ext_epg_ref not in external_epgs: op_path = '/sites/{0}/externalEpgs/-'.format(site_template) payload = dict( externalEpgRef=dict( schemaId=schema_id, templateName=template, externalEpgName=external_epg, ), l3outDn='', ) else: external_epg_idx = external_epgs.index(ext_epg_ref) # Get Selector selectors = [ s.get('name') for s in schema_obj['sites'][site_idx] ['externalEpgs'][external_epg_idx]['subnets'] ] if selector in selectors: selector_idx = selectors.index(selector) selector_path = '/sites/{0}/externalEpgs/{1}/subnets/{2}'.format( site_template, external_epg, selector_idx) mso.existing = schema_obj['sites'][site_idx]['externalEpgs'][ external_epg_idx]['subnets'][selector_idx] selectors_path = '/sites/{0}/externalEpgs/{1}/subnets/-'.format( site_template, external_epg) ops = [] if state == 'query': if selector is None: mso.existing = schema_obj['sites'][site_idx]['externalEpgs'][ external_epg_idx]['subnets'] elif not mso.existing: mso.fail_json(msg="Selector '{selector}' not found".format( selector=selector)) mso.exit_json() mso.previous = mso.existing if state == 'absent': if mso.existing: mso.sent = mso.existing = {} ops.append(dict(op='remove', path=selector_path)) elif state == 'present': # Get expressions types = dict(ip_address='ipAddress') all_expressions = [] if expressions: for expression in expressions: type_val = expression.get('type') operator = expression.get('operator') value = expression.get('value') all_expressions.append( dict( key=types.get(type_val), operator=operator, value=value, )) else: mso.fail_json(msg="Missing expressions in selector") subnets = dict(name=selector, ip=all_expressions[0]['value']) if not external_epgs: payload['subnets'] = [subnets] else: payload = subnets op_path = selectors_path mso.sanitize(payload, collate=True) if mso.existing: ops.append(dict(op='replace', path=selector_path, value=mso.sent)) else: ops.append(dict(op='add', path=op_path, value=mso.sent)) mso.existing = mso.proposed 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), 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').replace(' ', '') anp = module.params.get('anp') 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')] 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 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 mso.existing: ops.append(dict(op='replace', path=anp_path, value=mso.sent)) else: 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), 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( 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 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', ['bd']], ['state', 'present', ['bd']], ], ) schema = module.params.get('schema') site = module.params.get('site') template = module.params.get('template') bd = module.params.get('bd') 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_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 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 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_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 Subnet subnets = [ s.get('ip') for s in schema_obj.get('sites')[site_idx]['bds'][bd_idx]['subnets'] ] if subnet in subnets: subnet_idx = subnets.index(subnet) # FIXME: Changes based on index are DANGEROUS subnet_path = '/sites/{0}/bds/{1}/subnets/{2}'.format( site_template, bd, subnet_idx) mso.existing = schema_obj.get( 'sites')[site_idx]['bds'][bd_idx]['subnets'][subnet_idx] if state == 'query': if subnet is None: mso.existing = schema_obj.get( 'sites')[site_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 = '/sites/{0}/bds/{1}/subnets'.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=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), site=dict(type='str', required=True), template=dict(type='str', required=True), anp=dict(type='str', required=True), epg=dict(type='str', required=True), selector=dict(type='str'), expressions=dict(type='list', elements='dict', options=mso_expression_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', ['selector']], ['state', 'present', ['selector']], ], ) 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') selector = module.params.get('selector') expressions = module.params.get('expressions') 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) # Get site site_id = mso.lookup_site(site) # Get cloud type site_type = mso.get_obj('sites', name=site).get("cloudProviders")[0] # 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) 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_in_temp))) else: # Get 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: # Get 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}". format(epg, ', '.join(epgs_in_temp))) # 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] # Get index of EPG at site level else: epg_idx = epgs.index(epg_ref) # Get selectors # If anp at site level and epg is at site level if 'anpRef' not in payload and 'epgRef' not in payload: if selector and " " in selector: mso.fail_json( msg="There should not be any space in selector name.") selectors = [ s.get('name') for s in schema_obj.get('sites')[site_idx]['anps'] [anp_idx]['epgs'][epg_idx]['selectors'] ] if selector in selectors: selector_idx = selectors.index(selector) selector_path = '/sites/{0}/anps/{1}/epgs/{2}/selectors/{3}'.format( site_template, anp, epg, selector_idx) mso.existing = schema_obj['sites'][site_idx]['anps'][anp_idx][ 'epgs'][epg_idx]['selectors'][selector_idx] if state == 'query': if 'anpRef' in payload: mso.fail_json( msg="Anp '{anp}' does not exist in site level.".format( anp=anp)) if 'epgRef' in payload: mso.fail_json( msg="Epg '{epg}' does not exist in site level.".format( epg=epg)) if selector is None: mso.existing = schema_obj['sites'][site_idx]['anps'][anp_idx][ 'epgs'][epg_idx]['selectors'] elif not mso.existing: mso.fail_json(msg="Selector '{selector}' not found".format( selector=selector)) mso.exit_json() mso.previous = mso.existing if state == 'absent': if mso.existing: mso.sent = mso.existing = {} ops.append(dict(op='remove', path=selector_path)) elif state == 'present': # Get expressions all_expressions = [] if expressions: for expression in expressions: type = expression.get('type') operator = expression.get('operator') value = expression.get('value') if " " in type: mso.fail_json( msg= "There should not be any space in 'type' attribute of expression '{0}'" .format(type)) if operator in ["has_key", "does_not_have_key"] and value: mso.fail_json( msg= "Attribute 'value' is not supported for operator '{0}' in expression '{1}'" .format(operator, type)) if operator in ["not_in", "in", "equals", "not_equals" ] and not value: mso.fail_json( msg= "Attribute 'value' needed for operator '{0}' in expression '{1}'" .format(operator, type)) if type in ["region", "zone", "ip_address"]: if type == "zone" and site_type != "aws": mso.fail_json( msg="Type 'zone' is only supported for aws") if operator in ["has_key", "does_not_have_key"]: mso.fail_json( msg= "Operator '{0}' is not supported when expression type is '{1}'" .format(operator, type)) type = EXPRESSION_KEYS.get(type) else: type = 'Custom:' + type all_expressions.append( dict( key=type, operator=EXPRESSION_OPERATORS.get(operator), value=value, )) new_selector = dict( name=selector, expressions=all_expressions, ) selectors_path = '/sites/{0}/anps/{1}/epgs/{2}/selectors/-'.format( site_template, anp, epg) # if payload is empty, anp and epg already exist at site level if not payload: op_path = selectors_path payload = new_selector # if payload exist else: # if anp already exists at site level if 'anpRef' not in payload: payload['selectors'] = [new_selector] else: payload['epgs'][0]['selectors'] = [new_selector] mso.sanitize(payload, collate=True) if mso.existing: ops.append(dict(op='replace', path=selector_path, value=mso.sent)) else: ops.append(dict(op='add', path=op_path, value=mso.sent)) mso.existing = new_selector 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), domain_association_type=dict(type='str', choices=[ 'vmmDomain', 'l3ExtDomain', 'l2ExtDomain', 'physicalDomain', 'fibreChannel' ]), 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['schema'] site = module.params['site'] template = module.params['template'] anp = module.params['anp'] epg = module.params['epg'] domain_association_type = module.params['domain_association_type'] domain_profile = module.params['domain_profile'] deployment_immediacy = module.params['deployment_immediacy'] resolution_immediacy = module.params['resolution_immediacy'] state = module.params['state'] micro_seg_vlan_type = module.params['micro_seg_vlan_type'] micro_seg_vlan = module.params['micro_seg_vlan'] port_encap_vlan_type = module.params['port_encap_vlan_type'] port_encap_vlan = module.params['port_encap_vlan'] vlan_encap_mode = module.params['vlan_encap_mode'] allow_micro_segmentation = module.params['allow_micro_segmentation'] switch_type = module.params['switch_type'] switching_mode = module.params['switching_mode'] enhanced_lagpolicy_name = module.params['enhanced_lagpolicy_name'] enhanced_lagpolicy_dn = module.params['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['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 ANP anp_ref = mso.anp_ref(schema_id=schema_id, template=template, anp=anp) anps = [a['anpRef'] for a in schema_obj['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) print(epg_ref) epgs = [ e['epgRef'] for e in schema_obj['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} epgref {2}". format(epg, str(schema_obj['sites'][site_idx]), epg_ref)) 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 == 'fibreChannel': domain_dn = 'uni/fc-{0}'.format(domain_profile) else: domain_dn = '' # Get Domains domains = [ dom['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['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 = [] 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 micro_seg_vlan_type and micro_seg_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." ) payload = dict( dn=domain_dn, domainType=domain_association_type, deploymentImmediacy=deployment_immediacy, resolutionImmediacy=resolution_immediacy, ) if vmmDomainProperties: payload['vmmDomainProperties'] = vmmDomainProperties else: payload = dict( dn=domain_dn, domainType=domain_association_type, deploymentImmediacy=deployment_immediacy, resolutionImmediacy=resolution_immediacy, ) mso.previous = mso.existing if state == 'absent': if mso.existing: mso.sent = mso.existing = {} ops.append(dict(op='remove', path=domains_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=domains_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), bd=dict(type='str', aliases=[ 'name' ]), # This parameter is not required for querying all objects host_route=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', ['bd']], ['state', 'present', ['bd']], ], ) schema = module.params.get('schema') site = module.params.get('site') template = module.params.get('template') bd = module.params.get('bd') host_route = module.params.get('host_route') 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 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] if state == 'query': if bd is None: mso.existing = schema_obj.get('sites')[site_idx]['bds'] 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, ) 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: 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.get('schema') site = module.params.get('site') template = module.params.get('template').replace(' ', '') bd = module.params.get('bd') l3out = module.params.get('l3out') 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) # 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) payload = dict() ops = [] op_path = '' # 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']] bds_in_temp = [ a.get('name') for a in schema_obj['templates'][template_idx]['bds'] ] if bd not in bds_in_temp: mso.fail_json( msg="Provided BD '{0}' does not exist. Existing BDs '{1}'".format( bd, ', '.join(bds_in_temp))) # If bd not at site level but exists at template level if bd_ref not in bds: op_path = '/sites/{0}/bds'.format(site_template) payload.update(bdRef=dict( schemaId=schema_id, templateName=template, bdName=bd, ), ) else: # Get bd index at site level bd_idx = bds.index(bd_ref) # Get L3out # If bd is at site level if 'bdRef' not in payload: l3outs = schema_obj.get('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 op_path = '/sites/{0}/bds/{1}/l3Outs/{2}'.format( site_template, bd, l3out_idx) mso.existing = schema_obj.get( 'sites')[site_idx]['bds'][bd_idx]['l3Outs'][l3out_idx] else: op_path = '/sites/{0}/bds/{1}/l3Outs'.format(site_template, bd) if state == 'query': if l3out is None: mso.existing = schema_obj.get( '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() ops = [] mso.previous = mso.existing if state == 'absent': if mso.existing: mso.sent = mso.existing = {} ops.append(dict(op='remove', path=op_path)) elif state == 'present': if not payload: payload = l3out else: # If bd in payload, add l3out to payload payload['l3Outs'] = [l3out] mso.sanitize(payload, collate=True) if not mso.existing: ops.append(dict(op='add', path=op_path + '/-', value=payload)) mso.existing = l3out 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', 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', ['epg']], ['state', 'present', ['epg']], ], ) 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') 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) 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 is not None and epg_ref in epgs: epg_idx = epgs.index(epg_ref) epg_path = '/sites/{0}/anps/{1}/epgs/{2}'.format( site_template, anp, epg) mso.existing = schema_obj.get( 'sites')[site_idx]['anps'][anp_idx]['epgs'][epg_idx] if state == 'query': if epg is None: mso.existing = schema_obj.get( 'sites')[site_idx]['anps'][anp_idx]['epgs'] elif not mso.existing: mso.fail_json(msg="EPG '{epg}' not found".format(epg=epg)) mso.exit_json() epgs_path = '/sites/{0}/anps/{1}/epgs'.format(site_template, anp) 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': payload = dict(epgRef=dict( schemaId=schema_id, templateName=template, anpName=anp, epgName=epg, ), ) mso.sanitize(payload, collate=True) if not mso.existing: ops.append(dict(op='add', path=epgs_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']), template=dict(type='str'), site=dict(type='str'), state=dict(type='str', default='query', choices=['query']), ) module = AnsibleModule( argument_spec=argument_spec, supports_check_mode=True, required_if=[ ['state', 'query', ['schema']], ], ) schema = module.params.get('schema') template = module.params.get('template') if template is not None: template = template.replace(' ', '') site = module.params.get('site') state = module.params.get('state') mso = MSOModule(module) schema_id = None path = 'schemas' get_schema = mso.get_obj(path, displayName=schema) if get_schema: schema_id = get_schema.get('id') path = 'schemas/{id}/policy-states'.format(id=schema_id) else: mso.fail_json(msg="Schema '{0}' not found.".format(schema)) if state == 'query': get_data = mso.request(path, method='GET') mso.existing = [] if template: for configuration_objects in get_data.get('policyStates'): if configuration_objects.get('templateName') == template: mso.existing.append(configuration_objects) if not mso.existing: mso.fail_json(msg="Template '{0}' not found.".format(template)) if site: mso.existing.clear() for configuration_objects in get_data.get('policyStates'): if configuration_objects.get('siteId') == mso.lookup_site(site): if template: if configuration_objects.get('templateName') == template: mso.existing = configuration_objects else: mso.existing.append(configuration_objects) if template is not None and not mso.existing: mso.fail_json(msg="Provided Template '{0}' not associated with Site '{1}'.".format(template, site)) if template is None and site is None: mso.existing = get_data 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', 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), vrf=dict(type='dict', options=mso_reference_spec()), 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', 'vrf']], ], ) schema = module.params.get('schema') site = module.params.get('site') template = module.params.get('template').replace(' ', '') l3out = module.params.get('l3out') vrf = module.params.get('vrf') 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 template '{0}' is not associated to site". format(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 l3out l3out_ref = mso.l3out_ref(schema_id=schema_id, template=template, l3out=l3out) l3outs = [ v.get('l3outRef') for v in schema_obj.get('sites')[site_idx]['intersiteL3outs'] ] if l3out is not None and l3out_ref in l3outs: l3out_idx = l3outs.index(l3out_ref) l3out_path = '/sites/{0}/intersiteL3outs/{1}'.format( site_template, l3out) mso.existing = schema_obj.get( 'sites')[site_idx]['intersiteL3outs'][l3out_idx] if state == 'query': if l3out is None: mso.existing = schema_obj.get('sites')[site_idx]['intersiteL3outs'] for l3out in mso.existing: l3out['l3outRef'] = mso.dict_from_ref(l3out.get('l3outRef')) elif not mso.existing: mso.fail_json(msg="L3Out '{l3out}' not found".format(l3out=l3out)) mso.exit_json() l3outs_path = '/sites/{0}/intersiteL3outs'.format(site_template) 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) payload = dict( l3outRef=dict( schemaId=schema_id, templateName=template, l3outName=l3out, ), 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), 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), 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']), 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 deployment_immediacy=dict(type='str', choices=['immediate', 'lazy']), mode=dict(type='str', 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['schema'] site = module.params['site'] template = module.params['template'] anp = module.params['anp'] epg = module.params['epg'] path_type = module.params['type'] pod = module.params['pod'] leaf = module.params['leaf'] fex = module.params['fex'] path = module.params['path'] vlan = module.params['vlan'] deployment_immediacy = module.params['deployment_immediacy'] mode = module.params['mode'] state = module.params['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) 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['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 ANP anp_ref = mso.anp_ref(schema_id=schema_id, template=template, anp=anp) anps = [a['anpRef'] for a in schema_obj['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['epgRef'] for e in schema_obj['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 Leaf portpaths = [ p['path'] for p in schema_obj['sites'][site_idx]['anps'][anp_idx] ['epgs'][epg_idx]['staticPorts'] ] if portpath in portpaths: portpath_idx = portpaths.index(portpath) # FIXME: Changes based on index are DANGEROUS port_path = '/sites/{0}/anps/{1}/epgs/{2}/staticPorts/{3}'.format( site_template, anp, epg, portpath_idx) mso.existing = schema_obj['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['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 = [] 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': if not mso.existing: if deployment_immediacy is None: deployment_immediacy = 'lazy' if mode is None: mode = 'untagged' payload = dict( deploymentImmediacy=deployment_immediacy, mode=mode, path=portpath, portEncapVlan=vlan, type=path_type, ) 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=ports_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', required=True), hub_network=dict(type='dict', options=mso_hub_network_spec()), state=dict(type='str', default='present', choices=['absent', 'present', 'query']), ) module = AnsibleModule( argument_spec=argument_spec, supports_check_mode=True, required_if=[ ['state', 'present', ['hub_network']], ], ) 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') hub_network = module.params.get('hub_network') 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 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 not in regions: mso.fail_json( msg="Provided region '{0}' does not exist. Existing regions: {1}". format(region, ', '.join(regions))) region_idx = regions.index(region) # Get Region object region_obj = schema_obj.get( 'sites')[site_idx]['vrfs'][vrf_idx]['regions'][region_idx] region_path = '/sites/{0}/vrfs/{1}/regions/{2}'.format( site_template, vrf, region) # Get hub network existing_hub_network = region_obj.get('cloudRsCtxProfileToGatewayRouterP') if existing_hub_network is not None: mso.existing = existing_hub_network if state == 'query': if not mso.existing: mso.fail_json(msg="Hub network not found") mso.exit_json() ops = [] mso.previous = mso.existing if state == 'absent': if mso.existing: mso.sent = mso.existing = {} ops.append( dict(op='remove', path=region_path + '/cloudRsCtxProfileToGatewayRouterP')) ops.append( dict(op='replace', path=region_path + '/isTGWAttachment', value=False)) elif state == 'present': new_hub_network = dict( name=hub_network.get('name'), tenantName=hub_network.get('tenant'), ) payload = region_obj payload.update( cloudRsCtxProfileToGatewayRouterP=new_hub_network, isTGWAttachment=True, ) mso.sanitize(payload, collate=True) ops.append(dict(op='replace', path=region_path, value=mso.sent)) mso.existing = new_hub_network 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), 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']), 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', 'zone']], ], ) schema = module.params['schema'] site = module.params['site'] template = module.params['template'] vrf = module.params['vrf'] region = module.params['region'] cidr = module.params['cidr'] subnet = module.params['subnet'] zone = module.params['zone'] 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 VRF vrf_ref = mso.vrf_ref(schema_id=schema_id, template=template, vrf=vrf) vrfs = [v['vrfRef'] for v in schema_obj['sites'][site_idx]['vrfs']] if vrf_ref not in vrfs: mso.fail_json( msg="Provided vrf '{0}' does not exist. Existing vrfs: {1}".format( vrf, ', '.join(vrfs))) vrf_idx = vrfs.index(vrf_ref) # Get Region regions = [ r['name'] for r in schema_obj['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}". format(region, ', '.join(regions))) region_idx = regions.index(region) # Get CIDR cidrs = [ c['ip'] for c in schema_obj['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}" .format(cidr, ', '.join(cidrs))) cidr_idx = cidrs.index(cidr) # Get Subnet subnets = [ s['ip'] for s in schema_obj['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['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['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=zone, ) 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', 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', ['vrf']], ['state', 'present', ['vrf']], ], ) schema = module.params.get('schema') site = module.params.get('site') template = module.params.get('template') 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 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 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 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 is not None and vrf_ref in vrfs: vrf_idx = vrfs.index(vrf_ref) vrf_path = '/sites/{0}/vrfs/{1}'.format(site_template, vrf) mso.existing = schema_obj.get('sites')[site_idx]['vrfs'][vrf_idx] if state == 'query': if vrf is None: mso.existing = schema_obj.get('sites')[site_idx]['vrfs'] elif not mso.existing: mso.fail_json(msg="VRF '{vrf}' not found".format(vrf=vrf)) mso.exit_json() vrfs_path = '/sites/{0}/vrfs'.format(site_template) ops = [] mso.previous = mso.existing if state == 'absent': if mso.existing: mso.sent = mso.existing = {} ops.append(dict(op='remove', path=vrf_path)) elif state == 'present': payload = dict(vrfRef=dict( schemaId=schema_id, templateName=template, vrfName=vrf, ), ) mso.sanitize(payload, collate=True) if mso.existing: ops.append(dict(op='replace', path=vrf_path, value=mso.sent)) else: ops.append(dict(op='add', path=vrfs_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(mso_subnet_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'], required=True), subnet=dict(type='str', aliases=['ip']), description=dict(type='str'), scope=dict(type='str', choices=['private', 'public']), shared=dict(type='bool', default=False), no_default_gateway=dict(type='bool', default=False), querier=dict(type='bool', default=False), is_virtual_ip=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') site = module.params.get('site') template = module.params.get('template').replace(' ', '') bd = module.params.get('bd') 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') is_virtual_ip = module.params.get('is_virtual_ip') 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) # Get template BDs template_bds = [ b.get('name') for b in schema_obj.get('templates')[template_idx]['bds'] ] # Get template BD if bd not in template_bds: mso.fail_json( msg="Provided BD '{0}' does not exist. Existing template BDs: {1}". format(bd, ', '.join(template_bds))) template_bd_idx = template_bds.index(bd) template_bd = schema_obj.get( 'templates')[template_idx]['bds'][template_bd_idx] if template_bd.get('l2Stretch') is True and state == 'present': mso.fail_json( msg= "The l2Stretch of template bd should be false in order to create a site bd subnet. Set l2Stretch as false using mso_schema_template_bd" ) # 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.".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_ref not in bds: mso.fail_json( msg="Provided BD '{0}' does not exist. Existing site BDs: {1}". format(bd, ', '.join(bds))) bd_idx = bds.index(bd_ref) # Get Subnet subnets = [ s.get('ip') for s in schema_obj.get('sites')[site_idx]['bds'][bd_idx]['subnets'] ] if subnet in subnets: subnet_idx = subnets.index(subnet) # FIXME: Changes based on index are DANGEROUS subnet_path = '/sites/{0}/bds/{1}/subnets/{2}'.format( site_template, bd, subnet_idx) mso.existing = schema_obj.get( 'sites')[site_idx]['bds'][bd_idx]['subnets'][subnet_idx] if state == 'query': if subnet is None: mso.existing = schema_obj.get( 'sites')[site_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 = '/sites/{0}/bds/{1}/subnets'.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=subnet_path)) elif state == 'present': if not mso.existing: if description is None: description = subnet if scope is None: scope = 'private' payload = dict( ip=subnet, description=description, scope=scope, shared=shared, noDefaultGateway=no_default_gateway, virtual=is_virtual_ip, 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), anp=dict(type='str', required=True), epg=dict(type='str', required=True), pod=dict(type='str' ), # This parameter is not required for querying all objects leaf=dict(type='str', aliases=['name']), vlan=dict(type='int'), state=dict(type='str', default='present', choices=['absent', 'present', 'query']), ) module = AnsibleModule( argument_spec=argument_spec, supports_check_mode=True, required_if=[ ['state', 'absent', ['pod', 'leaf', 'vlan']], ['state', 'present', ['pod', 'leaf', 'vlan']], ], ) schema = module.params['schema'] site = module.params['site'] template = module.params['template'] anp = module.params['anp'] epg = module.params['epg'] pod = module.params['pod'] leaf = module.params['leaf'] vlan = module.params['vlan'] state = module.params['state'] leafpath = 'topology/{0}/node-{1}'.format(pod, leaf) 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 ANP anp_ref = mso.anp_ref(schema_id=schema_id, template=template, anp=anp) anps = [a['anpRef'] for a in schema_obj['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['epgRef'] for e in schema_obj['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 Leaf leafs = [(l['path'], l['portEncapVlan']) for l in schema_obj['sites'] [site_idx]['anps'][anp_idx]['epgs'][epg_idx]['staticLeafs']] if (leafpath, vlan) in leafs: leaf_idx = leafs.index((leafpath, vlan)) # FIXME: Changes based on index are DANGEROUS leaf_path = '/sites/{0}/anps/{1}/epgs/{2}/staticLeafs/{3}'.format( site_template, anp, epg, leaf_idx) mso.existing = schema_obj['sites'][site_idx]['anps'][anp_idx]['epgs'][ epg_idx]['staticLeafs'][leaf_idx] if state == 'query': if leaf is None or vlan is None: mso.existing = schema_obj['sites'][site_idx]['anps'][anp_idx][ 'epgs'][epg_idx]['staticLeafs'] elif not mso.existing: mso.fail_json(msg="Static leaf '{leaf}/{vlan}' not found".format( leaf=leaf, vlan=vlan)) mso.exit_json() leafs_path = '/sites/{0}/anps/{1}/epgs/{2}/staticLeafs'.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=leaf_path)) elif state == 'present': payload = dict( path=leafpath, portEncapVlan=vlan, ) mso.sanitize(payload, collate=True) if mso.existing: ops.append(dict(op='replace', path=leaf_path, value=mso.sent)) else: ops.append(dict(op='add', path=leafs_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', 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()
def main(): argument_spec = mso_argument_spec() argument_spec.update( tenant=dict(type='str', aliases=['name'], required=True), site=dict(type='str', aliases=['name']), cloud_account=dict(type='str'), security_domains=dict(type='list', elements='str', default=[]), aws_trusted=dict(type='bool'), azure_access_type=dict(type='str', default='shared', choices=['managed', 'unmanaged', 'shared']), azure_active_directory_id=dict(type='str'), aws_access_key=dict(type='str'), aws_account_org=dict(type='bool', default='false'), azure_active_directory_name=dict(type='str'), azure_subscription_id=dict(type='str'), azure_application_id=dict(type='str'), azure_credential_name=dict(type='str'), secret_key=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', ['tenant', 'site']], ['state', 'present', ['tenant', 'site']], ], ) state = module.params.get('state') security_domains = module.params.get('security_domains') cloud_account = module.params.get('cloud_account') azure_access_type = module.params.get('azure_access_type') azure_credential_name = module.params.get('azure_credential_name') azure_application_id = module.params.get('azure_application_id') azure_active_directory_id = module.params.get('azure_active_directory_id') azure_active_directory_name = module.params.get('azure_active_directory_name') azure_subscription_id = module.params.get('azure_subscription_id') secret_key = module.params.get('secret_key') aws_account_org = module.params.get('aws_account_org') aws_access_key = module.params.get('aws_access_key') aws_trusted = module.params.get('aws_trusted') mso = MSOModule(module) # Get tenant_id and site_id tenant_id = mso.lookup_tenant(module.params.get('tenant')) site_id = mso.lookup_site(module.params.get('site')) tenants = [(t.get('id')) for t in mso.query_objs('tenants')] tenant_idx = tenants.index((tenant_id)) # set tenent and port paths tenant_path = 'tenants/{0}'.format(tenant_id) ops = [] ports_path = '/siteAssociations/-' port_path = '/siteAssociations/{0}'.format(site_id) payload = dict( siteId=site_id, securityDomains=security_domains, cloudAccount=cloud_account, ) if cloud_account: if 'azure' in cloud_account: azure_account = dict( accessType=azure_access_type, securityDomains=security_domains, vendor='azure', ) payload['azureAccount'] = [azure_account] cloudSubscription = dict( cloudSubscriptionId=azure_subscription_id, cloudApplicationId=azure_application_id, ) payload['azureAccount'][0]['cloudSubscription'] = cloudSubscription if azure_access_type == 'shared': payload['azureAccount'] = [] if azure_access_type == 'managed': if not azure_subscription_id: mso.fail_json(msg="azure_susbscription_id is required when in managed mode.") if not azure_application_id: mso.fail_json(msg="azure_application_id is required when in managed mode.") payload['azureAccount'][0]['cloudApplication'] = [] payload['azureAccount'][0]['cloudActiveDirectory'] = [] if azure_access_type == 'unmanaged': if not azure_subscription_id: mso.fail_json(msg="azure_subscription_id is required when in unmanaged mode.") if not azure_application_id: mso.fail_json(msg="azure_application_id is required when in unmanaged mode.") if not secret_key: mso.fail_json(msg="secret_key is required when in unmanaged mode.") if not azure_active_directory_id: mso.fail_json(msg="azure_active_directory_id is required when in unmanaged mode.") if not azure_active_directory_name: mso.fail_json(msg="azure_active_directory_name is required when in unmanaged mode.") if not azure_credential_name: mso.fail_json(msg="azure_credential_name is required when in unmanaged mode.") azure_account.update( accessType='credentials', ) cloudApplication = dict( cloudApplicationId=azure_application_id, cloudCredentialName=azure_credential_name, secretKey=secret_key, cloudActiveDirectoryId=azure_active_directory_id ) cloudActiveDirectory = dict( cloudActiveDirectoryId=azure_active_directory_id, cloudActiveDirectoryName=azure_active_directory_name ) payload['azureAccount'][0]['cloudApplication'] = [cloudApplication] payload['azureAccount'][0]['cloudActiveDirectory'] = [cloudActiveDirectory] else: aws_account = dict( accountId=cloud_account, isTrusted=aws_trusted, accessKeyId=aws_access_key, secretKey=secret_key, isAccountInOrg=aws_account_org, ) if not aws_trusted: if not aws_access_key: mso.fail_json(msg="aws_access_key is a required field in untrusted mode.") if not secret_key: mso.fail_json(msg="secret_key is a required field in untrusted mode.") payload['awsAccount'] = [aws_account] sites = [(s.get('siteId')) for s in mso.query_objs('tenants')[tenant_idx]['siteAssociations']] if site_id in sites: site_idx = sites.index((site_id)) mso.existing = mso.query_objs('tenants')[tenant_idx]['siteAssociations'][site_idx] if state == 'query': if len(sites) == 0: mso.fail_json(msg="No site associated with tenant Id {0}".format(tenant_id)) elif site_id not in sites and site_id is not None: mso.fail_json(msg="Site Id {0} not associated with tenant Id {1}".format(site_id, tenant_id)) elif site_id is None: mso.existing = mso.query_objs('tenants')[tenant_idx]['siteAssociations'] mso.exit_json() mso.previous = mso.existing if state == 'absent': if mso.existing: mso.sent = mso.existing = {} ops.append(dict(op='remove', path=port_path)) if 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=ports_path, value=mso.sent)) mso.existing = mso.proposed if not module.check_mode and mso.proposed != mso.previous: mso.request(tenant_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), 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') 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_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) 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), 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 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['schema'] site = module.params['site'] template = module.params['template'] vrf = module.params['vrf'] region = module.params['region'] 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 VRF vrf_ref = mso.vrf_ref(schema_id=schema_id, template=template, vrf=vrf) vrfs = [v['vrfRef'] for v in schema_obj['sites'][site_idx]['vrfs']] if vrf_ref not in vrfs: mso.fail_json( msg="Provided vrf '{0}' does not exist. Existing vrfs: {1}".format( vrf, ', '.join(vrfs))) vrf_idx = vrfs.index(vrf_ref) # Get Region regions = [ r['name'] for r in schema_obj['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['sites'][site_idx]['vrfs'][vrf_idx][ 'regions'][region_idx] if state == 'query': if region is None: mso.existing = schema_obj['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, ) 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()