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 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 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 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 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
from acitoolkit import Tenant, AppProfile, EPG tenant = Tenant('mytenat') app = AppProfile('myapp', tenant) epg = EPG('myepg', app) print tenant.get_json()
second_epg.add_bd(bd) # Create the physical interface objects representing the physical ethernet ports first_intf = Interface('eth', '1', '101', '1', '17') second_intf = Interface('eth', '1', '102', '1', '17') # Create a VLAN interface and attach to each physical interface first_vlan_intf = L2Interface('vlan5-on-eth1-101-1-17', 'vlan', '5') first_vlan_intf.attach(first_intf) second_vlan_intf = L2Interface('vlan5-on-eth1-102-1-17', 'vlan', '5') second_vlan_intf.attach(second_intf) # Attach the EPGs to the VLAN interfaces first_epg.attach(first_vlan_intf) second_epg.attach(second_vlan_intf) # Push the tenant configuration to the APIC resp = session.push_to_apic(tenant.get_url(), tenant.get_json()) if not resp.ok: print('%% Error: Could not push the tenant configuration to APIC') # Push the interface attachments to the APIC resp = first_intf.push_to_apic(session) if not resp.ok: print('%% Error: Could not push interface configuration to APIC') resp = second_intf.push_to_apic(session) if not resp.ok: print('%% Error: Could not push interface configuration to APIC')