def main(): """ Main execution routine :return: None """ creds = Credentials('apic') creds.add_argument('--tenant', help='The name of Tenant') creds.add_argument('--app', help='The name of ApplicationProfile') creds.add_argument('--bd', help='The name of BridgeDomain') creds.add_argument('--epg', help='The name of EPG') creds.add_argument('--json', const='false', nargs='?', help='Json output only') args = creds.get() session = Session(args.url, args.login, args.password) session.login() tenant = Tenant(args.tenant) app = AppProfile(args.app, tenant) bd = BridgeDomain(args.bd, tenant) epg = EPG(args.epg, app) epg.add_bd(bd) if args.json: print(tenant.get_json()) else: resp = session.push_to_apic(tenant.get_url(), tenant.get_json()) if not resp.ok: print('%% Error: Could not push configuration to APIC') print(resp.text)
def setup_tenant(self, apic): tenant = Tenant('inheritanceautomatedtest') context = Context('mycontext', tenant) l3out = OutsideL3('myl3out', tenant) parent_epg = OutsideEPG('parentepg', l3out) parent_network = OutsideNetwork('5.1.1.1', parent_epg) parent_network.ip = '5.1.1.1/8' child_epg = OutsideEPG('childepg', l3out) child_network = OutsideNetwork('5.2.1.1', child_epg) child_network.ip = '5.2.1.1/16' contract = Contract('mycontract', tenant) parent_epg.provide(contract) entry = FilterEntry('webentry1', applyToFrag='no', arpOpc='unspecified', dFromPort='80', dToPort='80', etherT='ip', prot='tcp', sFromPort='1', sToPort='65535', tcpRules='unspecified', parent=contract) resp = tenant.push_to_apic(apic) self.assertTrue(resp.ok)
def add_child_subnet(self, apic): tenant = Tenant('inheritanceautomatedtest') l3out = OutsideL3('myl3out', tenant) child_epg = OutsideEPG('childepg', l3out) child_network = OutsideNetwork('5.2.1.1', child_epg) child_network.ip = '5.2.1.1/16' resp = tenant.push_to_apic(apic) self.assertTrue(resp.ok)
def add_contract(self, apic): tenant = Tenant('inheritanceautomatedtest') l3out = OutsideL3('myl3out', tenant) parent_epg = OutsideEPG('parentepg', l3out) contract = self.get_contract(tenant) parent_epg.provide(contract) resp = tenant.push_to_apic(apic) self.assertTrue(resp.ok)
def setup_tenant(self, apic): tenant = Tenant('inheritanceautomatedtest') context = Context('mycontext', tenant) l3out = OutsideL3('myl3out', tenant) parent_epg = OutsideEPG('parentepg', l3out) parent_network = OutsideNetwork('5.1.1.1', parent_epg) parent_network.ip = '5.1.1.1/8' child_epg = OutsideEPG('childepg', l3out) child_network = OutsideNetwork('5.2.1.1', child_epg) child_network.ip = '5.2.1.1/16' contract = self.get_contract(tenant) resp = tenant.push_to_apic(apic) self.assertTrue(resp.ok)
def push_config_to_apic(session, tenant_name, filename): """ Push the tenant configuration to the APIC :param session: Instance of Session class. Assumed to be logged in to the APIC. :param filename: String containing the file name :return: None """ tenant = Tenant(tenant_name) with open(filename) as input_file: tenant_json = json.load(input_file) resp = session.push_to_apic(tenant.get_url(), tenant_json) if resp.ok: print 'Successfully pushed configuration to APIC.' else: print 'Could not push configuration to APIC.', resp.text
def build(self, tenants=None): """ This will read in all of the model and from there build-out the data base :param tenants: :return: """ if tenants is None: tenants = Tenant.get_deep(self.session) for tenant in tenants: self.tenants_by_name[tenant.name] = tenant contexts = tenant.get_children(Context) for context in contexts: self.context_by_name[(tenant.name, context.name)] = context app_profiles = tenant.get_children(AppProfile) contracts = tenant.get_children(Contract) outside_l3s = tenant.get_children(OutsideL3) for app_profile in app_profiles: epgs = app_profile.get_children(EPG) self.build_ip_epg(epgs) self.build_epg_contract(epgs) for outside_l3 in outside_l3s: self.build_ip_epg_outside_l3(outside_l3) self.build_epg_contract_outside_l3(outside_l3) self.build_contract_filter(contracts) self.initialized = True
def test_verify_all_tenants_deleted(self): """ Test that all of the randomied tenants have been deleted """ session = self.login_to_apic() tenants = Tenant.get(session) for tenant in tenants: self.assertFalse(tenant.name.startswith('acitoolkitrandomized-'))
def main(): """ Main routine """ # Get all the arguments description = 'Creates a tenant with a micro-EPG.' creds = Credentials('apic', description) args = creds.get() # Login to the APIC session = Session(args.url, args.login, args.password) resp = session.login() if not resp.ok: print('%% Could not login to APIC') # Create the Tenant and AppProfile tenant = Tenant('acitoolkit-microepg-example') app_profile = AppProfile('myapp', tenant) # Create a Base EPG that will provide networking for the microEPGs base_epg = EPG('base', app_profile) base_epg.add_static_leaf_binding('101', 'vlan', '1', encap_mode='untagged') vrf = Context('myvrf', tenant) bd = BridgeDomain('mybd', tenant) bd.add_context(vrf) base_epg.add_bd(bd) # Create a microEPG microepg = EPG('microepg', app_profile) microepg.is_attributed_based = True microepg.set_base_epg(base_epg) # Add an IP address to this microepg criterion = AttributeCriterion('criterion', microepg) criterion.add_ip_address('1.2.3.4') # Contracts can be provided/consumed from the microepg as desired (not shown) # Push the tenant to the APIC resp = tenant.push_to_apic(session) if not resp.ok: print('%% Error: Could not push configuration to APIC') print(resp.text)
def delete_all_randomized_tenants(session): tenants = Tenant.get(session) for tenant in tenants: if tenant.name.startswith('acitoolkitrandomized-'): tenant.mark_as_deleted() resp = tenant.push_to_apic(session) if not resp.ok: print 'Could not delete tenant', tenant.name print resp.status_code, resp.text else: print 'Deleted tenant', tenant.name
def pull_config_from_apic(session, tenant_name, filename): """ Pull the tenant configuration from the APIC :param session: Instance of Session class. Assumed to be logged in to the APIC. :param tenant_name: String containing the tenant name :param filename: String containing the file name :return: None """ tenants = Tenant.get_deep(session, names=[tenant_name], config_only=True) output_file = open(filename, 'w') for tenant in tenants: output_file.write(json.dumps(tenant.get_json(), indent=4, sort_keys=True)) output_file.close()
def main(): """ Main execution routine """ description = ( 'Simple application that logs on to the APIC' ' and displays all the tenant info of the contract_interface related to the imported contract.' ) creds = Credentials('apic', description) creds.add_argument("-t", "--tenant_name", help="Tenant Name of where the contract is created") creds.add_argument("-i", "--contract_name", help="Imported Contract Name") args = creds.get() if (args.tenant_name is not None) and (args.contract_name is None): args.contract_name = raw_input("Contract Name: ") session = Session(args.url, args.login, args.password) resp = session.login() if not resp.ok: print('%% Could not login to APIC') tenants = Tenant.get_deep(session) for tenant in tenants: contracts_interfaces = tenant.get_children( only_class=ContractInterface) for contract_interface in contracts_interfaces: imported_contract = contract_interface.get_import_contract() if imported_contract is not None: if args.tenant_name is not None: if (imported_contract.name == args.contract_name) and ( imported_contract.get_parent().name == args.tenant_name): apps = AppProfile.get(session, tenant) for app in apps: epgs = EPG.get(session, app, tenant) for epg in epgs: data.append((imported_contract.name, tenant.name, app.name, epg.name)) else: apps = AppProfile.get(session, tenant) for app in apps: epgs = EPG.get(session, app, tenant) for epg in epgs: data.append((imported_contract.name, tenant.name, app.name, epg.name)) print tabulate( data, headers=["IMPORTED_CONTRACT", "TENANT", "APP_PROFILE", "EPG"])
def pull_config_from_apic(session, tenant_name, filename): """ Pull the tenant configuration from the APIC :param session: Instance of Session class. Assumed to be logged in to the APIC. :param tenant_name: String containing the tenant name :param filename: String containing the file name :return: None """ tenants = Tenant.get_deep(session, names=[tenant_name], config_only=True) output_file = open(filename, 'w') for tenant in tenants: output_file.write( json.dumps(tenant.get_json(), indent=4, sort_keys=True)) output_file.close()
def main(): """ Main show Subnets routine :return: None """ # Take login credentials from the command line if provided # Otherwise, take them from your environment variables file ~/.profile description = ('Simple application that logs on to the APIC' ' and displays all of the Subnets.') creds = Credentials('apic', description) creds.add_argument('--tenant', help='The name of Tenant') args = creds.get() # Login to APIC session = Session(args.url, args.login, args.password) resp = session.login() if not resp.ok: print('%% Could not login to APIC') # Download all of the tenants, app profiles, and Subnets # and store the names as tuples in a list tenants = Tenant.get(session) for tenant in tenants: check_longest_name(tenant.name, "Tenant") if args.tenant is None: get_subnet(session, tenant) else: if tenant.name == args.tenant: get_subnet(session, tenant) # Display the data downloaded template = '{0:' + str(longest_names["Tenant"]) + '} ' \ '{1:' + str(longest_names["Application Profile"]) + '} ' \ '{2:' + str(longest_names["Bridge Domain"]) + '} ' \ '{3:' + str(longest_names["Subnet"]) + '} ' \ '{4:' + str(longest_names["Scope"]) + '}' print(template.format("Tenant", "Application Profile", "Bridge Domain", "Subnet", "Scope")) print(template.format('-' * longest_names["Tenant"], '-' * longest_names["Application Profile"], '-' * longest_names["Bridge Domain"], '-' * longest_names["Subnet"], '-' * longest_names["Scope"])) for rec in sorted(data): print(template.format(*rec))
def verify_inherited(self, apic, not_inherited=False): tenants = Tenant.get_deep(apic, names=['inheritanceautomatedtest']) self.assertTrue(len(tenants) > 0) tenant = tenants[0] l3out = tenant.get_child(OutsideL3, 'myl3out') self.assertIsNotNone(l3out) childepg = l3out.get_child(OutsideEPG, 'childepg') self.assertIsNotNone(childepg) if not_inherited: self.assertFalse(childepg.has_tag('inherited:fvRsProv:mycontract')) else: self.assertTrue(childepg.has_tag('inherited:fvRsProv:mycontract')) contract = tenant.get_child(Contract, 'mycontract') self.assertIsNotNone(contract) if not_inherited: self.assertFalse(childepg.does_provide(contract)) else: self.assertTrue(childepg.does_provide(contract))
def delete_tenant(self): tenant = Tenant('inheritanceautomatedtest') tenant.mark_as_deleted() apic = Session(APIC_URL, APIC_USERNAME, APIC_PASSWORD) apic.login() resp = tenant.push_to_apic(apic) self.assertTrue(resp.ok) time.sleep(4) resp = tenant.push_to_apic(apic) self.assertTrue(resp.ok) time.sleep(2) tenants = Tenant.get(apic) for tenant in tenants: self.assertTrue(tenant.name != 'inheritanceautomatedtest')
def main(): """ Main execution routine """ description = ('Simple application that logs on to the APIC' ' and displays all the tenant info of the contract_interface related to the imported contract.') creds = Credentials('apic', description) creds.add_argument("-t", "--tenant_name", help="Tenant Name of where the contract is created") creds.add_argument("-i", "--contract_name", help="Imported Contract Name") args = creds.get() if (args.tenant_name is not None) and (args.contract_name is None): args.contract_name = raw_input("Contract Name: ") session = Session(args.url, args.login, args.password) resp = session.login() if not resp.ok: print('%% Could not login to APIC') tenants = Tenant.get_deep(session) for tenant in tenants: contracts_interfaces = tenant.get_children(only_class=ContractInterface) for contract_interface in contracts_interfaces: imported_contract = contract_interface.get_import_contract() if imported_contract is not None: if args.tenant_name is not None: if (imported_contract.name == args.contract_name) and (imported_contract.get_parent().name == args.tenant_name): apps = AppProfile.get(session, tenant) for app in apps: epgs = EPG.get(session, app, tenant) for epg in epgs: data.append((imported_contract.name, tenant.name, app.name, epg.name)) else: apps = AppProfile.get(session, tenant) for app in apps: epgs = EPG.get(session, app, tenant) for epg in epgs: data.append((imported_contract.name, tenant.name, app.name, epg.name)) print tabulate(data, headers=["IMPORTED_CONTRACT", "TENANT", "APP_PROFILE", "EPG"])
def main(): """ Main show EPGs routine :return: None """ # Login to APIC description = ('Simple application that logs on to the APIC' ' and displays all of the EPGs.') creds = Credentials('apic', description) creds.add_argument('--tenant', help='The name of Tenant') args = creds.get() session = Session(args.url, args.login, args.password) resp = session.login() if not resp.ok: print('%% Could not login to APIC') # Download all of the tenants, app profiles, and EPGs # and store the names as tuples in a list tenants = Tenant.get(session) for tenant in tenants: check_longest_name(tenant.name, "Tenant") if args.tenant is None: get_epg(session, tenant) else: if tenant.name == args.tenant: get_epg(session, tenant) # Display the data downloaded template = '{0:' + str(longest_names["Tenant"]) + '} ' \ '{1:' + str(longest_names["Application Profile"]) + '} ' \ '{2:' + str(longest_names["EPG"]) + '}' print(template.format("Tenant", "Application Profile", "EPG")) print(template.format('-' * longest_names["Tenant"], '-' * longest_names["Application Profile"], '-' * longest_names["EPG"])) for rec in sorted(data): print(template.format(*rec))
def main(): """ Main create tenant routine :return: None """ # Get all the arguments description = 'It logs in to the APIC and will delete tenants named with the specified string.' creds = Credentials(['apic', 'nosnapshotfiles'], description) group = creds.add_mutually_exclusive_group() group.add_argument('--startswith', default=None, help='String to match that starts the tenant name') group.add_argument('--endswith', default=None, help='String to match that ends the tenant name') group.add_argument('--exactmatch', default=None, help='String that exactly matches the tenant name') group.add_argument('--contains', default=None, help='String that is contained in the tenant name') creds.add_argument( '--force', action='store_true', help='Attempt to remove the tenants without prompting for confirmation' ) args = creds.get() # Login to the APIC apic = Session(args.url, args.login, args.password) resp = apic.login() if not resp.ok: print('%% Could not login to APIC') # Get all of the Tenants tenants = Tenant.get(apic) # Find the list of Tenants to delete according to command line options tenants_to_delete = [] for tenant in tenants: if args.startswith is not None: if tenant.name.startswith(args.startswith): tenants_to_delete.append(tenant) elif args.endswith is not None: if tenant.name.endswith(args.endswith): tenants_to_delete.append(tenant) elif args.exactmatch is not None: if args.exactmatch == tenant.name: tenants_to_delete.append(tenant) elif args.contains is not None: if args.contains in tenant.name: tenants_to_delete.append(tenant) # Query the user to be sure of deletion if not args.force: for tenant in tenants_to_delete: prompt = 'Delete tenant %s ? [y/N]' % tenant.name try: resp = raw_input(prompt) except NameError: resp = input(prompt) if not resp.lower().startswith('y'): tenants_to_delete.remove(tenant) print('Skipping tenant', tenant.name) # Delete the tenants for tenant in tenants_to_delete: tenant.mark_as_deleted() resp = tenant.push_to_apic(apic) if resp.ok: print('Deleted tenant', tenant.name) else: print('Could not delete tenant', tenant.name) print resp.text
requests.packages.urllib3.disable_warnings() # Disable warning message # What to look for? mission_tenant = "SnV" mission_anp = "Evolution_X" success_message = "I completed the WebArya Mission and added Application {} to Tenant {}!".format( mission_anp, mission_tenant) session = Session(URL, LOGIN, PASSWORD) resp = session.login() if not resp.ok: print('%% Could not login to APIC') sys.exit(1) # Query for ACI Tenants tenants = Tenant.get(session) for tenant in tenants: # Search for Mission Tenant if tenant.name == mission_tenant: # Get Apps in Tenant apps = AppProfile.get(session, tenant) for app in apps: # Search for mission app if app.name == mission_anp: print(success_message) print("Success! Well done !") sys.exit() # Tenant and/or App not found, exit sys.exit("\nMission Failed: Application {} not found in Tenant {}\n".format( mission_anp, mission_tenant))
def main(): """ Main execution routine :return: None """ # Create a tenant tenant = Tenant('Solar_Meter') # Create a Context and Allow_All context = Context('Solar_Meter', tenant) context.set_allow_all() #Create App Profiles app_sme = AppProfile('Solar_Meter_East', tenant) app_smw = AppProfile('Solar_Meter_West', tenant) app_corp = AppProfile('Corporate_Network', tenant) # Create BridgeDomains bd_east = BridgeDomain('Bridge_Domain_East', tenant) bd_east.add_context(context) bd_east.set_arp_flood('no') bd_east.set_unicast_route('yes') subnet_east = Subnet('10.20.12.3', bd_east) subnet_east.set_addr('10.20.12.3/24') subnet_east.set_scope("public") bd_west = BridgeDomain('Bridge_Domain_West', tenant) bd_west.add_context(context) bd_west.set_arp_flood('no') bd_west.set_unicast_route('yes') subnet_west = Subnet('10.20.13.3', bd_west) subnet_west.set_addr('10.20.13.3/24') subnet_west.set_scope("public") bd_corp = BridgeDomain('Corporate_Bridge_Domain', tenant) bd_corp.add_context(context) bd_corp.set_arp_flood('no') bd_corp.set_unicast_route('yes') subnet_corp = Subnet('10.20.14.3', bd_corp) subnet_corp.set_addr('10.20.14.3/24') subnet_corp.set_scope("public") # Create an EPGs and assign to App Profiles epg_db_east = EPG('Database_EPG_East', app_sme) epg_db_east.add_bd(bd_east) epg_mw_east = EPG('Middleware_EPG_East', app_sme) epg_mw_east.add_bd(bd_east) epg_web_east = EPG('Webserver_EPG_East', app_sme) epg_web_east.add_bd(bd_east) epg_db_west = EPG('Database_EPG_West', app_smw) epg_db_west.add_bd(bd_west) epg_mw_west = EPG('Middleware_EPG_West', app_smw) epg_mw_west.add_bd(bd_west) epg_web_west = EPG('Webserver_EPG_West', app_smw) epg_web_west.add_bd(bd_west) epg_finance_corp = EPG('Corporate_Finance_EPG', app_corp) epg_finance_corp.add_bd(bd_corp) epg_hr_corp = EPG('Corporate_HR_EPG', app_corp) epg_hr_corp.add_bd(bd_corp) epg_sales_corp = EPG('Corporate_Sales_EPG', app_corp) epg_sales_corp.add_bd(bd_corp) epg_engineering_corp = EPG('Corporate_Engineering_EPG', app_corp) epg_engineering_corp.add_bd(bd_corp) epg_marketing_corp = EPG('Corporate_Marketing_EPG', app_corp) epg_marketing_corp.add_bd(bd_corp) # Attach the EPGs to interfaces using VLAN as the encap # First - Create the physical interface objects if_101_61 = Interface('eth', '1', '101', '1', '61') if_101_62 = Interface('eth', '1', '101', '1', '62') if_101_63 = Interface('eth', '1', '101', '1', '63') if_101_64 = Interface('eth', '1', '101', '1', '64') if_101_65 = Interface('eth', '1', '101', '1', '65') if_101_66 = Interface('eth', '1', '101', '1', '66') if_101_67 = Interface('eth', '1', '101', '1', '67') if_101_68 = Interface('eth', '1', '101', '1', '68') if_102_61 = Interface('eth', '1', '102', '1', '61') if_102_62 = Interface('eth', '1', '102', '1', '62') if_102_63 = Interface('eth', '1', '102', '1', '63') if_102_64 = Interface('eth', '1', '102', '1', '64') if_102_65 = Interface('eth', '1', '102', '1', '65') if_102_66 = Interface('eth', '1', '102', '1', '66') if_102_67 = Interface('eth', '1', '102', '1', '67') if_102_68 = Interface('eth', '1', '102', '1', '68') if_101_71 = Interface('eth', '1', '101', '1', '71') if_101_72 = Interface('eth', '1', '101', '1', '72') if_101_73 = Interface('eth', '1', '101', '1', '73') if_101_74 = Interface('eth', '1', '101', '1', '74') if_101_75 = Interface('eth', '1', '101', '1', '75') if_102_71 = Interface('eth', '1', '102', '1', '71') if_102_72 = Interface('eth', '1', '102', '1', '72') if_102_73 = Interface('eth', '1', '102', '1', '73') if_102_74 = Interface('eth', '1', '102', '1', '74') if_102_75 = Interface('eth', '1', '102', '1', '75') # Second - Create a VLAN interfaces vlan161_db = L2Interface('vlan161_db', 'vlan', '161') vlan261_db = L2Interface('vlan261_db', 'vlan', '261') vlan162_web = L2Interface('vlan162_web', 'vlan', '162') vlan262_web = L2Interface('vlan262_web', 'vlan', '262') vlan163_mw = L2Interface('vlan163_web', 'vlan', '163') vlan263_mw = L2Interface('vlan263_web', 'vlan', '263') vlan64_corp = L2Interface('vlan64_corp', 'vlan', '64') vlan65_corp = L2Interface('vlan65_corp', 'vlan', '65') vlan66_corp = L2Interface('vlan66_corp', 'vlan', '66') vlan67_corp = L2Interface('vlan67_corp', 'vlan', '67') vlan68_corp = L2Interface('vlan68_corp', 'vlan', '68') # Third - Attach the VLANs to the physical interfaces vlan161_db.attach(if_101_61) vlan161_db.attach(if_101_62) vlan161_db.attach(if_101_63) vlan261_db.attach(if_102_61) vlan261_db.attach(if_102_62) vlan261_db.attach(if_102_63) vlan162_web.attach(if_101_64) vlan162_web.attach(if_101_65) vlan162_web.attach(if_101_66) vlan262_web.attach(if_102_64) vlan262_web.attach(if_102_65) vlan262_web.attach(if_102_66) vlan163_mw.attach(if_101_67) vlan163_mw.attach(if_101_68) vlan263_mw.attach(if_102_67) vlan263_mw.attach(if_102_68) vlan64_corp.attach(if_101_71) vlan64_corp.attach(if_102_71) vlan65_corp.attach(if_101_72) vlan65_corp.attach(if_102_72) vlan66_corp.attach(if_101_73) vlan66_corp.attach(if_102_73) vlan67_corp.attach(if_101_74) vlan67_corp.attach(if_102_74) vlan68_corp.attach(if_101_75) vlan68_corp.attach(if_102_75) # Forth - Attach the EPGs to the VLAN interfaces epg_db_east.attach(vlan161_db) epg_db_west.attach(vlan261_db) epg_web_east.attach(vlan162_web) epg_web_west.attach(vlan262_web) epg_mw_east.attach(vlan163_mw) epg_mw_west.attach(vlan263_mw) epg_finance_corp.attach(vlan64_corp) epg_hr_corp.attach(vlan65_corp) epg_sales_corp.attach(vlan66_corp) epg_engineering_corp.attach(vlan67_corp) epg_marketing_corp.attach(vlan68_corp) # Create the Endpoints # 3x DB East & 3x DB West db_east_ep1 = Endpoint(name='East_DB_Server_1', parent=epg_db_east) db_east_ep1.mac = '00:11:11:11:11:11' db_east_ep1.ip = '10.20.12.4' db_east_ep2 = Endpoint(name='East_DB_Server_2', parent=epg_db_east) db_east_ep2.mac = '00:11:11:11:12:11' db_east_ep2.ip = '10.20.12.5' db_east_ep3 = Endpoint(name='East_DB_Server_3', parent=epg_db_east) db_east_ep3.mac = '00:11:11:11:13:11' db_east_ep3.ip = '10.20.12.6' db_west_ep1 = Endpoint(name='West_DB_Server_1', parent=epg_db_west) db_west_ep1.mac = '00:11:11:12:11:11' db_west_ep1.ip = '10.20.13.4' db_west_ep2 = Endpoint(name='West_DB_Server_2', parent=epg_db_west) db_west_ep2.mac = '00:11:11:12:12:11' db_west_ep2.ip = '10.20.13.5' db_west_ep3 = Endpoint(name='West_DB_Server_3', parent=epg_db_west) db_west_ep3.mac = '00:11:11:12:13:11' db_west_ep3.ip = '10.20.13.6' # Assign it to the L2Interface db_east_ep1.attach(vlan161_db) db_east_ep2.attach(vlan161_db) db_east_ep3.attach(vlan161_db) db_west_ep1.attach(vlan261_db) db_west_ep2.attach(vlan261_db) db_west_ep3.attach(vlan261_db) # Create the Contract between Database and Middleware contract_db2mw = Contract('contract_db2mw', tenant) icmp_entry = FilterEntry('icmpentry', applyToFrag='no', arpOpc='unspecified', dFromPort='unspecified', dToPort='unspecified', etherT='ip', prot='icmp', sFromPort='unspecified', sToPort='unspecified', tcpRules='unspecified', parent=contract_db2mw) arp_entry = FilterEntry('arpentry', applyToFrag='no', arpOpc='unspecified', dFromPort='unspecified', dToPort='unspecified', etherT='arp', prot='unspecified', sFromPort='unspecified', sToPort='unspecified', tcpRules='unspecified', parent=contract_db2mw) tcp_entry = FilterEntry('tcpentry', applyToFrag='no', arpOpc='unspecified', dFromPort='1433', dToPort='1433', etherT='ip', prot='tcp', sFromPort='1433', sToPort='1433', tcpRules='unspecified', parent=contract_db2mw) udp_entry = FilterEntry('udpentry', applyToFrag='no', arpOpc='unspecified', dFromPort='1433', dToPort='1433', etherT='ip', prot='udp', sFromPort='1433', sToPort='1433', tcpRules='unspecified', parent=contract_db2mw) # Provide and consume the Contract epg_db_east.provide(contract_db2mw) epg_db_west.provide(contract_db2mw) epg_mw_east.consume(contract_db2mw) epg_mw_west.consume(contract_db2mw) # Create the Contract between Web and Middleware contract_web2mw = Contract('contract_web2mw', tenant) icmp_entry = FilterEntry('icmpentry', applyToFrag='no', arpOpc='unspecified', dFromPort='unspecified', dToPort='unspecified', etherT='ip', prot='icmp', sFromPort='unspecified', sToPort='unspecified', tcpRules='unspecified', parent=contract_web2mw) arp_entry = FilterEntry('arpentry', applyToFrag='no', arpOpc='unspecified', dFromPort='unspecified', dToPort='unspecified', etherT='arp', prot='unspecified', sFromPort='unspecified', sToPort='unspecified', tcpRules='unspecified', parent=contract_web2mw) tcp_entry = FilterEntry('tcpentry', applyToFrag='no', arpOpc='unspecified', dFromPort='443', dToPort='443', etherT='ip', prot='tcp', sFromPort='443', sToPort='443', tcpRules='unspecified', parent=contract_web2mw) udp_entry = FilterEntry('udpentry', applyToFrag='no', arpOpc='unspecified', dFromPort='443', dToPort='443', etherT='ip', prot='udp', sFromPort='443', sToPort='443', tcpRules='unspecified', parent=contract_web2mw) # Provide and consume the Contract epg_web_east.provide(contract_web2mw) epg_web_west.provide(contract_web2mw) epg_mw_east.consume(contract_web2mw) epg_mw_west.consume(contract_web2mw) # Create the Contract for Corporate users contract_corp = Contract('contract_corp', tenant) icmp_entry = FilterEntry('icmpentry', applyToFrag='no', arpOpc='unspecified', dFromPort='unspecified', dToPort='unspecified', etherT='ip', prot='icmp', sFromPort='unspecified', sToPort='unspecified', tcpRules='unspecified', parent=contract_corp) arp_entry = FilterEntry('arpentry', applyToFrag='no', arpOpc='unspecified', dFromPort='unspecified', dToPort='unspecified', etherT='arp', prot='unspecified', sFromPort='unspecified', sToPort='unspecified', tcpRules='unspecified', parent=contract_corp) tcp_entry = FilterEntry('tcpentry', applyToFrag='no', arpOpc='unspecified', dFromPort='443', dToPort='443', etherT='ip', prot='tcp', sFromPort='443', sToPort='443', tcpRules='unspecified', parent=contract_corp) udp_entry = FilterEntry('udpentry', applyToFrag='no', arpOpc='unspecified', dFromPort='443', dToPort='443', etherT='ip', prot='udp', sFromPort='443', sToPort='443', tcpRules='unspecified', parent=contract_corp) # Provide and consume the Contract epg_engineering_corp.provide(contract_corp) epg_finance_corp.provide(contract_corp) epg_hr_corp.provide(contract_corp) epg_sales_corp.provide(contract_corp) epg_marketing_corp.provide(contract_corp) epg_web_east.consume(contract_corp) epg_web_west.consume(contract_corp) epg_mw_east.consume(contract_corp) epg_mw_west.consume(contract_corp) epg_db_east.consume(contract_corp) epg_db_west.consume(contract_corp) # Dump the necessary configuration print('URL: ' + str(tenant.get_url())) print('JSON: ' + str(tenant.get_json())) send_to_apic(tenant)
def main(): """ Main routine :return: None """ # Login to APIC description = ('Simple application that logs on to the APIC' ' and displays all of the External Subnets.') creds = Credentials('apic', description) creds.add_argument('-f', '--find_ip', help='IP address to search for') args = creds.get() session = Session(args.url, args.login, args.password) resp = session.login() if not resp.ok: print('%% Could not login to APIC') if not args.find_ip: print("Error: -f|--find_ip <ip_address> argument required") sys.exit(1) print("searching for " + args.find_ip) # Download all of the tenants, app profiles, and Subnets # and store the names as tuples in two lists priv = [] publ = [] ip = args.find_ip tenants = Tenant.get_deep(session, limit_to=['fvTenant', 'fvSubnet', 'l3extOut', 'l3extInstP', 'l3extSubnet']) for tenant in tenants: apps = AppProfile.get(session, tenant) for app in apps: bds = BridgeDomain.get(session, tenant) for bd in bds: subnets = Subnet.get(session, bd, tenant) for subnet in subnets: net = IPNetwork(subnet.addr) if net.Contains(IPNetwork(ip)): priv.append((tenant.name, app.name, bd.name, subnet.addr, subnet.get_scope())) for tenant in tenants: outside_l3s = tenant.get_children(only_class=OutsideL3) for outside_l3 in outside_l3s: outside_epgs = outside_l3.get_children(only_class=OutsideEPG) for outside_epg in outside_epgs: outside_networks = outside_epg.get_children(only_class=OutsideNetwork) for outside_network in outside_networks: net = IPNetwork(outside_network.addr) if net.Contains(IPNetwork(ip)): publ.append((tenant.name, outside_l3.name, outside_epg.name, outside_network.addr, outside_network.get_scope())) # Display template = "{0:20} {1:20} {2:20} {3:18} {4:15}" if len(priv): print("") print(template.format("Tenant", "App", "Bridge Domain", "Subnet", "Scope")) print(template.format("-" * 20, "-" * 20, "-" * 20, "-" * 18, "-" * 15)) for rec in priv: print(template.format(*rec)) if len(publ): print("") print(template.format("Tenant", "OutsideL3", "OutsideEPG", "Subnet", "Scope")) print(template.format("-" * 20, "-" * 20, "-" * 20, "-" * 18, "-" * 15)) for rec in publ: print(template.format(*rec))
def test_dual_inheritance_contract_delete_both_relations(self): config_json = { "apic": { "user_name": APIC_USERNAME, "password": APIC_PASSWORD, "ip_address": APIC_IP, "use_https": False }, "inheritance_policies": [ { "epg": { "tenant": "inheritanceautomatedtest", "epg_container": { "name": "myl3out", "container_type": "l3out" }, "name": "childepg" }, "allowed": True, "enabled": True }, { "epg": { "tenant": "inheritanceautomatedtest", "epg_container": { "name": "myl3out", "container_type": "l3out" }, "name": "parentepg1" }, "allowed": True, "enabled": False }, { "epg": { "tenant": "inheritanceautomatedtest", "epg_container": { "name": "myl3out", "container_type": "l3out" }, "name": "parentepg2" }, "allowed": True, "enabled": False } ] } args = TestArgs() apic = Session(APIC_URL, APIC_USERNAME, APIC_PASSWORD) apic.login() self.setup_tenant_with_2_parent_epgs(apic) tool = execute_tool(args, cli_mode=False) tool.add_config(config_json) time.sleep(4) # Verify that the contract is now inherited by the child EPG self.verify_inherited(apic) print 'REMOVING 1 CONTRACT' # Remove contracts tenant = Tenant('inheritanceautomatedtest') l3out = OutsideL3('myl3out', tenant) contract = self.get_contract(tenant) parent_epg1 = OutsideEPG('parentepg1', l3out) parent_epg1.provide(contract) parent_epg1.dont_provide(contract) parent_epg2 = OutsideEPG('parentepg2', l3out) parent_epg2.provide(contract) parent_epg2.dont_provide(contract) resp = tenant.push_to_apic(apic) self.assertTrue(resp.ok) print 'STARTING VERIFICATION' # Verify that the contract is still inherited by the child EPG time.sleep(4) self.verify_not_inherited(apic) self.delete_tenant()
# Take login credentials from the command line if provided # Otherwise, take them from your environment variables file ~/.profile description = ('Simple application to define 2 EPGs with a contract between them and statically ' 'connecting the EPGs to specific interfaces using a specific VLANs.') creds = Credentials('apic', description) args = creds.get() # Login to the APIC session = Session(args.url, args.login, args.password) resp = session.login() if not resp.ok: print('%% Could not login to APIC') # Create the Tenant, App Profile, and EPGs tenant = Tenant('acitoolkit-attach-with-contract') app = AppProfile('myapp', tenant) first_epg = EPG('firstepg', app) second_epg = EPG('secondepg', app) # Create the Contract to permit only ARP and ICMP contract = Contract('mycontract', tenant) icmp_entry = FilterEntry('icmpentry', applyToFrag='no', arpOpc='unspecified', dFromPort='unspecified', dToPort='unspecified', etherT='ip', prot='icmp', sFromPort='unspecified', sToPort='unspecified',
from acitoolkit import Tenant, AppProfile, EPG tenant = Tenant('mytenat') app = AppProfile('myapp', tenant) epg = EPG('myepg', app) print tenant.get_json()
def create_random_tenant(self, interfaces=[]): max_string_length = int( self._config.get('GlobalDefaults', 'MaximumStringLength')) # Create the Tenant object tenant_prefix = self._config.get('GlobalDefaults', 'TenantPrefix') tenant_name_len = random_number(1, max_string_length - len(tenant_prefix)) tenant_name = tenant_prefix + random_string(tenant_name_len) tenant = Tenant(tenant_name) # Create some number of BridgeDomains bridge_domains = [] maximum_bds = int(self._config.get('BridgeDomains', 'Maximum')) if maximum_bds > self._global_limits.max_bds: maximum_bds = self._global_limits.max_bds for i in range( 0, random_number( 0, random_number( int(self._config.get('BridgeDomains', 'Minimum')), maximum_bds))): self._global_limits.max_bds -= 1 bd = BridgeDomain( random_string(random_number(1, max_string_length)), tenant) # Randomly choose settings for the BridgeDomain if self._config.get('BridgeDomains', 'AllowFloodUnkMacUcast').lower() == 'true': bd.set_unknown_mac_unicast( random.choice( ast.literal_eval( self._config.get('BridgeDomainSettings', 'UnknownMacUnicast')))) if self._config.get( 'BridgeDomains', 'AllowOptimizedFloodUnknownMcast').lower() == 'true': bd.set_unknown_multicast( random.choice( ast.literal_eval( self._config.get('BridgeDomainSettings', 'UnknownMulticast')))) if self._config.get('BridgeDomains', 'AllowArpFlood').lower() == 'true': bd.set_arp_flood( random.choice( ast.literal_eval( self._config.get('BridgeDomainSettings', 'ArpFlood')))) if self._config.get('BridgeDomains', 'AllowDisableUnicastRoute').lower() == 'true': bd.set_unicast_route( random.choice( ast.literal_eval( self._config.get('BridgeDomainSettings', 'UnicastRoute')))) if self._config.get( 'BridgeDomains', 'AllowNonDefaultMultiDstPkt').lower() == 'true': bd.set_multidestination( random.choice( ast.literal_eval( self._config.get('BridgeDomainSettings', 'Multidestination')))) bridge_domains.append(bd) # Create some number of Contexts contexts = [] max_contexts = int(self._config.get('Contexts', 'Maximum')) if max_contexts > self._global_limits.max_contexts: max_contexts = self._global_limits.max_contexts if max_contexts > int(self._config.get('Contexts', 'MaximumPerTenant')): max_contexts = int(self._config.get('Contexts', 'MaximumPerTenant')) for i in range( 0, random_number( 0, random_number(int(self._config.get('Contexts', 'Minimum')), max_contexts))): context = Context( random_string(random_number(1, max_string_length)), tenant) self._global_limits.max_contexts -= 1 if self._config.get('Contexts', 'AllowUnenforced').lower() == 'true': context.set_allow_all(random.choice([True, False])) contexts.append(context) # Randomly associate BridgeDomains with the Contexts (or use default) for bd in bridge_domains: if random.choice([True, True, False]) and len(contexts): bd.add_context(random.choice(contexts)) # Create some number of Application Profiles apps = [] for i in range( 0, random_number( 0, random_number( int(self._config.get('ApplicationProfiles', 'Minimum')), int(self._config.get('ApplicationProfiles', 'Maximum'))))): app = AppProfile( random_string(random_number(1, max_string_length)), tenant) apps.append(app) # Create some number of EPGs and place in AppProfiles epgs = [] max_epgs = int(self._config.get('EPGs', 'Maximum')) if max_epgs > self._global_limits.max_epgs: max_epgs = self._global_limits.max_epgs if len(apps): for i in range( 0, random_number( 0, random_number(int(self._config.get('EPGs', 'Minimum')), max_epgs))): epg = EPG(random_string(random_number(1, max_string_length)), random.choice(apps)) self._global_limits.max_epgs -= 1 epgs.append(epg) # Randomly associate the EPGs to BridgeDomains bd_epg_count = [0] * len(bridge_domains) for epg in epgs: if random_number(0, 9) == 1 or len( bridge_domains) == 0: # 1 in 10 chance for no bridgedomain continue keep_trying = 100 while keep_trying: bd_choice = random_number(0, len(bridge_domains) - 1) if bd_epg_count[bd_choice] <= int( self._config.get('BridgeDomains', 'MaximumEPGs')): epg.add_bd(bridge_domains[bd_choice]) bd_epg_count[bd_choice] += 1 break else: keep_trying -= 1 # Randomly assign the EPGs to the interfaces provided interface_objs = {} for interface in interfaces: # Create the Interface objects interface_objs[interface] = Interface.create_from_name(interface) for epg in epgs: # Pick an interface interface_choice = random.choice(interfaces) # Pick a VLAN vlan_choice = 0 keep_trying = 100 while vlan_choice in self._interfaces[interface_choice]: vlan_choice = random_number( int(self._config.get('VLANs', 'Minimum')), int(self._config.get('VLANs', 'Maximum'))) keep_trying -= 1 if not keep_trying: continue # Create the VLAN interface vlan_intf = L2Interface( 'vlan%s-on-%s' % (str(vlan_choice), interface_objs[interface_choice].name.replace(' ', '')), 'vlan', str(vlan_choice)) # Attach the VLAN interface to the Interface object vlan_intf.attach(interface_objs[interface_choice]) # Attach the EPG to the VLAN interface epg.attach(vlan_intf) # Create some filters filters = [] max_filters = int(self._config.get('Filters', 'Maximum')) if max_filters > self._global_limits.max_filters: max_filters = self._global_limits.max_filters for i in range( 0, random_number( 0, random_number(int(self._config.get('Filters', 'Minimum')), max_filters))): filter = Filter(random_string(random_number(1, max_string_length)), tenant) self._global_limits.max_filters -= 1 filters.append(filter) # Create some filter entries filter_entries = [] max_filter_entries = int(self._config.get('FilterEntries', 'Maximum')) if max_filter_entries > self._global_limits.max_filter_entries: max_filter_entries = self._global_limits.max_filter_entries if len(filters): for i in range( 0, random_number( 0, random_number( int(self._config.get('FilterEntries', 'Minimum')), max_filter_entries))): applyToFrag = '0' arpOpc = '0' dFromPort = '0' dToPort = '0' prot = '0' sFromPort = '0' sToPort = '0' tcpRules = '0' stateful = '0' icmpv4T = 'not-given' icmpv6T = 'not-given' if random_chance(20): # 20% chance of ARP arpOpc = random.choice( ast.literal_eval( self._config.get('FilterEntryOptions', 'ARPCode'))) etherT = 'arp' elif random_chance( 25): # 20% of remaining 80% is non-IP (16% of total) ethertype_choices = ast.literal_eval( self._config.get('Ethertypes', 'Choice16PC')) # if not filter.has_wildcard_entry(): # ethertype_choices += ['0'] etherT = random.choice(ethertype_choices) else: # remaining is IP applyToFrag = random.choice( ast.literal_eval( self._config.get('FilterEntryOptions', 'Fragmentation'))) etherT = 'ip' if random_chance( 20 ): # Choose more obscure protocols 20% of the time prot = ConfigRandomizer._ip_protocols[random.choice( ast.literal_eval( self._config.get('IPProtocols', 'Choice20PC')))] else: prot = ConfigRandomizer._ip_protocols[random.choice( ast.literal_eval( self._config.get('IPProtocols', 'Choice80PC')))] if prot == ConfigRandomizer._ip_protocols['icmp']: icmpv4T = random.choice( ast.literal_eval( self._config.get('FilterEntryOptions', 'ICMP4Types'))) if icmpv4T != 'not-given': # APIC will complain if both icmpv4T is specified and applyToFrag is set applyToFrag = '0' elif prot == ConfigRandomizer._ip_protocols['icmpv6']: icmpv6T = random.choice( ast.literal_eval( self._config.get('FilterEntryOptions', 'ICMP6Types'))) if icmpv6T != 'not-given': # APIC will complain if both icmpv6T is specified and applyToFrag is set applyToFrag = '0' else: # Remainder is TCP or UDP dFromPort, dToPort = random_range( int( self._config.get('FilterEntryOptions', 'PortRangeMin')), int( self._config.get('FilterEntryOptions', 'PortRangeMax'))) sFromPort, sToPort = random_range( int( self._config.get('FilterEntryOptions', 'PortRangeMin')), int( self._config.get('FilterEntryOptions', 'PortRangeMax'))) if dFromPort != '0' or dToPort != '0' or sFromPort != '0' or sToPort != '0': applyToFrag = '0' if prot == ConfigRandomizer._ip_protocols['tcp']: # Randomly choose whether to specify tcpRules if random_chance(30): # TODO: should actually take odds from the config file # Choose a random number of the possible tcpRules but # if est is chosen, then it must be the only tcpRule. Otherwise, APIC rejects it tcp_rule_choices = [] tcp_rule_possibilities = ast.literal_eval( self._config.get( 'FilterEntryOptions', 'TCPRules')) tcp_choice = random.choice( tcp_rule_possibilities) tcp_rule_choices.append(tcp_choice) while tcp_choice != 'est': tcp_choice = random.choice( tcp_rule_possibilities) if tcp_choice != 'est' and tcp_choice not in tcp_rule_choices: tcp_rule_choices.append(tcp_choice) tcpRules = '' for tcp_choice in tcp_rule_choices: tcpRules += str(tcp_choice) + ',' parent = random.choice(filters) if not parent.has_entry(applyToFrag, arpOpc, dFromPort, dToPort, etherT, prot, sFromPort, sToPort, tcpRules, stateful, icmpv4T, icmpv6T): filter_entry = FilterEntry(name=random_string( random_number(1, max_string_length)), parent=parent, applyToFrag=applyToFrag, arpOpc=arpOpc, dFromPort=dFromPort, dToPort=dToPort, etherT=etherT, prot=prot, sFromPort=sFromPort, sToPort=sToPort, tcpRules=tcpRules, stateful=stateful, icmpv4T=icmpv4T, icmpv6T=icmpv6T) # for l2tp traffic type we also need to udp filter with src and dst ports 1701 if etherT == 'ip' and prot == ConfigRandomizer._ip_protocols[ 'l2tp']: filter_entry = FilterEntry( name=random_string( random_number(1, max_string_length)), parent=parent, applyToFrag='0', arpOpc=arpOpc, dFromPort='1701', dToPort='1701', etherT=etherT, prot=ConfigRandomizer._ip_protocols['udp'], sFromPort='1701', sToPort='1701', tcpRules=tcpRules, stateful=stateful, icmpv4T=icmpv4T, icmpv6T=icmpv6T) self._global_limits.max_filter_entries -= 1 # Create some Contracts contracts = [] max_contracts = int(self._config.get('Contracts', 'Maximum')) if max_contracts > self._global_limits.max_contracts: max_contracts = self._global_limits.max_contracts for i in range( 0, random_number( 0, random_number( int(self._config.get('Contracts', 'Minimum')), max_contracts))): contract = Contract( random_string(random_number(1, max_string_length)), tenant) self._global_limits.max_contracts -= 1 contracts.append(contract) # Create some ContractSubjects contract_subjects = [] if len(contracts): for i in range( 0, random_number( 0, random_number( int(self._config.get('ContractSubjects', 'Minimum')), int(self._config.get('ContractSubjects', 'Maximum'))))): contract_subject = ContractSubject( random_string(random_number(1, max_string_length)), random.choice(contracts)) contract_subjects.append(contract_subject) # Randomly assign Filters to the ContractSubjects for filter in filters: if len(contracts) and len(contract_subjects): already_picked = [] # Pick an arbitrary number of Subjects for i in range(0, random_number(1, len(contract_subjects))): pick = random_number(0, len(contract_subjects) - 1) # Only choose each subject at most once if pick not in already_picked: contract_subjects[pick].add_filter(filter) already_picked.append(pick) # Randomly provide and consume the Contracts from the EPGs for action, max_num_epgs in [ ('provide', int(self._config.get('Contracts', 'MaximumProvidingEPGs'))), ('consume', int(self._config.get('Contracts', 'MaximumConsumingEPGs'))) ]: contract_count = [0] * len(contracts) for epg in epgs: already_picked = [] for i in range(0, random_number(0, len(contracts))): keep_trying = 20 # Try 20 times to randomly pick a contract while keep_trying: pick = random_number(0, len(contracts) - 1) if pick not in already_picked and contract_count[ pick] < max_num_epgs: getattr(epg, action)(contracts[pick]) already_picked.append(pick) contract_count[pick] += 1 keep_trying = 0 else: keep_trying -= 1 # Create some Taboos taboos = [] for i in range( 0, random_number( 0, random_number(int(self._config.get('Taboos', 'Minimum')), int(self._config.get('Taboos', 'Maximum'))))): taboo = Taboo(random_string(random_number(1, max_string_length)), tenant) taboos.append(taboo) # Create some Taboo ContractSubjects taboo_contract_subjects = [] if len(taboos): for i in range( 0, random_number( 1, random_number( int( self._config.get('TabooContractSubjects', 'Minimum')), int( self._config.get('TabooContractSubjects', 'Maximum'))))): taboo_contract_subject = ContractSubject( random_string(random_number(1, max_string_length)), random.choice(taboos)) taboo_contract_subjects.append(taboo_contract_subject) # Randomly assign Filters to TabooContractSubjects for filter in filters: if len(taboo_contract_subjects): already_picked = [] # Pick an arbitrary number of Subjects for i in range(0, random_number(1, len(taboo_contract_subjects))): pick = random_number(0, len(taboo_contract_subjects) - 1) # Only choose each subject at most once if pick not in already_picked: taboo_contract_subjects[pick].add_filter(filter) already_picked.append(pick) # Randomly protect epgs with taboos for epg in epgs: if random.choice([True, False, True]) and len(taboos): epg.protect(taboos[random_number(0, len(taboos) - 1)]) return tenant
def main(): """ Main show EPGs routine :return: None """ # Login to APIC description = ('Simple application that logs on to the APIC' ' and displays all of the EPGs.') creds = Credentials('apic', description) args = creds.get() session = Session(args.url, args.login, args.password) resp = session.login() if not resp.ok: print('%% Could not login to APIC') return # Download all of the tenants, app profiles, and EPGs # and store the names as tuples in a list tenants = Tenant.get_deep(session) tenants_list = [] for tenant in tenants: tenants_dict = {} tenants_dict['name'] = tenant.name if tenant.descr: tenants_dict['description'] = tenant.descr tenants_dict['app-profiles'] = [] for app in tenant.get_children(AppProfile): app_profiles = {'name': app.name} if app.descr: app_profiles['description'] = app.descr app_profiles['epgs'] = [] for epg in app.get_children(EPG): epgs_info = {'name': epg.name} if epg.descr: epgs_info['description'] = epg.descr epgs_info['endpoints'] = [] for endpoint in epg.get_children(Endpoint): endpoint_info = {'name': endpoint.name} if endpoint.ip != '0.0.0.0': endpoint_info['ip'] = endpoint.ip try: hostname = socket.gethostbyaddr(endpoint.ip)[0] except socket.error: hostname = None if hostname: endpoint_info['hostname'] = hostname if endpoint.descr: endpoint_info['description'] = endpoint.descr epgs_info['endpoints'].append(endpoint_info) app_profiles['epgs'].append(epgs_info) tenants_dict['app-profiles'].append(app_profiles) tenants_list.append(tenants_dict) tenants_info = {'tenants': tenants_list} print(yaml.safe_dump(tenants_info, sys.stdout, indent=4, default_flow_style=False))
def push_config_to_apic(self): """ Push the configuration to the APIC :return: Requests Response instance indicating success or not """ # Set the tenant name correctly if self.cdb.has_context_config(): self.set_tenant_name(self.cdb.get_context_config().tenant_name) # Find all the unique contract providers unique_providers = {} for provided_policy in self.cdb.get_contract_policies(): if provided_policy.dst_id not in unique_providers: unique_providers[provided_policy.dst_id] = 0 else: unique_providers[provided_policy.dst_id] += 1 # Find any duplicate contracts that this provider is providing (remove) duplicate_policies = [] for provider in unique_providers: for provided_policy in self.cdb.get_contract_policies(): if provided_policy in duplicate_policies: continue if provider in provided_policy.dst_ids: for other_policy in self.cdb.get_contract_policies(): if other_policy == provided_policy or other_policy in duplicate_policies: continue if other_policy.dst_ids == provided_policy.dst_ids and other_policy.has_same_permissions(provided_policy): provided_policy.src_ids = provided_policy.src_ids + other_policy.src_ids duplicate_policies.append(other_policy) for duplicate_policy in duplicate_policies: self.cdb.remove_contract_policy(duplicate_policy) if not self.displayonly: # Log on to the APIC apic_cfg = self.cdb.get_apic_config() apic = Session(apic_cfg.url, apic_cfg.user_name, apic_cfg.password) resp = apic.login() if not resp.ok: return resp # Push all of the Contracts tenant = Tenant(self._tenant_name) for contract_policy in self.cdb.get_contract_policies(): name = contract_policy.src_id + '::' + contract_policy.dst_id descr = contract_policy.src_name + '::' + contract_policy.dst_name contract = Contract(name, tenant) contract.descr = descr for whitelist_policy in contract_policy.get_whitelist_policies(): entry_name = whitelist_policy.proto + '.' + whitelist_policy.port_min + '.' + whitelist_policy.port_max if whitelist_policy.proto == '6' or whitelist_policy.proto == '17': entry = FilterEntry(entry_name, applyToFrag='no', arpOpc='unspecified', dFromPort=whitelist_policy.port_min, dToPort=whitelist_policy.port_max, etherT='ip', prot=whitelist_policy.proto, sFromPort='1', sToPort='65535', tcpRules='unspecified', parent=contract) else: entry = FilterEntry(entry_name, applyToFrag='no', arpOpc='unspecified', etherT='ip', prot=whitelist_policy.proto, parent=contract) if self.displayonly: print json.dumps(tenant.get_json(), indent=4, sort_keys=True) else: resp = tenant.push_to_apic(apic) if not resp.ok: return resp # Push all of the EPGs if not self.displayonly: tenant = Tenant(self._tenant_name) app = AppProfile(self._app_name, tenant) # Create a Base EPG base_epg = EPG('base', app) if self.cdb.has_context_config(): context_name = self.cdb.get_context_config().name else: context_name = 'vrf1' context = Context(context_name, tenant) bd = BridgeDomain('bd', tenant) bd.add_context(context) base_epg.add_bd(bd) if self.displayonly: # If display only, just deploy the EPG to leaf 101 base_epg.add_static_leaf_binding('101', 'vlan', '1', encap_mode='untagged') else: # Deploy the EPG to all of the leaf switches nodes = Node.get(apic) for node in nodes: if node.role == 'leaf': base_epg.add_static_leaf_binding(node.node, 'vlan', '1', encap_mode='untagged') # Create the Attribute based EPGs for epg_policy in self.cdb.get_epg_policies(): epg = EPG(epg_policy.id, app) # Add all of the IP addresses epg.is_attributed_based = True epg.set_base_epg(base_epg) criterion = AttributeCriterion('criterion', epg) for node_policy in epg_policy.get_node_policies(): ipaddr = ipaddress.ip_address(unicode(node_policy.ip)) if ipaddr.is_multicast: # Skip multicast addresses. They cannot be IP based EPGs continue criterion.add_ip_address(node_policy.ip) epg.descr = epg_policy.name # Consume and provide all of the necessary contracts for contract_policy in self.cdb.get_contract_policies(): contract = None if epg_policy.id in contract_policy.src_ids: name = contract_policy.src_id + '::' + contract_policy.dst_id contract = Contract(name, tenant) epg.consume(contract) if epg_policy.id in contract_policy.dst_ids: name = contract_policy.src_id + '::' + contract_policy.dst_id if contract is None: contract = Contract(name, tenant) epg.provide(contract) if self.displayonly: print json.dumps(tenant.get_json(), indent=4, sort_keys=True) else: resp = tenant.push_to_apic(apic) return resp
def push_config_to_apic(self): """ Push the configuration to the APIC :return: Requests Response instance indicating success or not """ THROTTLE_SIZE = 500000 / 8 # Set the tenant name correctly if self._tenant_name == '' and self.cdb.has_context_config(): self.set_tenant_name(self.cdb.get_context_config().tenant_name) elif self._tenant_name == '': self.set_tenant_name('acitoolkit') # Find all the unique contract providers logging.debug('Finding the unique contract providers') unique_providers = {} for provided_policy in self.cdb.get_contract_policies(): if provided_policy.dst_id not in unique_providers: unique_providers[provided_policy.dst_id] = 0 else: unique_providers[provided_policy.dst_id] += 1 logging.debug('Found %s unique contract providers', len(unique_providers)) # Find any duplicate contracts that this provider is providing (remove) logging.debug('Finding any duplicate contracts') duplicate_policies = [] for provider in unique_providers: for provided_policy in self.cdb.get_contract_policies(): if provided_policy in duplicate_policies: continue if provider in provided_policy.dst_ids: for other_policy in self.cdb.get_contract_policies(): if other_policy == provided_policy or other_policy in duplicate_policies: continue if other_policy.dst_ids == provided_policy.dst_ids and other_policy.has_same_permissions( provided_policy): provided_policy.src_ids = provided_policy.src_ids + other_policy.src_ids duplicate_policies.append(other_policy) logging.debug( 'duplicate_policies now has %s entries', len(duplicate_policies)) logging.debug('Removing duplicate contracts') for duplicate_policy in duplicate_policies: self.cdb.remove_contract_policy(duplicate_policy) if not self.displayonly: # Log on to the APIC apic_cfg = self.cdb.get_apic_config() apic = Session(apic_cfg.url, apic_cfg.user_name, apic_cfg.password) resp = apic.login() if not resp.ok: return resp logging.debug('Generating JSON....') # Push all of the Contracts logging.debug('Pushing contracts. # of Contract policies: %s', len(self.cdb.get_contract_policies())) tenant = Tenant(self._tenant_name) for contract_policy in self.cdb.get_contract_policies(): name = contract_policy.src_name + '::' + contract_policy.dst_name contract = Contract(name, tenant) contract.descr = contract_policy.descr[0:127 - ( contract_policy.descr.count('"') + contract_policy.descr.count("'") + contract_policy.descr.count('/'))] for whitelist_policy in contract_policy.get_whitelist_policies(): entry_name = whitelist_policy.proto + '.' + whitelist_policy.port_min + '.' + whitelist_policy.port_max if whitelist_policy.proto == '6' or whitelist_policy.proto == '17': entry = FilterEntry(entry_name, applyToFrag='no', arpOpc='unspecified', dFromPort=whitelist_policy.port_min, dToPort=whitelist_policy.port_max, etherT='ip', prot=whitelist_policy.proto, sFromPort='1', sToPort='65535', tcpRules='unspecified', parent=contract) else: entry = FilterEntry(entry_name, applyToFrag='no', arpOpc='unspecified', etherT='ip', prot=whitelist_policy.proto, parent=contract) if not self.displayonly: if len(str(tenant.get_json())) > THROTTLE_SIZE: logging.debug('Throttling contracts. Pushing config...') resp = tenant.push_to_apic(apic) if not resp.ok: return resp tenant = Tenant(self._tenant_name) if self.displayonly: print json.dumps(tenant.get_json(), indent=4, sort_keys=True) else: logging.debug('Pushing remaining contracts') resp = tenant.push_to_apic(apic) if not resp.ok: return resp # Push all of the EPGs logging.debug('Pushing EPGs') if not self.displayonly: tenant = Tenant(self._tenant_name) app = AppProfile(self._app_name, tenant) if self._use_ip_epgs: # Create a Base EPG base_epg = EPG('base', app) if self.cdb.has_context_config(): context_name = self.cdb.get_context_config().name else: context_name = 'vrf1' context = Context(context_name, tenant) bd = BridgeDomain('bd', tenant) bd.add_context(context) base_epg.add_bd(bd) if self.displayonly: # If display only, just deploy the EPG to leaf 101 base_epg.add_static_leaf_binding('101', 'vlan', '1', encap_mode='untagged') else: # Deploy the EPG to all of the leaf switches nodes = Node.get(apic) for node in nodes: if node.role == 'leaf': base_epg.add_static_leaf_binding(node.node, 'vlan', '1', encap_mode='untagged') # Create the Attribute based EPGs logging.debug('Creating Attribute Based EPGs') for epg_policy in self.cdb.get_epg_policies(): if not self.displayonly: # Check if we need to throttle very large configs if len(str(tenant.get_json())) > THROTTLE_SIZE: resp = tenant.push_to_apic(apic) if not resp.ok: return resp tenant = Tenant(self._tenant_name) app = AppProfile(self._app_name, tenant) context = Context(context_name, tenant) bd = BridgeDomain('bd', tenant) bd.add_context(context) if self._use_ip_epgs: base_epg = EPG('base', app) base_epg.add_bd(bd) epg = EPG(epg_policy.name, app) # Check if the policy has the default 0.0.0.0 IP address no_default_endpoint = True for node_policy in epg_policy.get_node_policies(): if node_policy.ip == '0.0.0.0' and node_policy.prefix_len == 0: no_default_endpoint = False epg.add_bd(bd) # Add all of the IP addresses if no_default_endpoint: epg.is_attributed_based = True epg.set_base_epg(base_epg) criterion = AttributeCriterion('criterion', epg) ipaddrs = [] for node_policy in epg_policy.get_node_policies(): ipaddr = ipaddress.ip_address(unicode(node_policy.ip)) if not ipaddr.is_multicast: # Skip multicast addresses. They cannot be IP based EPGs ipaddrs.append(ipaddr) nets = ipaddress.collapse_addresses(ipaddrs) for net in nets: criterion.add_ip_address(str(net)) epg.descr = epg_policy.descr[0:127] # Consume and provide all of the necessary contracts for contract_policy in self.cdb.get_contract_policies(): contract = None if epg_policy.id in contract_policy.src_ids: name = contract_policy.src_name + '::' + contract_policy.dst_name contract = Contract(name, tenant) epg.consume(contract) if epg_policy.id in contract_policy.dst_ids: name = contract_policy.src_name + '::' + contract_policy.dst_name if contract is None: contract = Contract(name, tenant) epg.provide(contract) else: logging.debug('Creating EPGs') for epg_policy in self.cdb.get_epg_policies(): epg = EPG(epg_policy.name, app) epg.descr = epg_policy.descr[0:127] # Consume and provide all of the necessary contracts for contract_policy in self.cdb.get_contract_policies(): contract = None if epg_policy.id in contract_policy.src_ids: name = contract_policy.src_name + '::' + contract_policy.dst_name contract = Contract(name, tenant) epg.consume(contract) if epg_policy.id in contract_policy.dst_ids: name = contract_policy.src_name + '::' + contract_policy.dst_name if contract is None: contract = Contract(name, tenant) epg.provide(contract) if self.displayonly: print json.dumps(tenant.get_json(), indent=4, sort_keys=True) else: resp = tenant.push_to_apic(apic) return resp
def main(): """ Main create tenant routine :return: None """ # Get all the arguments description = 'It logs in to the APIC and will delete tenants named with the specified string.' creds = Credentials(['apic', 'nosnapshotfiles'], description) group = creds.add_mutually_exclusive_group() group.add_argument('--startswith', default=None, help='String to match that starts the tenant name') group.add_argument('--endswith', default=None, help='String to match that ends the tenant name') group.add_argument('--exactmatch', default=None, help='String that exactly matches the tenant name') group.add_argument('--contains', default=None, help='String that is contained in the tenant name') creds.add_argument('--force', action='store_true', help='Attempt to remove the tenants without prompting for confirmation') args = creds.get() # Login to the APIC apic = Session(args.url, args.login, args.password) resp = apic.login() if not resp.ok: print('%% Could not login to APIC') # Get all of the Tenants tenants = Tenant.get(apic) # Find the list of Tenants to delete according to command line options tenants_to_delete = [] for tenant in tenants: if args.startswith is not None: if tenant.name.startswith(args.startswith): tenants_to_delete.append(tenant) elif args.endswith is not None: if tenant.name.endswith(args.endswith): tenants_to_delete.append(tenant) elif args.exactmatch is not None: if args.exactmatch == tenant.name: tenants_to_delete.append(tenant) elif args.contains is not None: if args.contains in tenant.name: tenants_to_delete.append(tenant) # Query the user to be sure of deletion if not args.force: for tenant in tenants_to_delete: prompt = 'Delete tenant %s ? [y/N]' % tenant.name try: resp = raw_input(prompt) except NameError: resp = input(prompt) if not resp.lower().startswith('y'): tenants_to_delete.remove(tenant) print 'Skipping tenant', tenant.name # Delete the tenants for tenant in tenants_to_delete: tenant.mark_as_deleted() resp = tenant.push_to_apic(apic) if resp.ok: print 'Deleted tenant', tenant.name else: print 'Could not delete tenant', tenant.name print resp.text
def create_random_tenant(self, interfaces=[]): max_string_length = int( self._config.get('GlobalDefaults', 'MaximumStringLength')) # Create the Tenant object tenant_prefix = 'acitoolkitrandomized-' tenant_name_len = random_number(1, max_string_length - len(tenant_prefix)) tenant_name = tenant_prefix + random_string(tenant_name_len) tenant = Tenant(tenant_name) # Create some number of BridgeDomains bridge_domains = [] maximum_bds = int(self._config.get('BridgeDomains', 'Maximum')) if maximum_bds > self._global_limits.max_bds: maximum_bds = self._global_limits.max_bds for i in range( 0, random_number( 0, random_number( int(self._config.get('BridgeDomains', 'Minimum')), maximum_bds))): self._global_limits.max_bds -= 1 bd = BridgeDomain( random_string(random_number(1, max_string_length)), tenant) # Randomly choose settings for the BridgeDomain if self._config.get('BridgeDomains', 'AllowFloodUnkMacUcast').lower() == 'true': bd.set_unknown_mac_unicast(random.choice(['proxy', 'flood'])) if self._config.get( 'BridgeDomains', 'AllowOptimizedFloodUnknownMcast').lower() == 'true': bd.set_unknown_multicast(random.choice(['flood', 'opt-flood'])) if self._config.get('BridgeDomains', 'AllowArpFlood').lower() == 'true': bd.set_arp_flood(random.choice(['yes', 'no'])) if self._config.get('BridgeDomains', 'AllowDisableUnicastRoute').lower() == 'true': bd.set_unicast_route(random.choice(['yes', 'no'])) if self._config.get( 'BridgeDomains', 'AllowNonDefaultMultiDstPkt').lower() == 'true': bd.set_multidestination( random.choice(['drop', 'bd-flood', 'encap-flood'])) bridge_domains.append(bd) # Create some number of Contexts contexts = [] max_contexts = int(self._config.get('Contexts', 'Maximum')) if max_contexts > self._global_limits.max_contexts: max_contexts = self._global_limits.max_contexts if max_contexts > int(self._config.get('Contexts', 'MaximumPerTenant')): max_contexts = int(self._config.get('Contexts', 'MaximumPerTenant')) for i in range( 0, random_number( 0, random_number(int(self._config.get('Contexts', 'Minimum')), max_contexts))): context = Context( random_string(random_number(1, max_string_length)), tenant) self._global_limits.max_contexts -= 1 if self._config.get('Contexts', 'AllowUnenforced').lower() == 'true': context.set_allow_all(random.choice([True, False])) contexts.append(context) # Randomly associate BridgeDomains with the Contexts (or use default) for bd in bridge_domains: if random.choice([True, True, False]) and len(contexts): bd.add_context(random.choice(contexts)) # Create some number of Application Profiles apps = [] for i in range( 0, random_number( 0, random_number( int(self._config.get('ApplicationProfiles', 'Minimum')), int(self._config.get('ApplicationProfiles', 'Maximum'))))): app = AppProfile( random_string(random_number(1, max_string_length)), tenant) apps.append(app) # Create some number of EPGs and place in AppProfiles epgs = [] max_epgs = int(self._config.get('EPGs', 'Maximum')) if max_epgs > self._global_limits.max_epgs: max_epgs = self._global_limits.max_epgs if len(apps): for i in range( 0, random_number( 0, random_number(int(self._config.get('EPGs', 'Minimum')), max_epgs))): epg = EPG(random_string(random_number(1, max_string_length)), random.choice(apps)) self._global_limits.max_epgs -= 1 epgs.append(epg) # Randomly associate the EPGs to BridgeDomains bd_epg_count = [0] * len(bridge_domains) for epg in epgs: if random_number(0, 9) == 1 or len( bridge_domains) == 0: # 1 in 10 chance for no bridgedomain continue keep_trying = 100 while keep_trying: bd_choice = random_number(0, len(bridge_domains) - 1) if bd_epg_count[bd_choice] <= int( self._config.get('BridgeDomains', 'MaximumEPGs')): epg.add_bd(bridge_domains[bd_choice]) bd_epg_count[bd_choice] += 1 break else: keep_trying -= 1 # Randomly assign the EPGs to the interfaces provided interface_objs = {} for interface in interfaces: # Create the Interface objects interface_objs[interface] = Interface.create_from_name(interface) for epg in epgs: # Pick an interface interface_choice = random.choice(interfaces) # Pick a VLAN vlan_choice = 0 keep_trying = 100 while vlan_choice in self._interfaces[interface_choice]: vlan_choice = random_number( int(self._config.get('VLANs', 'Minimum')), int(self._config.get('VLANs', 'Maximum'))) keep_trying -= 1 if not keep_trying: continue # Create the VLAN interface vlan_intf = L2Interface( 'vlan%s-on-%s' % (str(vlan_choice), interface_objs[interface_choice].name.replace(' ', '')), 'vlan', str(vlan_choice)) # Attach the VLAN interface to the Interface object vlan_intf.attach(interface_objs[interface_choice]) # Attach the EPG to the VLAN interface epg.attach(vlan_intf) # Create some filters filters = [] max_filters = int(self._config.get('Filters', 'Maximum')) if max_filters > self._global_limits.max_filters: max_filters = self._global_limits.max_filters for i in range( 0, random_number( 0, random_number(int(self._config.get('Filters', 'Minimum')), max_filters))): filter = Filter(random_string(random_number(1, max_string_length)), tenant) self._global_limits.max_filters -= 1 filters.append(filter) # Create some filter entries filter_entries = [] max_filter_entries = int(self._config.get('FilterEntries', 'Maximum')) if max_filter_entries > self._global_limits.max_filter_entries: max_filter_entries = self._global_limits.max_filter_entries ip_protocols = { 'icmp': '1', 'igmp': '2', 'tcp': '6', 'egp': '8', 'igp': '9', 'udp': '17', 'icmpv6': '58', 'eigrp': '88', 'ospfigp': '89', 'pim': '103', 'l2tp': '115' } if len(filters): for i in range( 0, random_number( 0, random_number( int(self._config.get('FilterEntries', 'Minimum')), max_filter_entries))): applyToFrag = '0' arpOpc = '0' dFromPort = '0' dToPort = '0' prot = '0' sFromPort = '0' sToPort = '0' tcpRules = '0' stateful = '0' icmpv4T = 'not-given' icmpv6T = 'not-given' if random_chance(20): # 20% chance of ARP arpOpc = random.choice(['req', 'reply']) etherT = 'arp' elif random_chance( 25): # 20% of remaining 80% is non-IP (16% of total) ethertype_choices = [ 'trill', 'mpls_ucast', 'mac_security', 'fcoe' ] # if not filter.has_wildcard_entry(): # ethertype_choices += ['0'] etherT = random.choice(ethertype_choices) else: # remaining is IP applyToFrag = random.choice(['0', '1']) etherT = 'ip' if random_chance( 20 ): # Choose more obscure protocols 20% of the time prot = ip_protocols[random.choice([ 'igmp', 'egp', 'igp', 'eigrp', 'ospfigp', 'pim', 'l2tp' ])] else: prot = ip_protocols[random.choice( ['icmp', 'tcp', 'udp', 'icmpv6'])] if prot == ip_protocols['icmp']: icmpv4T = random.choice([ 'echo-rep', 'dst-unreach', 'src-quench', 'echo', 'time-exceeded', 'unspecified', 'not-given' ]) elif prot == ip_protocols['icmpv6']: icmpv6T = random.choice([ 'unspecified', 'dst-unreach', 'time-exceeded', 'echo-req', 'echo-rep', 'nbr-solicit', 'nbr-advert', 'redirect', 'not-given' ]) else: # Remainder is TCP or UDP dFromPort, dToPort = random_range(0, 65535) sFromPort, sToPort = random_range(0, 65535) if dFromPort != '0' or dToPort != '0' or sFromPort != '0' or sToPort != '0': applyToFrag = '0' if prot == ip_protocols['tcp']: # Randomly choose whether to specify tcpRules if random_chance(30): # TODO: should actually take odds from the config file # Choose a random number of the possible tcpRules but # if est is chosen, then it must be the only tcpRule. Otherwise, APIC rejects it tcp_rule_choices = [] tcp_rule_possibilities = [ 'est', 'syn', 'ack', 'fin', 'rst' ] tcp_choice = random.choice( tcp_rule_possibilities) tcp_rule_choices.append(tcp_choice) while tcp_choice != 'est': tcp_choice = random.choice( tcp_rule_possibilities) if tcp_choice != 'est' and tcp_choice not in tcp_rule_choices: tcp_rule_choices.append(tcp_choice) tcpRules = '' for tcp_choice in tcp_rule_choices: tcpRules += str(tcp_choice) + ',' parent = random.choice(filters) if not parent.has_entry(applyToFrag, arpOpc, dFromPort, dToPort, etherT, prot, sFromPort, sToPort, tcpRules, stateful, icmpv4T, icmpv6T): filter_entry = FilterEntry(name=random_string( random_number(1, max_string_length)), parent=random.choice(filters), applyToFrag=applyToFrag, arpOpc=arpOpc, dFromPort=dFromPort, dToPort=dToPort, etherT=etherT, prot=prot, sFromPort=sFromPort, sToPort=sToPort, tcpRules=tcpRules, stateful=stateful, icmpv4T=icmpv4T, icmpv6T=icmpv6T) self._global_limits.max_filter_entries -= 1 # Create some Contracts contracts = [] max_contracts = int(self._config.get('Contracts', 'Maximum')) if max_contracts > self._global_limits.max_contracts: max_contracts = self._global_limits.max_contracts for i in range( 0, random_number( 0, random_number( int(self._config.get('Contracts', 'Minimum')), max_contracts))): contract = Contract( random_string(random_number(1, max_string_length)), tenant) self._global_limits.max_contracts -= 1 contracts.append(contract) # Create some ContractSubjects if len(contracts): contract_subjects = [] for i in range( 0, random_number( 0, random_number( int(self._config.get('ContractSubjects', 'Minimum')), int(self._config.get('ContractSubjects', 'Maximum'))))): contract_subject = ContractSubject( random_string(random_number(1, max_string_length)), random.choice(contracts)) contract_subjects.append(contract_subject) # Randomly assign Filters to the ContractSubjects for filter in filters: if len(contracts) and len(contract_subjects): already_picked = [] # Pick an arbitrary number of Subjects for i in range(0, random_number(1, len(contract_subjects))): pick = random_number(0, len(contract_subjects) - 1) # Only choose each subject at most once if pick not in already_picked: contract_subjects[pick].add_filter(filter) already_picked.append(pick) # Randomly provide and consume the Contracts from the EPGs for action, max_num_epgs in [ ('provide', int(self._config.get('Contracts', 'MaximumProvidingEPGs'))), ('consume', int(self._config.get('Contracts', 'MaximumConsumingEPGs'))) ]: contract_count = [0] * len(contracts) for epg in epgs: already_picked = [] for i in range(0, random_number(0, len(contracts))): keep_trying = 20 # Try 20 times to randomly pick a contract while keep_trying: pick = random_number(0, len(contracts) - 1) if pick not in already_picked and contract_count[ pick] < max_num_epgs: getattr(epg, action)(contracts[pick]) already_picked.append(pick) contract_count[pick] += 1 keep_trying = 0 else: keep_trying -= 1 return tenant
def push_config_to_apic(self): """ Push the configuration to the APIC :return: Requests Response instance indicating success or not """ THROTTLE_SIZE = 500000 / 8 # Set the tenant name correctly if self._tenant_name == '' and self.cdb.has_context_config(): self.set_tenant_name(self.cdb.get_context_config().tenant_name) elif self._tenant_name == '': self.set_tenant_name('acitoolkit') # Find all the unique contract providers logging.debug('Finding the unique contract providers') unique_providers = {} for provided_policy in self.cdb.get_contract_policies(): if provided_policy.dst_id not in unique_providers: unique_providers[provided_policy.dst_id] = 0 else: unique_providers[provided_policy.dst_id] += 1 logging.debug('Found %s unique contract providers', len(unique_providers)) # Find any duplicate contracts that this provider is providing (remove) logging.debug('Finding any duplicate contracts') duplicate_policies = [] for provider in unique_providers: for provided_policy in self.cdb.get_contract_policies(): if provided_policy in duplicate_policies: continue if provider in provided_policy.dst_ids: for other_policy in self.cdb.get_contract_policies(): if other_policy == provided_policy or other_policy in duplicate_policies: continue if other_policy.dst_ids == provided_policy.dst_ids and other_policy.has_same_permissions(provided_policy): provided_policy.src_ids = provided_policy.src_ids + other_policy.src_ids duplicate_policies.append(other_policy) logging.debug('duplicate_policies now has %s entries', len(duplicate_policies)) logging.debug('Removing duplicate contracts') for duplicate_policy in duplicate_policies: self.cdb.remove_contract_policy(duplicate_policy) if not self.displayonly: # Log on to the APIC apic_cfg = self.cdb.get_apic_config() apic = Session(apic_cfg.url, apic_cfg.user_name, apic_cfg.password) resp = apic.login() if not resp.ok: return resp logging.debug('Generating JSON....') # Push all of the Contracts logging.debug('Pushing contracts. # of Contract policies: %s', len(self.cdb.get_contract_policies())) tenant = Tenant(self._tenant_name) for contract_policy in self.cdb.get_contract_policies(): name = contract_policy.src_name + '::' + contract_policy.dst_name contract = Contract(name, tenant) contract.descr = contract_policy.descr[0:127 - (contract_policy.descr.count('"') + contract_policy.descr.count("'") + contract_policy.descr.count('/'))] for whitelist_policy in contract_policy.get_whitelist_policies(): entry_name = whitelist_policy.proto + '.' + whitelist_policy.port_min + '.' + whitelist_policy.port_max if whitelist_policy.proto == '6' or whitelist_policy.proto == '17': entry = FilterEntry(entry_name, applyToFrag='no', arpOpc='unspecified', dFromPort=whitelist_policy.port_min, dToPort=whitelist_policy.port_max, etherT='ip', prot=whitelist_policy.proto, sFromPort='unspecified', sToPort='unspecified', tcpRules='unspecified', parent=contract) else: entry = FilterEntry(entry_name, applyToFrag='no', arpOpc='unspecified', etherT='ip', prot=whitelist_policy.proto, parent=contract) if not self.displayonly: if len(str(tenant.get_json())) > THROTTLE_SIZE: logging.debug('Throttling contracts. Pushing config...') resp = tenant.push_to_apic(apic) if not resp.ok: return resp tenant = Tenant(self._tenant_name) if self.displayonly: print json.dumps(tenant.get_json(), indent=4, sort_keys=True) else: logging.debug('Pushing remaining contracts') resp = tenant.push_to_apic(apic) if not resp.ok: return resp # Push all of the EPGs logging.debug('Pushing EPGs') if not self.displayonly: tenant = Tenant(self._tenant_name) app = AppProfile(self._app_name, tenant) if self._use_ip_epgs: # Create a Base EPG base_epg = EPG('base', app) if self.cdb.has_context_config(): context_name = self.cdb.get_context_config().name else: context_name = 'vrf1' context = Context(context_name, tenant) bd = BridgeDomain('bd', tenant) bd.add_context(context) base_epg.add_bd(bd) if self.displayonly: # If display only, just deploy the EPG to leaf 101 base_epg.add_static_leaf_binding('101', 'vlan', '1', encap_mode='untagged') else: # Deploy the EPG to all of the leaf switches nodes = Node.get(apic) for node in nodes: if node.role == 'leaf': base_epg.add_static_leaf_binding(node.node, 'vlan', '1', encap_mode='untagged') # Create the Attribute based EPGs logging.debug('Creating Attribute Based EPGs') for epg_policy in self.cdb.get_epg_policies(): if not self.displayonly: # Check if we need to throttle very large configs if len(str(tenant.get_json())) > THROTTLE_SIZE: resp = tenant.push_to_apic(apic) if not resp.ok: return resp tenant = Tenant(self._tenant_name) app = AppProfile(self._app_name, tenant) context = Context(context_name, tenant) bd = BridgeDomain('bd', tenant) bd.add_context(context) if self._use_ip_epgs: base_epg = EPG('base', app) base_epg.add_bd(bd) epg = EPG(epg_policy.name, app) # Check if the policy has the default 0.0.0.0 IP address no_default_endpoint = True for node_policy in epg_policy.get_node_policies(): if node_policy.ip == '0.0.0.0' and node_policy.prefix_len == 0: no_default_endpoint = False epg.add_bd(bd) # Add all of the IP addresses if no_default_endpoint: epg.is_attributed_based = True epg.set_base_epg(base_epg) criterion = AttributeCriterion('criterion', epg) ipaddrs = [] for node_policy in epg_policy.get_node_policies(): ipaddr = ipaddress.ip_address(unicode(node_policy.ip)) if not ipaddr.is_multicast: # Skip multicast addresses. They cannot be IP based EPGs ipaddrs.append(ipaddr) nets = ipaddress.collapse_addresses(ipaddrs) for net in nets: criterion.add_ip_address(str(net)) epg.descr = epg_policy.descr[0:127] # Consume and provide all of the necessary contracts for contract_policy in self.cdb.get_contract_policies(): contract = None if epg_policy.id in contract_policy.src_ids: name = contract_policy.src_name + '::' + contract_policy.dst_name contract = Contract(name, tenant) epg.consume(contract) if epg_policy.id in contract_policy.dst_ids: name = contract_policy.src_name + '::' + contract_policy.dst_name if contract is None: contract = Contract(name, tenant) epg.provide(contract) else: logging.debug('Creating EPGs') for epg_policy in self.cdb.get_epg_policies(): epg = EPG(epg_policy.name, app) epg.descr = epg_policy.descr[0:127] # Consume and provide all of the necessary contracts for contract_policy in self.cdb.get_contract_policies(): contract = None if epg_policy.id in contract_policy.src_ids: name = contract_policy.src_name + '::' + contract_policy.dst_name contract = Contract(name, tenant) epg.consume(contract) if epg_policy.id in contract_policy.dst_ids: name = contract_policy.src_name + '::' + contract_policy.dst_name if contract is None: contract = Contract(name, tenant) epg.provide(contract) if self.displayonly: print json.dumps(tenant.get_json(), indent=4, sort_keys=True) else: resp = tenant.push_to_apic(apic) return resp
def main(): """ Main routine :return: None """ # Login to APIC description = ('Simple application that logs on to the APIC' ' and displays all of the External Subnets.') creds = Credentials('apic', description) creds.add_argument('-f', '--find_ip', help='IP address to search for') args = creds.get() session = Session(args.url, args.login, args.password) resp = session.login() if not resp.ok: print('%% Could not login to APIC') if not args.find_ip: print("Error: -f|--find_ip <ip_address> argument required") sys.exit(1) print("searching for " + args.find_ip) # Download all of the tenants, app profiles, and Subnets # and store the names as tuples in two lists priv = [] publ = [] ip = args.find_ip tenants = Tenant.get_deep(session, limit_to=[ 'fvTenant', 'fvSubnet', 'l3extOut', 'l3extInstP', 'l3extSubnet' ]) for tenant in tenants: apps = AppProfile.get(session, tenant) for app in apps: bds = BridgeDomain.get(session, tenant) for bd in bds: subnets = Subnet.get(session, bd, tenant) for subnet in subnets: net = IPNetwork(subnet.addr) if net.Contains(IPNetwork(ip)): priv.append( (tenant.name, app.name, bd.name, subnet.addr, subnet.get_scope())) for tenant in tenants: outside_l3s = tenant.get_children(only_class=OutsideL3) for outside_l3 in outside_l3s: outside_epgs = outside_l3.get_children(only_class=OutsideEPG) for outside_epg in outside_epgs: outside_networks = outside_epg.get_children( only_class=OutsideNetwork) for outside_network in outside_networks: net = IPNetwork(outside_network.addr) if net.Contains(IPNetwork(ip)): publ.append((tenant.name, outside_l3.name, outside_epg.name, outside_network.addr, outside_network.get_scope())) # Display template = "{0:20} {1:20} {2:20} {3:18} {4:15}" if len(priv): print("") print( template.format("Tenant", "App", "Bridge Domain", "Subnet", "Scope")) print(template.format("-" * 20, "-" * 20, "-" * 20, "-" * 18, "-" * 15)) for rec in priv: print(template.format(*rec)) if len(publ): print("") print( template.format("Tenant", "OutsideL3", "OutsideEPG", "Subnet", "Scope")) print(template.format("-" * 20, "-" * 20, "-" * 20, "-" * 18, "-" * 15)) for rec in publ: print(template.format(*rec))
def push_config_to_apic(self): """ Push the configuration to the APIC :return: Requests Response instance indicating success or not """ THROTTLE_SIZE = 500000 / 8 # Set the tenant name correctly if self._tenant_name == '' and self.cdb.has_context_config(): self.set_tenant_name(self.cdb.get_context_config().tenant_name) elif self._tenant_name == '': self.set_tenant_name('acitoolkit') # Find all the unique contract providers logging.debug('Finding the unique contract providers') unique_providers = {} for provided_policy in self.cdb.get_contract_policies(): if provided_policy.dst_id not in unique_providers: unique_providers[provided_policy.dst_id] = 0 else: unique_providers[provided_policy.dst_id] += 1 logging.debug('Found %s unique contract providers', len(unique_providers)) # Find any duplicate contracts that this provider is providing (remove) logging.debug('Finding any duplicate contracts') duplicate_policies = [] for provider in unique_providers: for provided_policy in self.cdb.get_contract_policies(): if provided_policy in duplicate_policies: continue if provider in provided_policy.dst_ids: for other_policy in self.cdb.get_contract_policies(): if other_policy == provided_policy or other_policy in duplicate_policies: continue if other_policy.dst_ids == provided_policy.dst_ids and other_policy.has_same_permissions( provided_policy): provided_policy.src_ids = provided_policy.src_ids + other_policy.src_ids duplicate_policies.append(other_policy) logging.debug('duplicate_policies now has %s entries', len(duplicate_policies)) logging.debug('Removing duplicate contracts') for duplicate_policy in duplicate_policies: self.cdb.remove_contract_policy(duplicate_policy) if not self.displayonly: # Log on to the APIC apic_cfg = self.cdb.get_apic_config() apic = Session(apic_cfg.url, apic_cfg.user_name, apic_cfg.password) resp = apic.login() if not resp.ok: return resp tenant_names = [] tenant_names.append(self._tenant_name) # delete all the unwanted epgs tenant = Tenant(self._tenant_name) existing_epgs = [] if Tenant.exists(apic, tenant): tenants = Tenant.get_deep( apic, names=tenant_names, limit_to=[ 'fvTenant', 'fvAp', 'vzFilter', 'vzEntry', 'vzBrCP', 'vzSubj', 'vzRsSubjFiltAtt']) tenant = tenants[0] appProfiles = tenant.get_children(AppProfile) app = appProfiles[0] existing_epgs = app.get_children(EPG) else: app = AppProfile(self._app_name, tenant) for existing_epg in existing_epgs: matched = False if existing_epg.name != "base": for epg_policy in self.cdb.get_epg_policies(): if existing_epg.descr.split(":")[1] == epg_policy.descr.split(":")[1]: matched = True if not matched: existing_epg.mark_as_deleted() if self.displayonly: print json.dumps(tenant.get_json(), indent=4, sort_keys=True) else: logging.debug('Pushing EPGS by deleting unwanted epgs ') if len(tenant.get_children()) > 0: resp = tenant.push_to_apic(apic) if not resp.ok: return resp # delete all the unwanted contracts tenants = Tenant.get_deep( apic, names=tenant_names, limit_to=[ 'fvTenant', 'fvAp', 'vzFilter', 'vzEntry', 'vzBrCP', 'vzSubj', 'vzRsSubjFiltAtt']) tenant = tenants[0] existing_contracts = tenant.get_children(Contract) for existing_contract in existing_contracts: matched = False for contract_policy in self.cdb.get_contract_policies(): if existing_contract.descr.split("::")[1] == contract_policy.descr.split("::")[1]: matched = True if not matched: existing_contract.mark_as_deleted() exist_contract_providing_epgs = existing_contract.get_all_providing_epgs() for exist_contract_providing_epg in exist_contract_providing_epgs: exist_contract_providing_epg.mark_as_deleted() exist_contract_consuming_epgs = existing_contract.get_all_consuming_epgs() for exist_contract_consuming_epg in exist_contract_consuming_epgs: exist_contract_consuming_epg.mark_as_deleted() if self.displayonly: print json.dumps(tenant.get_json(), indent=4, sort_keys=True) else: logging.debug('Pushing contracts by deleting unwanted contracts') if len(tenant.get_children()) > 0: resp = tenant.push_to_apic(apic) if not resp.ok: return resp filterEntry_list = [] logging.debug('Generating JSON....') # Push all of the Contracts logging.debug('Pushing contracts. # of Contract policies: %s', len(self.cdb.get_contract_policies())) tenant = Tenant(self._tenant_name) if Tenant.exists(apic, tenant): tenants = Tenant.get_deep( apic, names=tenant_names, limit_to=[ 'fvTenant', 'vzFilter', 'vzEntry', 'vzBrCP', 'vzSubj', 'vzRsSubjFiltAtt']) tenant = tenants[0] existing_contracts = tenant.get_children(Contract) else: existing_contracts = tenant.get_children(Contract) # removing the unwanted contractsubject filters for each contract subject for contract_policy in self.cdb.get_contract_policies(): name = contract_policy.src_name + '::' + contract_policy.dst_name for existing_contract in existing_contracts: if existing_contract.descr.split("::")[1] == contract_policy.descr.split("::")[1]: for child_contractSubject in existing_contract.get_children(ContractSubject): for child_filter in child_contractSubject.get_filters(): matched = False for whitelist_policy in contract_policy.get_whitelist_policies(): entry_name = whitelist_policy.proto + '.' + whitelist_policy.port_min + '.' + whitelist_policy.port_max if child_filter.name == entry_name + '_Filter': matched = True continue if not matched: # TBD need to check this. this is not working child_contractSubject._remove_relation(child_filter) child_filter._remove_attachment(child_contractSubject) logging.debug('removing filter ' + child_filter.name) if self.displayonly: print json.dumps(tenant.get_json(), indent=4, sort_keys=True) else: logging.debug('Pushing contracts by deleting unwanted filters') if len(tenant.get_children()) > 0: resp = tenant.push_to_apic(apic) if not resp.ok: return resp # if num of contract_subjects is 0 then remove it finally for contract_policy in self.cdb.get_contract_policies(): name = contract_policy.src_name + '::' + contract_policy.dst_name contract = Contract(name, tenant) contract.descr = contract_policy.descr[0:127 - (contract_policy.descr.count('"') + contract_policy.descr.count("'") + contract_policy.descr.count('/'))] for whitelist_policy in contract_policy.get_whitelist_policies(): entry_name = whitelist_policy.proto + '.' + whitelist_policy.port_min + '.' + whitelist_policy.port_max if whitelist_policy.proto == '6' or whitelist_policy.proto == '17': entry = FilterEntry(entry_name, applyToFrag='no', arpOpc='unspecified', dFromPort=whitelist_policy.port_min, dToPort=whitelist_policy.port_max, etherT='ip', prot=whitelist_policy.proto, sFromPort='unspecified', sToPort='unspecified', tcpRules='unspecified', parent=contract) else: entry = FilterEntry(entry_name, applyToFrag='no', arpOpc='unspecified', etherT='ip', prot=whitelist_policy.proto, parent=contract) filterEntry_list.append(entry_name) if not self.displayonly: if len(str(tenant.get_json())) > THROTTLE_SIZE: logging.debug('Throttling contracts. Pushing config...') resp = tenant.push_to_apic(apic) if not resp.ok: return resp tenant = Tenant(self._tenant_name) if self.displayonly: print json.dumps(tenant.get_json(), indent=4, sort_keys=True) else: logging.debug('Pushing remaining contracts') resp = tenant.push_to_apic(apic) if not resp.ok: return resp # Push all of the EPGs logging.debug('Pushing EPGs') if not self.displayonly: tenants = Tenant.get_deep(apic, names=tenant_names) tenant = tenants[0] appProfiles = tenant.get_children(AppProfile) app = appProfiles[0] if self._use_ip_epgs: # Create a Base EPG base_epg = EPG('base', app) if self.cdb.has_context_config(): context_name = self.cdb.get_context_config().name else: context_name = 'vrf1' context = Context(context_name, tenant) bd = BridgeDomain('bd', tenant) bd.add_context(context) base_epg.add_bd(bd) if self.displayonly: # If display only, just deploy the EPG to leaf 101 base_epg.add_static_leaf_binding('101', 'vlan', '1', encap_mode='untagged') else: # Deploy the EPG to all of the leaf switches nodes = Node.get(apic) for node in nodes: if node.role == 'leaf': base_epg.add_static_leaf_binding(node.node, 'vlan', '1', encap_mode='untagged') # Create the Attribute based EPGs logging.debug('Creating Attribute Based EPGs') existing_epgs = app.get_children(EPG) for epg_policy in self.cdb.get_epg_policies(): if not self.displayonly: # Check if we need to throttle very large configs if len(str(tenant.get_json())) > THROTTLE_SIZE: resp = tenant.push_to_apic(apic) if not resp.ok: return resp tenant = Tenant(self._tenant_name) app = AppProfile(self._app_name, tenant) context = Context(context_name, tenant) bd = BridgeDomain('bd', tenant) bd.add_context(context) if self._use_ip_epgs: base_epg = EPG('base', app) base_epg.add_bd(bd) matched = False for existing_epg in existing_epgs: if existing_epg.name != "base": if existing_epg.descr.split(":")[1] == epg_policy.descr.split(":")[1]: matched = True break consumed_contracts = [] provided_contracts = [] if matched is True: consumed_contracts = existing_epg.get_all_consumed() provided_contracts = existing_epg.get_all_provided() epg = existing_epg else: epg = EPG(epg_policy.name, app) # Check if the policy has the default 0.0.0.0 IP address no_default_endpoint = True for node_policy in epg_policy.get_node_policies(): if node_policy.ip == '0.0.0.0' and node_policy.prefix_len == 0: no_default_endpoint = False epg.add_bd(bd) # Add all of the IP addresses if no_default_endpoint: epg.is_attributed_based = True epg.set_base_epg(base_epg) criterion = AttributeCriterion('criterion', epg) ipaddrs = [] # check if the existing nodes are there in the present config,if not delete them for node_policy in epg_policy.get_node_policies(): ipaddr = ipaddress.ip_address(unicode(node_policy.ip)) if not ipaddr.is_multicast: # Skip multicast addresses. They cannot be IP based EPGs ipaddrs.append(ipaddr) nets = ipaddress.collapse_addresses(ipaddrs) for net in nets: criterion.add_ip_address(str(net)) epg.descr = epg_policy.descr[0:127] # Consume and provide all of the necessary contracts for contract_policy in self.cdb.get_contract_policies(): contract = None if epg_policy.id in contract_policy.src_ids: name = contract_policy.src_name + '::' + contract_policy.dst_name existing = False for existing_consumed_contract in consumed_contracts: if name == existing_consumed_contract.name: existing = True contract = existing_consumed_contract if not existing: contract = Contract(name, tenant) epg.consume(contract) if epg_policy.id in contract_policy.dst_ids: name = contract_policy.src_name + '::' + contract_policy.dst_name if contract is None: existing = False for existing_provided_contract in provided_contracts: if name == existing_provided_contract.name: existing = True contract = existing_provided_contract if not existing: contract = Contract(name, tenant) epg.provide(contract) else: logging.debug('Creating EPGs') tenants = Tenant.get_deep(apic, names=tenant_names) tenant = tenants[0] appProfiles = tenant.get_children(AppProfile) if len(appProfiles) > 0: app = appProfiles[0] else: app = AppProfile(self._app_name, tenant) existing_epgs = app.get_children(EPG) for epg_policy in self.cdb.get_epg_policies(): matched = False for existing_epg in existing_epgs: if existing_epg.name != "base": if existing_epg.descr.split(":")[1] == epg_policy.descr.split(":")[1]: matched = True break consumed_contracts = [] provided_contracts = [] if matched is True: consumed_contracts = existing_epg.get_all_consumed() provided_contracts = existing_epg.get_all_provided() epg = EPG(epg_policy.name, app) epg.descr = epg_policy.descr[0:127] # Consume and provide all of the necessary contracts for contract_policy in self.cdb.get_contract_policies(): contract = None if epg_policy.id in contract_policy.src_ids: name = contract_policy.src_name + '::' + contract_policy.dst_name existing = False for existing_consumed_contract in consumed_contracts: if name == existing_consumed_contract.name: existing = True contract = existing_consumed_contract if not existing: contract = Contract(name, tenant) epg.consume(contract) if epg_policy.id in contract_policy.dst_ids: name = contract_policy.src_name + '::' + contract_policy.dst_name if contract is None: existing = False for existing_provided_contract in provided_contracts: if name == existing_provided_contract.name: existing = True contract = existing_provided_contract if not existing: contract = Contract(name, tenant) epg.provide(contract) if self.displayonly: print json.dumps(tenant.get_json(), indent=4, sort_keys=True) else: resp = tenant.push_to_apic(apic) if not resp.ok: return resp # remove the unwanted filters existing_filters = tenant.get_children(Filter) for existing_filetrEntry in existing_filters: matched = False for filterEntry in filterEntry_list: if filterEntry + '_Filter' == existing_filetrEntry.name: matched = True if not matched: existing_filetrEntry.mark_as_deleted() if self.displayonly: print json.dumps(tenant.get_json(), indent=4, sort_keys=True) else: resp = tenant.push_to_apic(apic) return resp
def main(): """ Main show EPGs routine :return: None """ # Login to APIC description = ('Simple application that logs on to the APIC' ' and displays all of the EPGs.') creds = Credentials('apic', description) args = creds.get() session = Session(args.url, args.login, args.password) resp = session.login() if not resp.ok: print('%% Could not login to APIC') return # Download all of the tenants, app profiles, and EPGs # and store the names as tuples in a list tenants = Tenant.get_deep(session) tenants_list = [] for tenant in tenants: tenants_dict = {} tenants_dict['name'] = tenant.name if tenant.descr: tenants_dict['description'] = tenant.descr tenants_dict['app-profiles'] = [] for app in tenant.get_children(AppProfile): app_profiles = {'name': app.name} if app.descr: app_profiles['description'] = app.descr app_profiles['epgs'] = [] for epg in app.get_children(EPG): epgs_info = {'name': epg.name} if epg.descr: epgs_info['description'] = epg.descr epgs_info['endpoints'] = [] for endpoint in epg.get_children(Endpoint): endpoint_info = {'name': endpoint.name} if endpoint.ip != '0.0.0.0': endpoint_info['ip'] = endpoint.ip try: hostname = socket.gethostbyaddr(endpoint.ip)[0] except socket.error: hostname = None if hostname: endpoint_info['hostname'] = hostname if endpoint.descr: endpoint_info['description'] = endpoint.descr epgs_info['endpoints'].append(endpoint_info) app_profiles['epgs'].append(epgs_info) tenants_dict['app-profiles'].append(app_profiles) tenants_list.append(tenants_dict) tenants_info = {'tenants': tenants_list} print( yaml.safe_dump(tenants_info, sys.stdout, indent=4, default_flow_style=False))