Beispiel #1
0
    def create_epg_for_vlan(self,
                            vlan,
                            mac_address=None,
                            net=None,
                            provision=True):
        epg = aci.EPG(vlan, self.app)
        bd = aci.BridgeDomain(vlan, self.tenant)

        if net:
            subnet = aci.Subnet('subnet-' + vlan, parent=bd)
            subnet.set_addr(net)
            bd.set_unicast_route('yes')
        else:
            bd.set_unicast_route('no')

        if mac_address:
            bd.set_mac(mac_address)

        bd.set_unknown_mac_unicast('flood')
        bd.set_arp_flood('yes')
        bd.add_context(self.context)
        epg.add_bd(bd)
        epg.provide(self.contract)
        epg.consume(self.contract)
        if provision:
            resp = self.session.push_to_apic(self.tenant.get_url(),
                                             self.tenant.get_json())
        else:
            print self.tenant.get_json()

        # TODO: attach domain to EPG
        # TODO: add static path binding
        return resp
Beispiel #2
0
    def create_aci_resources(self,
                             tenant_name,
                             app_profile_name,
                             epg_name,
                             bd_name,
                             bd_ip_address=None,
                             bd_mask=None):
        """

        :param tenant_name:
        :param app_profile_name:
        :param epg_name:
        :param bd_name:
        :param bd_ip_address:
        :param bd_mask:
        :return:
        """
        tenant = self.get_tenant(tenant_name)

        app = aci.AppProfile(name=app_profile_name, parent=tenant)
        epg = aci.EPG(epg_name=epg_name, parent=app)

        bd = aci.BridgeDomain(bd_name=bd_name, parent=tenant)
        epg.add_bd(bd)

        bd.set_arp_flood('yes')
        bd.set_unicast_route('yes')

        if bd_ip_address:
            bd.set_unicast_route('yes')
            subnet = aci.Subnet('', bd)
            subnet.addr = "{}/{}".format(bd_ip_address, bd_mask)
            subnet.set_scope("private")
        else:
            bd.set_unicast_route('no')

        resp = tenant.push_to_apic(self._session)
        self._logger.info("Pushed Tenant data {}".format(tenant.get_json()))

        if not resp.ok:
            raise Exception(
                'Could not push tenant configuration to APIC. Error response: {}'
                .format(resp.content))
def main():
    """
    Main create tenant routine
    :return: None
    """
    # Get all the arguments
    description = 'It logs in to the APIC and will create the tenant.'
    creds = aci.Credentials('apic', description)
    creds.add_argument('-t',
                       '--tenant',
                       help='The name of tenant',
                       default=DEFAULT_TENANT_NAME)
    creds.add_argument('-b',
                       '--bd',
                       help='The name of bridge domain',
                       default=DEFAULT_BD_NAME)
    creds.add_argument('-s',
                       '--subnet',
                       help='The name of subnet',
                       default=DEFAULT_SUBNET_NAME)
    args = creds.get()

    # Login to the APIC
    session = aci.Session(args.url, args.login, args.password)
    resp = session.login()
    if not resp.ok:
        print('%% Could not login to APIC')

    # Create the Tenant
    tenant = aci.Tenant(args.tenant)

    # Create the Bridge Domain
    bd = aci.BridgeDomain(args.bd, tenant)
    subnet = aci.Subnet(args.subnet, bd)
    subnet.set_addr('10.10.10.1/24')

    # Push the Bridge Domain to the APIC
    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)
