Example #1
0
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_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 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 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
Example #7
0
    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()
Example #12
0
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))
Example #13
0
 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))
Example #14
0
 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"])
Example #16
0
    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
Example #17
0
    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 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
Example #19
0
    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 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))
Example #21
0
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))
Example #22
0
    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',