def api_switch(request): """ Return a list of switches :param request: :return: """ if 'HTTP_AUTHORIZATION' in request.META: apic_token = request.META['HTTP_AUTHORIZATION'].split(' ')[1] apic_url = request.META['HTTP_AUTHORIZATION'].split(' ')[2] if request.method == 'POST': try: payload = json.loads(request.body) apic = ApicController() apic.url = apic_url apic.token = apic_token switches = apic.getSwitches(pod_dn=payload["pod"]["fabricPod"]["attributes"]["dn"]) return JSONResponse(switches) except Exception as e: print(traceback.print_exc()) # return the error to web client return JSONResponse({'error': e.__class__.__name__, 'message': str(e)}, status=500) else: return JSONResponse("Bad request. " + request.method + " is not supported", status=400) else: return JSONResponse("Bad request. HTTP_AUTHORIZATION header is required", status=400)
def api_login(request): """ Return an apic neighbors :param request: :return: """ if request.method == 'POST': try: payload = json.loads(request.body) apic = ApicController() apic.url = payload["url"] request.session['apic_url'] = payload["url"] token = apic.get_token(username=payload["username"], password=payload["password"]) request.session["token"] = token request.session["url"] = apic.url return JSONResponse("ok") except Exception as e: print(traceback.print_exc()) # return the error to web client return JSONResponse( { 'error': e.__class__.__name__, 'message': str(e) }, status=500) else: return JSONResponse("Bad request. " + request.method + " is not supported", status=400)
def api_pod(request): """ Return a list of pods :param request: :return: """ if 'HTTP_AUTHORIZATION' in request.META: apic_token = request.META['HTTP_AUTHORIZATION'].split(' ')[1] apic_url = request.META['HTTP_AUTHORIZATION'].split(' ')[2] if request.method == 'GET': try: apic = ApicController() apic.url = apic_url apic.token = apic_token pods = apic.getPods() return JSONResponse(pods) except Exception as e: print(traceback.print_exc()) # return the error to web client return JSONResponse({'error': e.__class__.__name__, 'message': str(e)}, status=500) else: return JSONResponse("Bad request. " + request.method + " is not supported", status=400) else: return JSONResponse("Bad request. HTTP_AUTHORIZATION header is required", status=400)
def api_deploy(request): """ Creates a port deployment in ACI :param request: :return: """ if request.method == 'POST': try: # Parse request body to json payload = json.loads(request.body) # Create a new controller apic = ApicController() # Create a new deployment apic.createDeployment(payload, PREFIX) print("Deployment Done!") # Reply ok to the web client return JSONResponse("ok") except Exception as e: print(traceback.print_exc()) # return the error to web client return JSONResponse( { 'error': e.__class__.__name__, 'message': str(e) }, status=500) else: # return the error to web client return JSONResponse("Bad request. " + request.method + " is not supported", status=400)
def api_pod(request): """ Return a json list of pods :param request: :return: """ if request.method == 'GET': try: # Create a new controller apic = ApicController() # Get the pods pods = apic.getPods() # Send pods to the web client return JSONResponse(pods) except Exception as e: print(traceback.print_exc()) # return the error to web client return JSONResponse( { 'error': e.__class__.__name__, 'message': str(e) }, status=500) else: # return the error to web client return JSONResponse("Bad request. " + request.method + " is not supported", status=400)
def api_interface(request, switchDn): """ Return a list of interfaces for a given switch :param request: :return: """ if request.method == 'GET': try: # Create a new controller apic = ApicController() # Get the interfaces for a given switch interfaces = apic.getInterfaces(switch_dn=switchDn) # Send the interfaces to the web client return JSONResponse(interfaces) except Exception as e: print(traceback.print_exc()) # return the error to web client return JSONResponse( { 'error': e.__class__.__name__, 'message': str(e) }, status=500) else: # return the error to web client return JSONResponse("Bad request. " + request.method + " is not supported", status=400)
def api_isedeployleaf(request): """ Return a list of EPG for a given tenant :param request: :return: """ if request.method == 'POST': try: payload = json.loads(request.body) print(payload) # Create a new controller apic = ApicController() ise = IseController() # Get all EPGs from the first application profile leafs = apic.getLeafs(pod_dn=payload["deployment"]["selectedPod"]["fabricPod"]["attributes"]["dn"]) for leaf in leafs: leaf_name = leaf["fabricNode"]["attributes"]["id"] leaf_ip_parameters = apic.getLeafMgmtIp(leaf_dn=leaf["fabricNode"]["attributes"]["dn"]) print(leaf_ip_parameters) for leaf_ip in leaf_ip_parameters: ise.createNetworkDevice(leaf_name, leaf_ip["ipv4Addr"]["attributes"]["addr"][:-3]) # Send EPGs to web client return JSONResponse(leafs) except Exception as e: print(traceback.print_exc()) # return the error to web client return JSONResponse({'error': e.__class__.__name__, 'message': str(e)}, status=500) else: # return the error to web client return JSONResponse("Bad request. " + request.method + " is not supported", status=400)
def api_iseleaf(request): """ Return a json list of tenants :param request: :return: """ if request.method == 'GET': try: payload = json.loads(request.body) print(payload) # Create a new controller apic = ApicController() # Get the pods tenants = apic.getTenants(query_filter="") # Send pods to the web client return JSONResponse(tenants) except Exception as e: print(traceback.print_exc()) # return the error to web client return JSONResponse({'error': e.__class__.__name__, 'message': str(e)}, status=500) else: # return the error to web client return JSONResponse("Bad request. " + request.method + " is not supported", status=400)
def api_epg(request): """ Return a list of EPG for a given tenant :param request: :return: """ if 'HTTP_AUTHORIZATION' in request.META: apic_token = request.META['HTTP_AUTHORIZATION'].split(' ')[1] apic_url = request.META['HTTP_AUTHORIZATION'].split(' ')[2] if request.method == 'GET': try: apic = ApicController() apic.url = apic_url apic.token = apic_token tenants = apic.getTenants(query_filter='eq(fvTenant.name,"' + PREFIX + '")') if len(tenants) == 0: return JSONResponse([]) aps = apic.getAppProfiles(tenant_dn=tenants[0]["fvTenant"]["attributes"]["dn"], query_filter='eq(fvAp.name,"' + PREFIX + '")') if len(aps) == 0: return JSONResponse([]) epgs = apic.getEPGs(ap_dn=aps[0]["fvAp"]["attributes"]["dn"]) return JSONResponse(epgs) except Exception as e: print(traceback.print_exc()) # return the error to web client return JSONResponse({'error': e.__class__.__name__, 'message': str(e)}, status=500) else: return JSONResponse("Bad request. " + request.method + " is not supported", status=400) else: return JSONResponse("Bad request. HTTP_AUTHORIZATION header is required", status=400)
def api_epg(request): """ Return a list of EPG for a given tenant :param request: :return: """ if request.method == 'GET': try: # Create a new controller apic = ApicController() # Get all tenants for the configured prefix tenants = apic.getTenants(query_filter='eq(fvTenant.name,"' + PREFIX + '")') if len(tenants) == 0: return JSONResponse([]) # Get all application profiles for the tenant aps = apic.getAppProfiles( tenant_dn=tenants[0]["fvTenant"]["attributes"]["dn"], query_filter='eq(fvAp.name,"' + PREFIX + '")') if len(aps) == 0: return JSONResponse([]) # Get all EPGs from the first application profile epgs = apic.getEPGs(ap_dn=aps[0]["fvAp"]["attributes"]["dn"]) # Send EPGs to web client return JSONResponse(epgs) except Exception as e: print(traceback.print_exc()) # return the error to web client return JSONResponse( { 'error': e.__class__.__name__, 'message': str(e) }, status=500) else: # return the error to web client return JSONResponse("Bad request. " + request.method + " is not supported", status=400)
def api_deploy(request): """ Return a list of EPG for a given tenant :param request: :return: """ if request.method == 'POST': try: payload = json.loads(request.body) print(payload) ise = IseController() apic = ApicController() if payload["deployment"]["portType"] == "select": print("inhere1") #leafs = apic.getLeafs(pod_dn=payload["deployment"]["selectedPod"]["fabricPod"]["attributes"]["dn"]) #for leaf in leafs: #leaf_name = leaf["fabricNode"]["attributes"]["id"] #leaf_ip_parameters = apic.getLeafMgmtIp(leaf_dn=leaf["fabricNode"]["attributes"]["dn"]) #print(leaf_ip_parameters) #for leaf_ip in leaf_ip_parameters: #ise.createNetworkDevice(leaf_name, leaf_ip["ipv4Addr"]["attributes"]["addr"][:-3]) ise.createEndPoint(mac=payload["deployment"]["selectedMac"], endpointgroup_id=payload["deployment"]["selectedEndpointgroup"]["id"]) print("Deployment Done!") elif payload["deployment"]["portType"] == "add": print("inhere2") ise.createEndPointIdentityGroup(name=payload["deployment"]["selectedIseeig"], description=payload["deployment"]["selectedIseeigdescrip"]) apic_tenant = payload["deployment"]["selectedTenant"]["fvTenant"]["attributes"]["dn"] apic_tenant_trim = apic_tenant[apic_tenant.find('tn-'):] apic_apppro = payload["deployment"]["selectedAppPro"]["fvAp"]["attributes"]["dn"] apic_apppro_trim = apic_apppro[apic_apppro.find('ap-'):] apic_epg = payload["deployment"]["selectedEpg"]["fvAEPg"]["attributes"]["dn"] apic_epg_trim = apic_epg[apic_epg.find('epg-'):] ise.createAuthorizationProfile(apname=payload["deployment"]["selectedIseap"], apictenant=apic_tenant_trim, apicap=apic_apppro_trim, apicepg=apic_epg_trim, vlan = payload["deployment"]["selectedIseapvlan"]) print("Deployment Done!") # Reply ok to the web client return JSONResponse("ok") except Exception as e: print(traceback.print_exc()) # return the error to web client return JSONResponse({'error': e.__class__.__name__, 'message': str(e)}, status=500) else: # return the error to web client return JSONResponse("Bad request. " + request.method + " is not supported", status=400)
def api_take_snapshot(request): """ Take the snapshot of the switch and saves it in a local database :param request: :return: """ if 'HTTP_AUTHORIZATION' in request.META: apic_token = request.META['HTTP_AUTHORIZATION'].split(' ')[1] apic_url = request.META['HTTP_AUTHORIZATION'].split(' ')[2] if request.method == 'POST': try: payload = json.loads(request.body) apic = ApicController() apic.url = apic_url apic.token = apic_token apic.saveSnapshot(switch_dn=payload["switch"]["fabricNode"]["attributes"]["dn"], filename=payload["snapshot"]["name"], type=payload["snapshot"]["type"]) return JSONResponse("ok") except Exception as e: print(traceback.print_exc()) # return the error to web client return JSONResponse({'error': e.__class__.__name__, 'message': str(e)}, status=500) else: return JSONResponse("Bad request. " + request.method + " is not supported", status=400) else: return JSONResponse("Bad request. HTTP_AUTHORIZATION header is required", status=400)
def api_epg(request, apDn): """ Return a list of EPG for a given tenant :param request: :return: """ if request.method == 'GET': try: # Create a new controller apic = ApicController() # Get all EPGs from the first application profile epgs = apic.getEPGs(ap_dn=apDn) # Send EPGs to web client return JSONResponse(epgs) except Exception as e: print(traceback.print_exc()) # return the error to web client return JSONResponse({'error': e.__class__.__name__, 'message': str(e)}, status=500) else: # return the error to web client return JSONResponse("Bad request. " + request.method + " is not supported", status=400)
def api_iseleaf(request, podDn): """ Return a list of switches for a given pod :param request: :return: """ if request.method == 'GET': try: # Create a new controller apic = ApicController() # Get the leaf switches for a given pod apicleafs = apic.getLeafs(pod_dn=podDn) # Send the leaf switches to the web client return JSONResponse(apicleafs) except Exception as e: print(traceback.print_exc()) # return the error to web client return JSONResponse({'error': e.__class__.__name__, 'message': str(e)}, status=500) else: # return the error to web client return JSONResponse("Bad request. " + request.method + " is not supported", status=400)
def api_get_neighbors(request): """ Return an apic neighbors :param request: :return: """ if request.method == 'GET': try: # return JSONResponse([{'fabricLooseNode': {'attributes': {'childAction': '', 'dn': 'topology/lsnode-10.0.226.249', 'id': '10.0.226.249', 'lcOwn': 'local', 'modTs': '2018-01-04T20:45:13.803-05:00', 'monPolDn': 'uni/fabric/monfab-default', 'name': '', 'nameAlias': '', 'operIssues': '', 'status': '', 'sysDesc': 'Cisco Nexus Operating System (NX-OS) Software\nTAC support: http://www.cisco.com/tac\nCopyright (c) 2002-2016, Cisco Systems, Inc. All rights reserved.', 'sysName': 'ucs-TT14-B', 'lldpNodes': ['topology/pod-1/node-203/']}}}, {'fabricLooseNode': {'attributes': {'childAction': '', 'dn': 'topology/lsnode-10.0.243.14', 'id': '10.0.243.14', 'lcOwn': 'local', 'modTs': '2017-06-18T20:26:46.416-05:00', 'monPolDn': 'uni/fabric/monfab-default', 'name': '', 'nameAlias': '', 'operIssues': '', 'status': '', 'sysDesc': 'Cisco Nexus Operating System (NX-OS) Software 6.0(2)U3(7)\nTAC support: http://www.cisco.com/tac\nCopyright (c) 2002-2015, Cisco Systems, Inc. All rights reserved.', 'sysName': 'n3k-top'}}}, {'fabricLooseNode': {'attributes': {'childAction': '', 'dn': 'topology/lsnode-10.0.226.248', 'id': '10.0.226.248', 'lcOwn': 'local', 'modTs': '2018-01-04T20:45:14.239-05:00', 'monPolDn': 'uni/fabric/monfab-default', 'name': '', 'nameAlias': '', 'operIssues': '', 'status': '', 'sysDesc': 'Cisco Nexus Operating System (NX-OS) Software\nTAC support: http://www.cisco.com/tac\nCopyright (c) 2002-2016, Cisco Systems, Inc. All rights reserved.', 'sysName': 'ucs-TT14-A', 'lldpNodes': ['topology/pod-1/node-203/']}}}, {'fabricLooseNode': {'attributes': {'childAction': '', 'dn': 'topology/lsnode-10.0.243.15', 'id': '10.0.243.15', 'lcOwn': 'local', 'modTs': '2018-01-04T20:45:49.470-05:00', 'monPolDn': 'uni/fabric/monfab-default', 'name': '', 'nameAlias': '', 'operIssues': '', 'status': '', 'sysDesc': 'Cisco Nexus Operating System (NX-OS) Software 6.0(2)U3(7)\nTAC support: http://www.cisco.com/tac\nCopyright (c) 2002-2015, Cisco Systems, Inc. All rights reserved.', 'sysName': 'n3k-bottom', 'lldpNodes': ['topology/pod-1/node-203/']}}}, {'fabricLooseNode': {'attributes': {'childAction': '', 'dn': 'topology/lsnode-10.0.243.38', 'id': '10.0.243.38', 'lcOwn': 'local', 'modTs': '2017-05-18T13:10:10.629-05:00', 'monPolDn': 'uni/fabric/monfab-default', 'name': '', 'nameAlias': '', 'operIssues': '', 'status': '', 'sysDesc': 'Red Hat Enterprise Linux Server 7.3 (Maipo) Linux 3.10.0-514.el7.x86_64 #1 SMP Wed Oct 19 11:24:13 EDT 2016 x86_64', 'sysName': 'os-getsvs-1', 'lldpNodes': ['topology/pod-1/node-203/']}}}, {'fabricLooseNode': {'attributes': {'childAction': '', 'dn': 'topology/lsnode-10.0.243.39', 'id': '10.0.243.39', 'lcOwn': 'local', 'modTs': '2017-05-26T12:41:54.352-05:00', 'monPolDn': 'uni/fabric/monfab-default', 'name': '', 'nameAlias': '', 'operIssues': '', 'status': '', 'sysDesc': 'Red Hat Enterprise Linux Server 7.3 (Maipo) Linux 3.10.0-514.el7.x86_64 #1 SMP Wed Oct 19 11:24:13 EDT 2016 x86_64', 'sysName': 'os-getsvs-2'}}}]) # Parse the json apic = ApicController() apic.url = request.session["url"] apic.token = request.session["token"] pods = apic.getPods() lldpNodes = [] manageByACI = False present = False for pod in apic.getPods(): podInventory = apic.getSwitches( pod_dn=pod["fabricPod"]["attributes"]["dn"]) for leaf in apic.getLeafs( pod_dn=pod["fabricPod"]["attributes"]["dn"]): print("Checking switch " + leaf["fabricNode"]["attributes"]["dn"]) for neighborItfc in apic.getLldpNeighbors( switch_dn=leaf["fabricNode"]["attributes"]["dn"]): # Check that neighbor is not part of the inventory for neighbor in neighborItfc["lldpIf"]["children"]: manageByACI = False for switch in podInventory: if switch["fabricNode"]["attributes"]["dn"] == \ neighbor["lldpAdjEp"]["attributes"]["sysDesc"]: manageByACI = True break if not manageByACI: if neighbor["lldpAdjEp"]["attributes"]["sysName"] != "" and "apic" not in \ neighbor["lldpAdjEp"]["attributes"]["sysName"]: # Neighbor found # Getting name for switch_in in podInventory: if neighborItfc["lldpIf"]["attributes"]["sysDesc"] == \ switch_in["fabricNode"]["attributes"]["dn"]: neighborName = switch_in[ "fabricNode"]["attributes"][ "name"] break present = False for item in lldpNodes: if item["name"] == neighbor[ "lldpAdjEp"]["attributes"][ "sysName"]: item["neighbors"].append( "Device " + neighborName + " port " + neighborItfc["lldpIf"] ["attributes"]["id"]) present = True break if not present: lldpNodes.append({ "name": neighbor["lldpAdjEp"]["attributes"] ["sysName"], "mgmtIp": neighbor["lldpAdjEp"]["attributes"] ["mgmtIp"], "neighbors": [ "Device " + neighborName + " port " + neighborItfc["lldpIf"] ["attributes"]["id"] ] }) return JSONResponse(lldpNodes) except Exception as e: print(traceback.print_exc()) # return the error to web client return JSONResponse( { 'error': e.__class__.__name__, 'message': str(e) }, status=500) else: return JSONResponse("Bad request. " + request.method + " is not supported", status=400)
def api_deploy(request): """ Creates if does not exist: - EPG - App Profile - BD - VRF - Tenant :param request: :return: """ if 'HTTP_AUTHORIZATION' in request.META: apic_token = request.META['HTTP_AUTHORIZATION'].split(' ')[1] apic_url = request.META['HTTP_AUTHORIZATION'].split(' ')[2] if request.method == 'POST': try: payload = json.loads(request.body) apic = ApicController() apic.url = apic_url apic.token = apic_token print("Creating tenant if not present") tenants = apic.getTenants(query_filter='eq(fvTenant.name,"' + PREFIX + '")') if len(tenants) == 0: tenants = apic.createTenant(PREFIX) print("Creating application profile if not present") aps = apic.getAppProfiles(tenant_dn=tenants[0]["fvTenant"]["attributes"]["dn"], query_filter='eq(fvAp.name,"' + PREFIX + '")') if len(aps) == 0: aps = apic.createAppProfile(tenant_dn=tenants[0]["fvTenant"]["attributes"]["dn"], app_prof_name=PREFIX) print("Creating VRF if not present") vrfs = apic.getVRFs(tenant_dn=tenants[0]["fvTenant"]["attributes"]["dn"], query_filter='eq(fvCtx.name,"' + PREFIX + '")') if len(vrfs) == 0: vrfs = apic.createVRF(tenant_dn=tenants[0]["fvTenant"]["attributes"]["dn"], vrf_name=PREFIX) print("Creating Bridge Domain if not present") bds = apic.getBridgeDomains(tenant_dn=tenants[0]["fvTenant"]["attributes"]["dn"], query_filter='eq(fvBD.name,"' + PREFIX + '")') if len(bds) == 0: bds = apic.createBridgeDomain(tenant_dn=tenants[0]["fvTenant"]["attributes"]["dn"], bd_name=PREFIX, vrf_name=vrfs[0]["fvCtx"]["attributes"]["name"]) print("Creating Endpoint Group if not present") if payload["deployment"]["epgAction"] == "new": epgName = payload["deployment"]["epgVlan"] else: epgName = payload["deployment"]["selectedEpg"]["fvAEPg"]["attributes"]["name"] # Check if EPG already exists epgs = apic.getEPGs(ap_dn=aps[0]["fvAp"]["attributes"]["dn"], query_filter='eq(fvAEPg.name,"' + epgName + '")') if len(epgs) == 0: # Create only if does not exist epgs = apic.createEPG(ap_dn=aps[0]["fvAp"]["attributes"]["dn"], bridge_domain_name=bds[0]["fvBD"]["attributes"]["name"], epg_name=epgName) print("Creating VLAN Pool if not present") vpools = apic.getVlanPools(query_filter='eq(fvnsVlanInstP.name,"' + PREFIX + '")') if len(vpools) == 0: # Create vlan pool vpools = apic.createVlanPool(name=PREFIX) print("Add selected VLANs to pool if not present") apic.addVlansToPool(pool_name=vpools[0]["fvnsVlanInstP"]["attributes"]["name"], from_vlan=epgName, to_vlan=epgName) print("Creating Physical Domain if not present") phyDoms = apic.getPhysicalDomains(query_filter='eq(physDomP.name,"' + PREFIX + '")') if len(phyDoms) == 0: phyDoms = apic.createPhysicalDomain(name=PREFIX, vlan_pool_dn=vpools[0]["fvnsVlanInstP"]["attributes"]["dn"]) print("Creating Attachable Entity Profile if not present") atthEntProfiles = apic.getAttachEntityProfile(query_filter='eq(infraAttEntityP.name,"' + PREFIX + '")') if len(atthEntProfiles) == 0: atthEntProfiles = apic.createAttachEntityProfile(name=PREFIX, phy_domain_dn=phyDoms[0]["physDomP"]["attributes"][ "dn"]) port1 = payload["deployment"]["selectedInterface1"]["l1PhysIf"]["attributes"]["id"].replace( "eth1/", "") leaf1_id = payload["deployment"]["selectedSwitch1"]["fabricNode"]["attributes"]["id"] if payload["deployment"]["portType"] == "access": # ## Access ## # Create Policy Group default options with attachable entity profile print("**** Deployment Port Type: Access *****") intPolGroups = apic.createAccessInterfacePolicyGroup( name=PREFIX + "-access", attEntPro_dn=atthEntProfiles[0]["infraAttEntityP"]["attributes"]["dn"]) print("Creating Interface Policy if not present") # Create access interface policy intAccessProfiles = apic.createAccessInterfaceProfile(name=PREFIX + "-access-" + port1) print("Creating Interface Selector if not present") # Add selected port apic.createInterfaceSelector( name=payload["deployment"]["selectedInterface1"]["l1PhysIf"]["attributes"]["id"].replace( "/", "-"), from_port=port1, to_port=port1, interface_profile_dn=intAccessProfiles[0]["infraAccPortP"]["attributes"]["dn"], interface_policy_group_dn=intPolGroups[0]["infraAccPortGrp"]["attributes"]["dn"]) print("Creating Switch Profile if not present") # Create switch profile sProfile = apic.createSwitchProfile(name=PREFIX, leaf_id=leaf1_id) print("Associating interface profiles to switch profile if not present") # Associate interface profiles to switch profile sw_prof_dn, int_prof_dn apic.associateIntProfToSwProf( sw_prof_dn=sProfile["infraNodeP"]["attributes"]["dn"], int_prof_dn=intAccessProfiles[0]["infraAccPortP"]["attributes"]["dn"]) print("Associating port to EPG if not present") # Associate port to EPG apic.addStaticPortToEpg( vlan=epgName, leaf_id=leaf1_id, port_id=payload["deployment"]["selectedInterface1"]["l1PhysIf"]["attributes"]["id"], epg_dn=epgs[0]["fvAEPg"]["attributes"]["dn"]) elif payload["deployment"]["portType"] == "portChannel": print("**** Deployment Port Type: PortChannel *****") # ## Port Channel ## port2 = payload["deployment"]["selectedInterface2"]["l1PhysIf"]["attributes"]["id"].replace( "eth1/", "") print("Creating LACP Profile if not present") # make sure lacp_profile exists lapc_prof = apic.addLacpProf(name=PREFIX + '-LACP-ACTIVE') print("Creating port channel policy group if not present") # make sure portchannel policy group exists portchannel_policy = apic.addPortchannelIntPolicyGroup( name=PREFIX + '-portchannel', att_ent_prof_dn=atthEntProfiles[0]["infraAttEntityP"]["attributes"]["dn"], lacp_prof_name=lapc_prof["lacpLagPol"]["attributes"]["name"]) print("Creating port channel profile if not present") # make sure portchannel profile exists for port 1 portchannel_profile = apic.addPortchannelIntProfile( name=PREFIX + '-portchannel-' + port1 + '-' + port2) print("Creating Interface Selector for interfaces if not present") # Add selected port1 apic.createInterfaceSelector( name=payload["deployment"]["selectedInterface1"]["l1PhysIf"]["attributes"]["id"].replace( "/", "-"), from_port=port1, to_port=port1, interface_profile_dn=portchannel_profile["infraAccPortP"]["attributes"]["dn"], interface_policy_group_dn=portchannel_policy["infraAccBndlGrp"]["attributes"]["dn"]) # Add selected port2 apic.createInterfaceSelector( name=payload["deployment"]["selectedInterface2"]["l1PhysIf"]["attributes"]["id"].replace( "/", "-"), from_port=port2, to_port=port2, interface_profile_dn=portchannel_profile["infraAccPortP"]["attributes"]["dn"], interface_policy_group_dn=portchannel_policy["infraAccBndlGrp"]["attributes"]["dn"]) print("Creating Switch Profile if not present") # Create switch Profile sProfile = apic.createSwitchProfile(name=PREFIX, leaf_id=leaf1_id) print("Associating interface profiles to switch profile if not present") # Associate interface profiles to switch profile sw_prof_dn, int_prof_dn apic.associateIntProfToSwProf( sw_prof_dn=sProfile["infraNodeP"]["attributes"]["dn"], int_prof_dn=portchannel_profile["infraAccPortP"]["attributes"]["dn"]) print("Associating port to EPG if not present") # Associate port to EPG apic.addStaticPortchannelToEpg( vlan=epgName, leaf_id=leaf1_id, portchannel_pol_grp_name=portchannel_policy["infraAccBndlGrp"]["attributes"]["name"], epg_dn=epgs[0]["fvAEPg"]["attributes"]["dn"]) print("Deployment Done!") return JSONResponse("ok") except Exception as e: print(traceback.print_exc()) # return the error to web client return JSONResponse({'error': e.__class__.__name__, 'message': str(e)}, status=500) else: return JSONResponse("Bad request. " + request.method + " is not supported", status=400) else: return JSONResponse("Bad request. HTTP_AUTHORIZATION header is required", status=400)