Beispiel #4
0
def Create_BD(aci_sheet, row):
    # call login function and return session
    session = apic_login()

	# create variables by importing values from spreadsheet
    tn_name = ACI.Tenant(aci_sheet.cell_value(row, 1))
    VRF_name = ACI.Context(aci_sheet.cell_value(row, 3), tn_name)
    BD_name = ACI.BridgeDomain(aci_sheet.cell_value(row, 2), tn_name)
    advertise = aci_sheet.cell_value(row, 7)
    subnet = ACI.Subnet((aci_sheet.cell_value(row, 2) + '_subnet'), BD_name)
    subnet.set_addr(aci_sheet.cell_value(row, 6))
    OutsideL3 = ACI.OutsideL3(aci_sheet.cell_value(row, 8), tn_name)
    L3_out = aci_sheet.cell_value(row, 8)

    BD_name.add_context(VRF_name)
    BD_name.add_subnet(subnet)

    if advertise == "yes":
        BD_name.add_l3out(OutsideL3)

    resp = session.push_to_apic(tn_name.get_url(), data=tn_name.get_json())
    if resp.ok:
        print 'Bridge Domain %s deployed' % BD_name
        print '=' * 20
def main():

    # We're going to prompt the user for a desired tenant name to build from
    # and then return the name to ensure that its correct
    tenant = ACI.Tenant(input("Enter desired tenant name: "))
    print("Tenant name is: " + tenant.name)

    # Application profile name is built from the tenant name
    # and printed to validate
    ap = ACI.AppProfile(tenant.name + "-AP", tenant)
    print("AppProfile name is: " + ap.name)

    # Two EGPs are created and tied to the previously created AP
    web_epg = ACI.EPG('web', ap)
    db_epg = ACI.EPG('db', ap)

    # A VRF is built from the tenant name and printed
    vrf = ACI.Context(tenant.name + "-CTX", tenant)
    print("VRF name is: " + vrf.name)

    # Build a bridge domain from tenant name, print
    tenant_bd = ACI.BridgeDomain(tenant.name + "-BD", tenant)
    print("BD name is: " + tenant_bd.name)

    # Finally, build the subnet from tenant name, print
    tenant_bd_subnet = ACI.Subnet(tenant.name + "-Subnet", tenant_bd)
    print("Subnet name is: " + tenant_bd_subnet.name)

    # For sake of exercise, we'll just statically assign the subnet for
    # the BD
    tenant_bd_subnet.addr = "10.1.1.1/24"

    # The BD is attached to the VRF, and options are set for flooding
    tenant_bd.add_context(vrf)
    tenant_bd.set_arp_flood('no')
    tenant_bd.set_unicast_route('yes')

    # Each of the EPGs is added to the previously created BD
    web_epg.add_bd(tenant_bd)
    db_epg.add_bd(tenant_bd)

    # The first contract, defining SQL and tied to our tenant.
    # The entry is tied to the contract and includes port and other info
    sql_contract = ACI.Contract('mssql-contract', tenant)
    sql_entry_1 = ACI.FilterEntry('ms-sql',
                         applyToFrag='no',
                         arpOpc='unspecified',
                         dFromPort='1433',
                         dToPort='1433',
                         etherT='ip',
                         prot='tcp',
                         sFromPort='1',
                         sToPort='65535',
                         tcpRules='unspecified',
                         parent=sql_contract)

    # The second contract will be for web services.  Include 80 and 443
    web_contract = ACI.Contract('web-contract', tenant)
    web_entry_1 = ACI.FilterEntry('http',
                         applyToFrag='no',
                         arpOpc='unspecified',
                         dFromPort='80',
                         dToPort='80',
                         etherT='ip',
                         prot='tcp',
                         sFromPort='1',
                         sToPort='65535',
                         tcpRules='unspecified',
                         parent=web_contract)
    web_entry_2 = ACI.FilterEntry('https',
                         applyToFrag='no',
                         arpOpc='unspecified',
                         dFromPort='443',
                         dToPort='443',
                         etherT='ip',
                         prot='tcp',
                         sFromPort='1',
                         sToPort='65535',
                         tcpRules='unspecified',
                         parent=web_contract)

    # The contracts are attached to the EPGs are providers, consumers
    db_epg.provide(sql_contract)
    web_epg.consume(sql_contract)
    web_epg.provide(web_contract)

    # Physical interfaces for attachment
    intf1 = ACI.Interface('eth', '1', '101', '1', '1')
    intf2 = ACI.Interface('eth', '1', '102', '1', '1')

    # Create a single VLAN for these interfaces.  Remember, EPGs do the allow-list
    vl10_intf1_web = ACI.L2Interface('vl10_intf1_web', 'vlan', '10')
    vl10_intf2_db = ACI.L2Interface('vl10_intf2_db', 'vlan', '10')

    # Attach the logical to physical interface config
    vl10_intf1_web.attach(intf1)
    vl10_intf2_db.attach(intf2)

    # Finally attach the EPGs to the layer-2 interface configs
    web_epg.attach(vl10_intf1_web)
    db_epg.attach(vl10_intf2_db) 

    # Now the actual "configuration push" is setup
    description = 'ACIToolkit mock full tenant configuration script'
    creds = ACI.Credentials('apic', description)
    # Adding in pieces for JSON only or delete the tenant
    creds.add_argument('--delete', action='store_true',
                    help='Delete the configuration from the APIC')
    creds.add_argument('--json', const='false', nargs='?', help='JSON output only')
    args = creds.get()
    session = ACI.Session(args.url, args.login, args.password)
    session.login()

    # Several if/else to delete the tenant or print the JSON payload
    if args.delete:
        tenant.mark_as_deleted()

    if args.json:
        print("The following JSON payload was created")
        print("URL: ", tenant.get_url())
        print(json.dumps(tenant.get_json(), indent=2))

    else:
        resp = session.push_to_apic(tenant.get_url(),tenant.get_json())

        # Some error handling along the way
        if not resp.ok:
            print("%% Error: Could not push configuration to APIC")
            print(resp.text)

        else:
            print("Success")
