def main(): argument_spec = mso_argument_spec() argument_spec.update( schema=dict(type='str', required=True), template=dict(type='str', required=True), anp=dict(type='str', required=True), epg=dict(type='str', required=True), contract=dict(type='dict', options=mso_contractref_spec()), state=dict(type='str', default='present', choices=['absent', 'present', 'query']), ) module = AnsibleModule( argument_spec=argument_spec, supports_check_mode=True, required_if=[ ['state', 'absent', ['contract']], ['state', 'present', ['contract']], ], ) schema = module.params.get('schema') template = module.params.get('template') anp = module.params.get('anp') epg = module.params.get('epg') contract = module.params.get('contract') state = module.params.get('state') mso = MSOModule(module) if contract: if contract.get('schema') is None: contract['schema'] = schema contract['schema_id'] = mso.lookup_schema(contract.get('schema')) if contract.get('template') is None: contract['template'] = template # Get schema_id schema_obj = mso.get_obj('schemas', displayName=schema) if schema_obj: schema_id = schema_obj.get('id') else: mso.fail_json( msg="Provided schema '{0}' does not exist".format(schema)) schema_path = 'schemas/{id}'.format(**schema_obj) # Get template templates = [t.get('name') for t in schema_obj.get('templates')] if template not in templates: mso.fail_json( msg="Provided template '{0}' does not exist. Existing templates: {1}" .format(template, ', '.join(templates))) template_idx = templates.index(template) # Get ANP anps = [ a.get('name') for a in schema_obj.get('templates')[template_idx]['anps'] ] if anp not in anps: mso.fail_json( msg="Provided anp '{0}' does not exist. Existing anps: {1}".format( anp, ', '.join(anps))) anp_idx = anps.index(anp) # Get EPG epgs = [ e.get('name') for e in schema_obj.get('templates')[template_idx] ['anps'][anp_idx]['epgs'] ] if epg not in epgs: mso.fail_json( msg="Provided epg '{epg}' does not exist. Existing epgs: {epgs}". format(epg=epg, epgs=', '.join(epgs))) epg_idx = epgs.index(epg) # Get Contract if contract: contracts = [(c.get('contractRef'), c.get('relationshipType')) for c in schema_obj.get('templates')[template_idx]['anps'] [anp_idx]['epgs'][epg_idx]['contractRelationships']] contract_ref = mso.contract_ref(**contract) if (contract_ref, contract.get('type')) in contracts: contract_idx = contracts.index( (contract_ref, contract.get('type'))) contract_path = '/templates/{0}/anps/{1}/epgs/{2}/contractRelationships/{3}'.format( template, anp, epg, contract) mso.existing = schema_obj.get( 'templates')[template_idx]['anps'][anp_idx]['epgs'][epg_idx][ 'contractRelationships'][contract_idx] if state == 'query': if not contract: mso.existing = schema_obj.get('templates')[template_idx]['anps'][ anp_idx]['epgs'][epg_idx]['contractRelationships'] elif not mso.existing: mso.fail_json(msg="Contract '{0}' not found".format(contract_ref)) mso.exit_json() contracts_path = '/templates/{0}/anps/{1}/epgs/{2}/contractRelationships'.format( template, anp, epg) ops = [] mso.previous = mso.existing if state == 'absent': if mso.existing: mso.sent = mso.existing = {} ops.append(dict(op='remove', path=contract_path)) elif state == 'present': payload = dict( relationshipType=contract.get('type'), contractRef=dict( contractName=contract.get('name'), templateName=contract.get('template'), schemaId=contract.get('schema_id'), ), ) mso.sanitize(payload, collate=True) if mso.existing: ops.append(dict(op='replace', path=contract_path, value=mso.sent)) else: ops.append( dict(op='add', path=contracts_path + '/-', value=mso.sent)) mso.existing = mso.proposed if not module.check_mode: mso.request(schema_path, method='PATCH', data=ops) mso.exit_json()
def main(): argument_spec = mso_argument_spec() argument_spec.update( schema=dict(type='str', required=True), template=dict(type='str', required=True), contract=dict(type='str', required=True), contract_display_name=dict(type='str'), contract_scope=dict( type='str', choices=['application-profile', 'global', 'tenant', 'vrf']), contract_filter_type=dict(type='str', choices=['both-way', 'one-way']), filter=dict(type='str', aliases=[ 'name' ]), # This parameter is not required for querying all objects filter_directives=dict(type='list', choices=['log', 'none']), filter_template=dict(type='str'), filter_schema=dict(type='str'), filter_type=dict(type='str', default='both-way', choices=FILTER_KEYS.keys(), aliases=['type']), state=dict(type='str', default='present', choices=['absent', 'present', 'query']), ) module = AnsibleModule( argument_spec=argument_spec, supports_check_mode=True, required_if=[ ['state', 'absent', ['filter']], ['state', 'present', ['filter']], ], ) schema = module.params.get('schema') template = module.params.get('template') contract = module.params.get('contract') contract_display_name = module.params.get('contract_display_name') contract_filter_type = module.params.get('contract_filter_type') contract_scope = module.params.get('contract_scope') filter_name = module.params.get('filter') filter_directives = module.params.get('filter_directives') filter_template = module.params.get('filter_template') filter_schema = module.params.get('filter_schema') filter_type = module.params.get('filter_type') state = module.params.get('state') contract_ftype = 'bothWay' if contract_filter_type == 'both-way' else 'oneWay' if contract_filter_type == 'both-way' and filter_type != 'both-way': module.warn( "You are adding 'one-way' filters to a 'both-way' contract") elif contract_filter_type != 'both-way' and filter_type == 'both-way': module.warn( "You are adding 'both-way' filters to a 'one-way' contract") if filter_template is None: filter_template = template if filter_schema is None: filter_schema = schema filter_key = FILTER_KEYS[filter_type] mso = MSOModule(module) filter_schema_id = mso.lookup_schema(filter_schema) # Get schema object schema_obj = mso.get_obj('schemas', displayName=schema) if schema_obj: schema_id = schema_obj.get('id') else: mso.fail_json( msg="Provided schema '{0}' does not exist".format(schema)) schema_path = 'schemas/{id}'.format(**schema_obj) # Get template templates = [t.get('name') for t in schema_obj.get('templates')] if template not in templates: mso.fail_json( msg="Provided template '{0}' does not exist. Existing templates: {1}" .format(template, ', '.join(templates))) template_idx = templates.index(template) # Get contracts mso.existing = {} contract_idx = None filter_idx = None contracts = [ c.get('name') for c in schema_obj.get('templates')[template_idx]['contracts'] ] if contract in contracts: contract_idx = contracts.index(contract) filters = [ f.get('filterRef') for f in schema_obj.get('templates') [template_idx]['contracts'][contract_idx][filter_key] ] filter_ref = mso.filter_ref(schema_id=filter_schema_id, template=filter_template, filter=filter_name) if filter_ref in filters: filter_idx = filters.index(filter_ref) filter_path = '/templates/{0}/contracts/{1}/{2}/{3}'.format( template, contract, filter_key, filter_name) mso.existing = schema_obj.get('templates')[template_idx][ 'contracts'][contract_idx][filter_key][filter_idx] if state == 'query': if contract_idx is None: mso.fail_json( msg= "Provided contract '{0}' does not exist. Existing contracts: {1}" .format(contract, ', '.join(contracts))) if filter_name is None: mso.existing = schema_obj.get('templates')[template_idx][ 'contracts'][contract_idx][filter_key] elif not mso.existing: mso.fail_json(msg="FilterRef '{filter_ref}' not found".format( filter_ref=filter_ref)) mso.exit_json() ops = [] contract_path = '/templates/{0}/contracts/{1}'.format(template, contract) filters_path = '/templates/{0}/contracts/{1}/{2}'.format( template, contract, filter_key) mso.previous = mso.existing if state == 'absent': mso.proposed = mso.sent = {} if contract_idx is None: # There was no contract to begin with pass elif filter_idx is None: # There was no filter to begin with pass elif len(filters) == 1: # There is only one filter, remove contract mso.existing = {} ops.append(dict(op='remove', path=contract_path)) else: # Remove filter mso.existing = {} ops.append(dict(op='remove', path=filter_path)) elif state == 'present': if filter_directives is None: filter_directives = ['none'] payload = dict( filterRef=dict( filterName=filter_name, templateName=filter_template, schemaId=filter_schema_id, ), directives=filter_directives, ) mso.sanitize(payload, collate=True) mso.existing = mso.sent if contract_idx is None: # Contract does not exist, so we have to create it if contract_display_name is None: contract_display_name = contract if contract_filter_type is None: contract_ftype = 'bothWay' if contract_scope is None: contract_scope = 'context' payload = { 'name': contract, 'displayName': contract_display_name, 'filterType': contract_ftype, 'scope': contract_scope, } ops.append( dict(op='add', path='/templates/{0}/contracts/-'.format(template), value=payload)) else: # Contract exists, but may require an update if contract_display_name is not None: ops.append( dict(op='replace', path=contract_path + '/displayName', value=contract_display_name)) if contract_filter_type is not None: ops.append( dict(op='replace', path=contract_path + '/filterType', value=contract_ftype)) if contract_scope is not None: ops.append( dict(op='replace', path=contract_path + '/scope', value=contract_scope)) if filter_idx is None: # Filter does not exist, so we have to add it ops.append(dict(op='add', path=filters_path + '/-', value=mso.sent)) else: # Filter exists, we have to update it ops.append(dict(op='replace', path=filter_path, value=mso.sent)) if not module.check_mode: mso.request(schema_path, method='PATCH', data=ops) mso.exit_json()