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 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 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 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 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))
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 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 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))