Beispiel #6
0
    def create_epg_for_vlan(self,
                            name,
                            num,
                            mac_address=None,
                            net=None,
                            provision=True):
        """
        This creates the EPG for a given EPG, it is generally called from the main migration routine

        :param name: str name for the vlan
        :param num: str vlan id
        :param mac_address: str
        :param net: str
        :param provision: bool
        :return:
        """

        epg = aci.EPG(name, self.app)
        bd = aci.BridgeDomain(name, self.tenant)

        if net:
            subnet = aci.Subnet('subnet-' + name, parent=bd)
            subnet.set_addr(net)
            bd.set_unicast_route('yes')
        else:
            bd.set_unicast_route('no')

        if mac_address:
            bd.set_mac(mac_address)

        bd.set_unknown_mac_unicast('flood')
        bd.set_arp_flood('yes')
        bd.add_context(self.context)
        epg.add_bd(bd)
        epg.provide(self.contract)
        epg.consume(self.contract)
        # Attach physdom
        dom = aci.EPGDomain('acimigrate', epg)
        dom.tDn = 'uni/phys-{}'.format(self.physdom)

        if provision:
            resp = self.session.push_to_apic(self.tenant.get_url(),
                                             self.tenant.get_json())
            print resp.text
            # Add static binding for migration interface
            self.migration_leaves = sorted(self.migration_leaves)
            protep_str = "topology/pod-1/protpaths-{}-{}/pathep-[{}]".format(
                self.migration_leaves[0], self.migration_leaves[1],
                self.migration_vpc_rn)

            c = {
                "fvRsPathAtt": {
                    "attributes": {
                        "encap": "vlan-{}".format(num),
                        "tDn": protep_str,
                        "status": "created"
                    },
                    "children": []
                }
            }

            epgurl = '/api/mo/uni/tn-{}/ap-{}/epg-{}.json'.format(
                self.tenant, self.app, epg)
            print "Creating static path binding for {}....".format(protep_str),

            bindresp = self.session.push_to_apic(epgurl, c)
            print bindresp.status_code

        else:
            print self.tenant.get_json()

        return resp
Beispiel #7
0
# Create the Application Profile
app = ACI.AppProfile(AP_Name, tenant)

