def main(): # Get the APIC login credentials description = 'testing tags' creds = aci.Credentials('apic', description) creds.add_argument('--tag', help='Add tag to all objects in this configuration') creds.add_argument('--tenant', help='Tenant name to be created') args = creds.get() #Create the Tenant if args.tenant: tenant = aci.Tenant(args.tenant) else: tenant = aci.Tenant('tutorial-tag') # Create the Application Profile app = aci.AppProfile('myapp', tenant) # Create the EPG epg1 = aci.EPG('myepg1', app) epg2 = aci.EPG('myepg2', app) # Create a Context and BridgeDomain context = aci.Context('myvrf', tenant) bd = aci.BridgeDomain('mybd', tenant) bd.add_context(context) # Place the EPG in the BD epg1.add_bd(bd) epg2.add_bd(bd) # Add Tag to the EPGs epg1.add_tag("web server") epg2.add_tag("database") # test app2 = aci.AppProfile('myapp2', tenant) epg21 = aci.EPG('myepg21', app2) epg22 = aci.EPG('myepg22', app2) # Add Tag to all objects in this configuration if args.tag: tenant.add_tag(args.tag) context.add_tag(args.tag) bd.add_tag(args.tag) epg1.add_tag(args.tag) epg2.add_tag(args.tag) # Login to APIC and push the config session = aci.Session(args.url, args.login, args.password) session.login() resp = tenant.push_to_apic(session) if resp.ok: print('Success') # Print what was sent print('Pushed the following JSON to the APIC') print('URL:', tenant.get_url()) print('JSON:', tenant.get_json())
def lab2(course_partecipants, tenant_list = []): new_tenant_list = [] for cp in range(1, course_partecipants+1): tenant = aci.Tenant("MMTENANT{}".format(cp)) vrf = aci.Context("VRF-INSIDE", tenant) bd1 = aci.BridgeDomain("BD100", tenant) bd1.add_context(vrf) bd2 = aci.BridgeDomain("BD200", tenant) bd2.add_context(vrf) new_tenant_list.append(tenant) return new_tenant_list
def migration_tenant(self, tenant_name, app_name, provision=True): self.tenant = aci.Tenant(tenant_name) self.app = aci.AppProfile(app_name, self.tenant) self.context = aci.Context('default', self.tenant) self.contract = aci.Contract('allow-any', self.tenant) entry1 = aci.FilterEntry('default', applyToFrag='no', arpOpc='unspecified', etherT='unspecified', parent=self.contract) if provision: self.session.push_to_apic(self.tenant.get_url(), self.tenant.get_json()) else: self.tenant.get_json() return self.tenant
def Create_BD(aci_sheet, row): # call login function and return session session = apic_login() # create variables by importing values from spreadsheet tn_name = ACI.Tenant(aci_sheet.cell_value(row, 1)) VRF_name = ACI.Context(aci_sheet.cell_value(row, 3), tn_name) BD_name = ACI.BridgeDomain(aci_sheet.cell_value(row, 2), tn_name) advertise = aci_sheet.cell_value(row, 7) subnet = ACI.Subnet((aci_sheet.cell_value(row, 2) + '_subnet'), BD_name) subnet.set_addr(aci_sheet.cell_value(row, 6)) OutsideL3 = ACI.OutsideL3(aci_sheet.cell_value(row, 8), tn_name) L3_out = aci_sheet.cell_value(row, 8) BD_name.add_context(VRF_name) BD_name.add_subnet(subnet) if advertise == "yes": BD_name.add_l3out(OutsideL3) resp = session.push_to_apic(tn_name.get_url(), data=tn_name.get_json()) if resp.ok: print 'Bridge Domain %s deployed' % BD_name print '=' * 20
def main(): # Take login credentials from the command line if provided # Otherwise, take them from your environment variables file ~/.profile description = ('Simple application to build a Tenant/AP/EPG/BD/VRF') creds = aci.Credentials('apic', description) creds.add_argument('--delete', action='store_true', help='Delete the configuration from the APIC') creds.add_argument('--prefix', help='Prefix to use for all objects', default="mipetrin_acitoolkit") creds.add_argument('--amount', nargs='?', const=1, type=int, default=3, help='The total amount of iterations to complete') creds.add_argument('--test', action='store_true', help='Don\'t write to APIC. Print JSON output only') creds.add_argument('--debug', action='store_true', help='Verbose output') args = creds.get() name_prefix = args.prefix total_amount = args.amount debug_enabled = args.debug # Login to APIC session = aci.Session(args.url, args.login, args.password) resp = session.login() if not resp.ok: print('%% Could not login to APIC') return # Start time count at this point, otherwise takes into consideration the amount of time taken to input the password start_time = time.time() count = 1 while (count <= total_amount): if debug_enabled: print 'The count is:', count tenant = aci.Tenant(name_prefix + "_t" + str(count)) app = aci.AppProfile(name_prefix + "_app" + str(count), tenant) bd = aci.BridgeDomain(name_prefix + "_bd" + str(count), tenant) context = aci.Context(name_prefix + "_vrf" + str(count), tenant) epg = aci.EPG(name_prefix + "_epg" + str(count), app) bd.add_context(context) epg.add_bd(bd) # Delete the configuration if desired # WARNING - NO VALIDATION TAKES PLACE CURRENTLY. SIMPLY DELETES CONFIG # # WARNING - READ THAT AGAIN # # WARNING - NO VALIDATION TAKES PLACE CURRENTLY. SIMPLY DELETES CONFIG aborted = False abort_count = 0 if args.delete: #selection = None # First pass, ensure selection exists but no choice yet if debug_enabled: print "Checkpoint: args.delete" while 1: # raw_input returns an empty string for "enter" yes = {'yes', 'y', 'ye'} no = {'no', 'n', ''} selection = raw_input( "Are you absolutely sure you want to DELETE the entire tenant: [" + tenant.name + "]??? [y|N] ").lower() if selection in yes: # Uncomment the below line with caution. Wipes all tenants that match the criteria tenant.mark_as_deleted() print("Delete action is being performed...") print("-" * 30) break elif selection in no: # everything else to default to NO print "Aborting delete..." aborted = True print("-" * 30) break else: print "error state" if aborted: count = count + 1 # Ensure that we do loop to the next iteration from name perspective in an aborted scenario abort_count += 1 # Keep track of how many we abort/skip over deleting, per user selection continue # to the next iteration of the loop as no config push is required elif args.test: print(tenant.get_json()) else: # Push our json configuration to the APIC (either to be created or deleted) unless aborted #if aborted: # continue # to the next iteration of the loop as no config push is required resp = session.push_to_apic(tenant.get_url(), tenant.get_json()) if resp.ok: # print 'Success:', count # Print what was sent if debug_enabled: print 'Success:', count print 'Pushed the following JSON to the APIC' print 'URL:', tenant.get_url() print 'JSON:', tenant.get_json() if not resp.ok: print('%% Error: Could not push configuration to APIC') print(resp.text) exit(0) count = count + 1 # Loop to the next iteration from name perspective for Test/Update print "=" * 80 if args.delete: print 'Attempted to delete the following object count:', total_amount - abort_count elif args.test: print 'Printed test output for a total object count:', total_amount else: print 'Successfully pushed total object count to the APIC:', total_amount print "=" * 80 print("#" * 80) finish_time = time.time() print("Started @ {}".format(time.asctime(time.localtime(start_time)))) print("Ended @ {}".format(time.asctime(time.localtime(finish_time)))) print("--- Total Execution Time: %s seconds ---" % (finish_time - start_time)) print("#" * 80)
def main(): """ This is the main function of the script. From here, other functions are called. This script will take in the IP and credentials for an APIC, a new Tenant name, and a filename of existing VLANS This script can be used when the initial ACI Policy will map EPGs to existing client vlans This script takes in a list of existing vlans and creates the Tenant and corresponding VRF,ANP, EPG, and BO based on naming best practice. This script configures one ANP, mapped to one EPG and its corresponding BD for each vlan. Each BD is a member of one VRF. """ # Put relevant arguments passed to the script when the script was called in variables with east to understand names hostname, username, password, tenant_name, vlan_csv = sys.argv[1:] # Initialize and empty dictionary to hold the ANP=>EPG key value pairs epg_anp_dict = {} print "\n\n" + "="*20 + 'Creating Application Network Profiles and End Point Groups for each existing Vlan.' + "="*20 print "="*10 + "Processing VLAN file " + vlan_csv +' for new Tenant ' + tenant_name + ' by user ' + username + " on APIC " + hostname + "="*10 # Call the extract_vlan function, pass it the filename provided in the command line # This function will return a dictionary of vlan_id keys and vlan_name values vlans = extract_vlans(vlan_csv) # Now that we have a dictionary of our anp=>epg pairs, generat the ANP and EPG names to be configured in the APIC # Store those names in the epg_anp_dict dictionary for later use. for vlan_id,vlan_name in vlans.items(): #print vlan_id, vlan_name epg_name = "v"+vlan_id.strip()+"_"+vlan_name.upper().strip()+"_EPG" anp_name = "v"+vlan_id.strip()+"_"+vlan_name.upper().strip()+"_ANP" epg_anp_dict[anp_name]=epg_name #print epg_anp_dict print "="*10 + "Attempting to create Tenant " + tenant_name + ' by user ' + username + " on APIC " + hostname + "="*10 print "\n\tLogging in to APIC" # Establish a session to the apic whose parameters/credentials were passed as arguments on the command line apic_session = apic_login_acitk(hostname, username, password) # Call the print_tenant function which will return a list of all the tenants currently configured on the APIC # This list will be used to check to see if the tenant to be configured provided via an argument already exists tenants = print_tenant(apic_session) #print "modir ",modir #print "tenant_name ", tenant_name # If the tenant we are supposed to create already exists, primt a status message, print all the existing tenants, and exit the script. if tenant_name in tenants: print "\n\t Tenant <"+tenant_name+ "> already exists and does not need to be created.\n" for t in tenants: print "\t Tenant "+t + " exists." delete = raw_input("\n**** Would you like to delete the existing tenant " + tenant_name + " (Yes/No)? ****: ") #print "delete", str(delete) if delete.lower().strip() == 'no': print "\t\n Exiting Script.\n" sys.exit() else: delete2 = raw_input("\n**** Are you absolutely sure you want to delete the existing tenant <" + tenant_name + "> (Yes/No)? ****: ") print "\nSorry, I still need to figure out how to delete a tenant." print "\t\nExiting Script.\n" sys.exit() # If the tenant does not exist, create it and create the corresponding VRF else: print "\n\tCreating Tenant " + tenant_name #create_tenant(modir, tenant_name) # Create the tenant tenant = ACI.Tenant(tenant_name) #Configure a Private Network/VRF for the Tenant tenant_vrf = tenant_name + "_VRF" print "\n\tCreating Private Network\VRF " + tenant_vrf + " for Tenant " + tenant_name + "\n" context = ACI.Context(tenant_vrf, tenant) for anp, epg in epg_anp_dict.items(): # Create the App Profile, Bridge Domain, and EPG bd_name = re.sub("_EPG","_BD",epg ) #print "bd_name: ",bd_name print "\tCreating Application Profile " + anp + " with EPG " + epg + " and BD " + bd_name aciapp = ACI.AppProfile(anp, tenant) aciepg = ACI.EPG(epg, aciapp) acibd = ACI.BridgeDomain(bd_name, tenant) #Add the BD to the context acibd.add_context(context) #Add the BD to the EPG aciepg.add_bd(acibd) # Push it all to the APIC resp = tenant.push_to_apic(apic_session) if not resp.ok: print('%% Error: Could not push configuration to APIC') print(resp.text) print "\nLogging out of APIC"
for row in reader: input_vlan_bd_pairs.append(row) finally: f.close() for vlan_bd_pair in input_vlan_bd_pairs: vlan_id = vlan_bd_pair[0] bd_name = vlan_bd_pair[1] # Creating new Bridge domain, change values if required new_bridge_domain = aci.BridgeDomain(bd_name, tenant) new_bridge_domain.set_arp_flood("yes") new_bridge_domain.set_unicast_route("no") new_bridge_domain.set_unknown_mac_unicast("flood") new_bridge_domain.set_unknown_multicast("flood") new_bridge_domain.add_context(aci.Context(context_name, tenant)) #new_bridge_domain.set MULTIDEST FLOODING # Associate EPG with BD epg = aci.EPG(bd_name, app) epg.add_bd(new_bridge_domain) # Associate path with EPG static_binding = { "fvRsPathAtt": { "attributes": { "encap": "vlan-{}".format(vlan_id), "tDn": VPC_DN, "instrImedcy": "immediate", "status": "created" }
def main(): # We're going to prompt the user for a desired tenant name to build from # and then return the name to ensure that its correct tenant = ACI.Tenant(input("Enter desired tenant name: ")) print("Tenant name is: " + tenant.name) # Application profile name is built from the tenant name # and printed to validate ap = ACI.AppProfile(tenant.name + "-AP", tenant) print("AppProfile name is: " + ap.name) # Two EGPs are created and tied to the previously created AP web_epg = ACI.EPG('web', ap) db_epg = ACI.EPG('db', ap) # A VRF is built from the tenant name and printed vrf = ACI.Context(tenant.name + "-CTX", tenant) print("VRF name is: " + vrf.name) # Build a bridge domain from tenant name, print tenant_bd = ACI.BridgeDomain(tenant.name + "-BD", tenant) print("BD name is: " + tenant_bd.name) # Finally, build the subnet from tenant name, print tenant_bd_subnet = ACI.Subnet(tenant.name + "-Subnet", tenant_bd) print("Subnet name is: " + tenant_bd_subnet.name) # For sake of exercise, we'll just statically assign the subnet for # the BD tenant_bd_subnet.addr = "10.1.1.1/24" # The BD is attached to the VRF, and options are set for flooding tenant_bd.add_context(vrf) tenant_bd.set_arp_flood('no') tenant_bd.set_unicast_route('yes') # Each of the EPGs is added to the previously created BD web_epg.add_bd(tenant_bd) db_epg.add_bd(tenant_bd) # The first contract, defining SQL and tied to our tenant. # The entry is tied to the contract and includes port and other info sql_contract = ACI.Contract('mssql-contract', tenant) sql_entry_1 = ACI.FilterEntry('ms-sql', applyToFrag='no', arpOpc='unspecified', dFromPort='1433', dToPort='1433', etherT='ip', prot='tcp', sFromPort='1', sToPort='65535', tcpRules='unspecified', parent=sql_contract) # The second contract will be for web services. Include 80 and 443 web_contract = ACI.Contract('web-contract', tenant) web_entry_1 = ACI.FilterEntry('http', applyToFrag='no', arpOpc='unspecified', dFromPort='80', dToPort='80', etherT='ip', prot='tcp', sFromPort='1', sToPort='65535', tcpRules='unspecified', parent=web_contract) web_entry_2 = ACI.FilterEntry('https', applyToFrag='no', arpOpc='unspecified', dFromPort='443', dToPort='443', etherT='ip', prot='tcp', sFromPort='1', sToPort='65535', tcpRules='unspecified', parent=web_contract) # The contracts are attached to the EPGs are providers, consumers db_epg.provide(sql_contract) web_epg.consume(sql_contract) web_epg.provide(web_contract) # Physical interfaces for attachment intf1 = ACI.Interface('eth', '1', '101', '1', '1') intf2 = ACI.Interface('eth', '1', '102', '1', '1') # Create a single VLAN for these interfaces. Remember, EPGs do the allow-list vl10_intf1_web = ACI.L2Interface('vl10_intf1_web', 'vlan', '10') vl10_intf2_db = ACI.L2Interface('vl10_intf2_db', 'vlan', '10') # Attach the logical to physical interface config vl10_intf1_web.attach(intf1) vl10_intf2_db.attach(intf2) # Finally attach the EPGs to the layer-2 interface configs web_epg.attach(vl10_intf1_web) db_epg.attach(vl10_intf2_db) # Now the actual "configuration push" is setup description = 'ACIToolkit mock full tenant configuration script' creds = ACI.Credentials('apic', description) # Adding in pieces for JSON only or delete the tenant creds.add_argument('--delete', action='store_true', help='Delete the configuration from the APIC') creds.add_argument('--json', const='false', nargs='?', help='JSON output only') args = creds.get() session = ACI.Session(args.url, args.login, args.password) session.login() # Several if/else to delete the tenant or print the JSON payload if args.delete: tenant.mark_as_deleted() if args.json: print("The following JSON payload was created") print("URL: ", tenant.get_url()) print(json.dumps(tenant.get_json(), indent=2)) else: resp = session.push_to_apic(tenant.get_url(),tenant.get_json()) # Some error handling along the way if not resp.ok: print("%% Error: Could not push configuration to APIC") print(resp.text) else: print("Success")
def two_ports(): if not connected(): if not collect_login(): return print '\n\n' print '=========================' print '== Connect Two Ports ==' print '=========================\n' # Basic Connectivity Example # Equivalent to connecting to ports to the same VLAN new_tenant = raw_input('Please enter a Tenant name: ') new_app = raw_input('Please enter an Application name: ') new_epg = new_app + '_EPG' # Create a tenant tenant = ACI.Tenant(new_tenant) # Create a Context and a BridgeDomain context = ACI.Context('VRF-1', tenant) context.set_allow_all() bd = ACI.BridgeDomain('BD-1', tenant) bd.add_context(context) # Create an App Profile and an EPG app = ACI.AppProfile(new_app, tenant) epg = ACI.EPG(new_epg, app) interfaces = ACI.Interface.get(session) for i in xrange(len(interfaces) - 1, -1, -1): if interfaces[i].porttype != 'leaf': del interfaces[i] interface1_in = interface2_in = -1 while interface1_in == -1 or interface2_in == -1: for a in range(len(interfaces)): name = interfaces[a].if_name print str(a) + ': ' + name input1 = raw_input('\nEnter the first interface: ') input2 = raw_input('\nEnter the second interface: ') try: interface1_in = int(input1) interface2_in = int(input2) if (0 > interface1_in > len(interfaces)) or (0 > interface1_in > len(interfaces)): interface1_in = interface2_in == -1 except: print '\nError: Please enter a number on the left side of the screen.' # Attach the EPG to 2 interfaces using VLAN 5 as the encap if1 = interfaces[interface1_in] if2 = interfaces[interface2_in] # if1 = ACI.Interface('eth','1','101','1','62') # if2 = ACI.Interface('eth','1','101','1','63') vlan5_on_if1 = ACI.L2Interface('vlan5_on_if1', 'vlan', '5') vlan5_on_if2 = ACI.L2Interface('vlan5_on_if2', 'vlan', '5') vlan5_on_if1.attach(if1) vlan5_on_if2.attach(if2) epg.attach(vlan5_on_if1) epg.attach(vlan5_on_if2) resp = session.push_to_apic(tenant.get_url(), data=tenant.get_json()) if resp.ok: print '\nSuccess' input = raw_input('\nPress Enter to continue ')
BD_Name = 'BD1' # Create the Tenant tenant = ACI.Tenant(Tenant_Name) # Create the Application Profile app = ACI.AppProfile(AP_Name, tenant) # Create the EPGs web_epg = ACI.EPG(EPG1_Name, app) app_epg = ACI.EPG(EPG2_Name, app) db_epg = ACI.EPG(EPG3_Name, app) # Create a Context and BridgeDomain # Place all EPGs in the Context and in the same BD context = ACI.Context(Context_Name, tenant) bd = ACI.BridgeDomain(BD_Name, tenant) # Define a subnet in the BridgeDomain subnet1 = ACI.Subnet('Subnet1', bd) subnet2 = ACI.Subnet('Subnet2', bd) subnet1.set_addr('10.20.30.1/24') subnet2.set_addr('192.168.1.1/24') # Add Context and Subnets to BridgeDomain bd.add_context(context) bd.add_subnet(subnet1) bd.add_subnet(subnet2) # Define three EPGs web_epg.add_bd(bd)
def create_unique(session): # Objects for the ESXi servers in a tenant uni_pn = 'ESXi_PN' uni_bd = 'ESXi_BD' uni_app = 'ESXi_mgmt' uni_1_epg = 'Management' uni_2_epg = 'VMotion' uni_3_epg = 'Storage_acc' ip_segments = [ '10.1.1.1/24', ] # Valid options for the scape are 'private', 'public', and 'shared'. Comma seperated, and NO spaces subnet_scope = 'private,shared' # Connect to the VMM Domain # This must already exist. It should have been created in this script vmmdomain = vmm_name # Setup or credentials and session description = ('Create EPGs for ESXi servers in a tenant.') # Get the virtual domain we are going to use vdomain = ACI.EPGDomain.get_by_name(session, vmmdomain) tenant = ACI.Tenant(unique_tenant) app = ACI.AppProfile(uni_app, tenant) # Create the EPGs u1_epg = ACI.EPG(uni_1_epg, app) u2_epg = ACI.EPG(uni_2_epg, app) u3_epg = ACI.EPG(uni_3_epg, app) # Create a Context and BridgeDomain # Place all EPGs in the Context and in the same BD context = ACI.Context(uni_pn, tenant) ubd = ACI.BridgeDomain(uni_bd, tenant) ubd.add_context(context) for subnet_ip in ip_segments: ran_name = [random.choice(string.hexdigits).lower() for n in xrange(6)] sub_name = ''.join(ran_name) asubnet = ACI.Subnet(sub_name, ubd) asubnet.set_addr(subnet_ip) asubnet.set_scope(subnet_scope) u1_epg.add_bd(ubd) u1_epg.add_infradomain(vdomain) u2_epg.add_bd(ubd) u2_epg.add_infradomain(vdomain) u3_epg.add_bd(ubd) ''' Define contracts with a multiple entries ''' contract1 = ACI.Contract('esxi_clients', tenant) filters = [['HTTPS', '443', 'tcp'], ['HTTP', '80', 'tcp'], ['SSH', '22', 'tcp']] for filt in filters: entry = ACI.FilterEntry(filt[0], applyToFrag='no', arpOpc='unspecified', dFromPort=filt[1], dToPort=filt[1], etherT='ip', prot=filt[2], tcpRules='unspecified', parent=contract1) # Attach the contracts u1_epg.provide(contract1) # CAUTION: The next line will DELETE the tenant # tenant.mark_as_deleted() resp = tenant.push_to_apic(session) if resp.ok: # Uncomment the next lines if you want to see the configuration # print('URL: ' + str(tenant.get_url())) # print('JSON: ' + str(tenant.get_json())) return True else: return False
def create_common(session): # Objects for the Vcenter servers in the common Tenant common_tenant = 'common' the_pn = 'VMware_Infra_PN' the_bd = 'VMware_Infra_BD' app_1 = 'VMware-MGMT' epg_1 = 'VCenter' app_2 = 'Shared_Services' epg_2 = 'Services_Servers' app_3 = 'IP_Storage' epg_3 = 'Storage_Arrays' ip_segments = [ '10.1.1.1/24', ] # Connect to the VMM Domain # This must already exist and should have been created in this script vmmdomain = vmm_name # Setup or credentials and session description = ( 'Create EPGs Vcenter servers, IP Storage, and Shared Services in the common tenant.' ) # Get the virtual domain we are going to use vdomain = ACI.EPGDomain.get_by_name(session, vmmdomain) tenant = ACI.Tenant(unique_tenant) app_1 = ACI.AppProfile(app_1, tenant) app_2 = ACI.AppProfile(app_2, tenant) app_3 = ACI.AppProfile(app_3, tenant) # Create the EPGs epg_1 = ACI.EPG(epg_1, app_1) epg_2 = ACI.EPG(epg_2, app_2) epg_3 = ACI.EPG(epg_3, app_3) # Create a Context and BridgeDomain # Place all EPGs in the Context and in the same BD context = ACI.Context(the_pn, tenant) thebd = ACI.BridgeDomain(the_bd, tenant) thebd.add_context(context) epg_1.add_bd(thebd) epg_1.add_infradomain(vdomain) epg_2.add_bd(thebd) epg_2.add_infradomain(vdomain) epg_3.add_bd(thebd) ''' Define contracts with a multiple entries ''' contract1 = ACI.Contract('vCenter_clients', tenant) filters = [['HTTPS', '443', 'tcp'], ['HTTP', '80', 'tcp'], ['SSH', '22', 'tcp']] for filt in filters: entry = ACI.FilterEntry(filt[0], applyToFrag='no', arpOpc='unspecified', dFromPort=filt[1], dToPort=filt[1], etherT='ip', prot=filt[2], tcpRules='unspecified', parent=contract1) # Attach the contracts epg_1.provide(contract1) # CAUTION: The next line will DELETE the tenant # tenant.mark_as_deleted() resp = tenant.push_to_apic(session) if resp.ok: # Uncomment the next lines if you want to see the configuration # print('URL: ' + str(tenant.get_url())) # print('JSON: ' + str(tenant.get_json())) return True else: return False
def main(): #################### GET CREDENTIALS & APIC LOGIN ####################################################### # ## Credentials # description = 'ACI Fabric Setup' creds = aci.Credentials('apic', description) creds.add_argument('--delete', action='store_true', help='Delete the configuration from the APIC') args = creds.get() # ## Login to the APIC # session = aci.Session(args.url, args.login, args.password) resp = session.login() if not resp.ok: print('%% Could not login to APIC') # #################### CREATE & PUSH ACI CONFIG ########################################################### # ## TENANT, VRF & Bridge Domains # tenant = aci.Tenant("MMTENANT0") tenant.descr = "Created using ACITOOLKIT" vrf = aci.Context("VRF-INSIDE", tenant) bd1 = aci.BridgeDomain("BD100", tenant) bd1.add_context(vrf) bd2 = aci.BridgeDomain("BD200", tenant) bd2.add_context(vrf) # ## Application Profile & EPGs # app_profile = aci.AppProfile("AP0", tenant) epg1 = aci.EPG("EPG100", app_profile) epg1.add_bd(bd1) epg2 = aci.EPG("EPG200", app_profile) epg2.add_bd(bd2) # ## Contract # # Define a contract with a single entry contract = aci.Contract("permit-icmp", tenant) entry1 = aci.FilterEntry("icmp", parent=contract, applyToFrag='no', etherT='ip', prot='icmp') # Apply contract in both directions # apply from epg1 to epg2 epg1.provide(contract) epg2.consume(contract) # apply from epg2 to epg1 epg1.consume(contract) epg2.provide(contract) # ## Push to APIC # resp = session.push_to_apic(tenant.get_url(), tenant.get_json()) if not resp.ok: print('%% Error: Could not push {} configuration to APIC'.format( tenant.name)) print(resp.text) # ######################################################################################################### # print(" *** SCRIPT EXECUTED SUCCESSFULLY! *** ")