# Create the EPGs
web_epg = ACI.EPG(EPG1_Name, app)
app_epg = ACI.EPG(EPG2_Name, app)
db_epg = ACI.EPG(EPG3_Name, app)

# Create a Context and BridgeDomain
# Place all EPGs in the Context and in the same BD
context = ACI.Context(Context_Name, tenant)
bd = ACI.BridgeDomain(BD_Name, tenant)

# Define a subnet in the BridgeDomain
subnet1 = ACI.Subnet('Subnet1', bd)
subnet2 = ACI.Subnet('Subnet2', bd)
subnet1.set_addr('10.20.30.1/24')
subnet2.set_addr('192.168.1.1/24')

# Add Context and Subnets to BridgeDomain
bd.add_context(context)
bd.add_subnet(subnet1)
bd.add_subnet(subnet2)

# Define three EPGs
web_epg.add_bd(bd)
app_epg.add_bd(bd)
db_epg.add_bd(bd)

# Define a contract with a single entry
Beispiel #8
0
def create_unique(session):
    # Objects for the ESXi servers in a tenant
    uni_pn = 'ESXi_PN'
    uni_bd = 'ESXi_BD'
    uni_app = 'ESXi_mgmt'
    uni_1_epg = 'Management'
    uni_2_epg = 'VMotion'
    uni_3_epg = 'Storage_acc'
    ip_segments = [
        '10.1.1.1/24',
    ]

    # Valid options for the scape are 'private', 'public', and 'shared'.  Comma seperated, and NO spaces
    subnet_scope = 'private,shared'

    # Connect to the VMM Domain
    # This must already exist.  It should have been created in this script
    vmmdomain = vmm_name

    # Setup or credentials and session
    description = ('Create EPGs for ESXi servers in a tenant.')

    # Get the virtual domain we are going to use
    vdomain = ACI.EPGDomain.get_by_name(session, vmmdomain)
    tenant = ACI.Tenant(unique_tenant)
    app = ACI.AppProfile(uni_app, tenant)

    # Create the EPGs
    u1_epg = ACI.EPG(uni_1_epg, app)
    u2_epg = ACI.EPG(uni_2_epg, app)
    u3_epg = ACI.EPG(uni_3_epg, app)

    # Create a Context and BridgeDomain
    # Place all EPGs in the Context and in the same BD
    context = ACI.Context(uni_pn, tenant)
    ubd = ACI.BridgeDomain(uni_bd, tenant)
    ubd.add_context(context)
    for subnet_ip in ip_segments:
        ran_name = [random.choice(string.hexdigits).lower() for n in xrange(6)]
        sub_name = ''.join(ran_name)
        asubnet = ACI.Subnet(sub_name, ubd)
        asubnet.set_addr(subnet_ip)
        asubnet.set_scope(subnet_scope)

    u1_epg.add_bd(ubd)
    u1_epg.add_infradomain(vdomain)
    u2_epg.add_bd(ubd)
    u2_epg.add_infradomain(vdomain)
    u3_epg.add_bd(ubd)
    ''' 
    Define contracts with a multiple entries
    '''
    contract1 = ACI.Contract('esxi_clients', tenant)
    filters = [['HTTPS', '443', 'tcp'], ['HTTP', '80', 'tcp'],
               ['SSH', '22', 'tcp']]
    for filt in filters:
        entry = ACI.FilterEntry(filt[0],
                                applyToFrag='no',
                                arpOpc='unspecified',
                                dFromPort=filt[1],
                                dToPort=filt[1],
                                etherT='ip',
                                prot=filt[2],
                                tcpRules='unspecified',
                                parent=contract1)

    # Attach the contracts
    u1_epg.provide(contract1)

    # CAUTION:  The next line will DELETE the tenant
    # tenant.mark_as_deleted()
    resp = tenant.push_to_apic(session)

    if resp.ok:
        # Uncomment the next lines if you want to see the configuration
        # print('URL: '  + str(tenant.get_url()))
        # print('JSON: ' + str(tenant.get_json()))
        return True
    else:
        return False