Cisco Application Centric Infrastructure Programmability

Introduction to ACI Programmability

The Cisco ACI programmability model allows complete programmatic access to the application centric infrastructure. With this access, customers can integrate network deployment into management and monitoring tools and deploy new workloads programmatically.

ACI Fabric is configured using an abstract policy model on the Cisco Application Policy Infrastructure Controller (APIC). The APIC has a very rich and complete object model that is accessible through a programmatic REST API. The API accepts and returns HTTP or HTTPS messages that contain JavaScript Object Notation (JSON) or Extensible Markup Language (XML) documents. You can use any programming language to generate the messages and the JSON or XML documents that contain the API methods or managed object (MO) descriptions.

In addition to standard REST interface, Cisco provides several open source tools/frameworks to automate and program the APIC: ACItoolkit, Cobra (Python), ACIrb (Ruby), Puppet, Ansible etc.

This section introduces the user to some basic APIC configuration use cases such as Physical domain config, VLAN pool creation and Tenant config.

Configuration

Authentication

POST http://APIC-IP/api/aaaLogin.json HTTP/1.1
Content-Type: application/json

{
    "aaaUser" : {
        "attributes" : {
            "name" : "APIC_USER",
            "pwd" : "APIC_PASSWORD"
        }
    }
}

In order to execute a request the login needs to be performed first. A cookie will get generated and stored for subsequent execution. In this script replace APIC-IP in the URL with the IP or hostname of the APIC server. If you do not have access to an ACI environment, you can use the ACI Simulator in the DevNet Sandbox.

Using Postman

If you are more comfortable with a GUI, use Postman which is a Google Chrome Browser application to make REST API calls.

Executing ACI-REST using Postman for first time:

  1. Enter the IP address of the APIC server in your browser and accept the certificate if asked.
  2. Copy POST URL, mentioned in Authentication section to the right, after replacing APIC-IP with IP address of APIC.
  3. Select method as POST
  4. Open raw JSON section.
  5. Copy BODY JSON to raw JSON body section of postman.
  6. Replace APIC_USERNAME with apic user.
  7. Replace APIC_PASSWORD with apic password.
  8. Click send button

Note: If the cookie gets expired you might have to perform the above steps again.

For subsequent REST call:

  1. Copy POST URL, after replacing APIC-IP with IP address of APIC.
  2. Select method as POST
  3. Open raw JSON section.
  4. Copy BODY JSON to raw JSON body section of postman.
  5. Click send button

Using ACI Toolkit

If you are ready to start programming, download and install the ACI Toolkit.

Environment

Required

Downloading

If you have git installed, clone the repository

git clone https://github.com/datacenter/acitoolkit.git

Installing

After downloading, install using setuptools.

cd acitoolkit python setup.py install

If you plan on modifying the actual toolkit files, you should install the developer environment that will link the package installation to your development directory.

cd acitoolkit python setup.py develop

ACI Toolkit Samples

This directory contains sample scripts that use the python library.

Set up

In order to use the examples in this directory, it is important to set the PYTHONPATH variable to include the path to the ACI toolkit or have installed the acitoolkit using setup.py.

credentials.py

Many of the samples in this directory use the file credentials.py to login to the APIC. Before running, edit the credentials.py with the username, password, and IP address for your environment.

To execute the sample files

  1. cd samples
  2. vi example.py (Copy the script here)
  3. Execute the script. example: python example.py

Sample scripts

These scripts can also be found at https://github.com/datacenter/aci-examples

Physical Domain

HTTP

POST http://APIC-IP/api/node/mo/uni.json HTTP/1.1
Content-Type: application/json
Cache-Control: no-cache

{
    "physDomP": {
        "attributes": {
            "name": "test_phy_dmn",
            "dn": "uni/phys-test_phy_dmn"
        },
        "children": [{
            "infraRsVlanNs": {
                "attributes": {
                    "tDn": "uni/infra/vlanns-[test_vlan]-dynamic"
                }
            }
        }]
    }
}

Python

import acitoolkit.acitoolkit as aci

# Define static values to pass (edit these if you wish to set differently)
DEFAULT_PHY_DOMAIN_NAME = 'test_phy_dmn'

def main():
    """
    Main create tenant routine
    :return: None
    """
    # Get all the arguments
    description = 'It logs in to APIC and will create the physical domain.'
    creds = aci.Credentials('apic', description)
    creds.add_argument('-p', '--phy_domain',
                       help='The name of physical domain',
                       default=DEFAULT_PHY_DOMAIN_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 physical Domain
    phy_dmn = aci.PhysDomain(args.phy_domain)

    # Push the physical domain to the APIC
    resp = session.push_to_apic(phy_dmn.get_url(),
                                phy_dmn.get_json())
    if not resp.ok:
        print('%% Error: Could not push configuration to APIC')
        print(resp.text)


if __name__ == '__main__':
    try:
        main()
    except KeyboardInterrupt:
        pass

Configure physical domain and attach VLAN pool to it

The physical domain profile, which stores the physical resources (ports and port-channels) and encapsulate resources (VLAN/VXLAN) that should be used for endpoint groups associated with this domain. The following example shows the creation of the physical domain by attaching AEP and VLAN pools.

VLAN Pool

HTTP

POST http://APIC-IP/api/node/mo/uni/infra/vlanns-[test_vlan]-dynamic.json HTTP/1.1
Content-Type: application/json
Cache-Control: no-cache

{
    "fvnsVlanInstP":{
        "attributes":{
            "name":"test_vlan"
        },
        "children":[
            {
                "fvnsEncapBlk":{
                    "attributes":{
                        "from":"vlan-222",
                        "to":"vlan-223"
                    }
                }
            }
        ]
    }
}

Python

import acitoolkit.acitoolkit as aci

# Define static values to pass (edit these if you wish to set differently)
DEFAULT_VLAN_NAME = 'test_vlan'

def main():
    """
    Main create tenant routine
    :return: None
    """
    # Get all the arguments
    description = 'It logs in to the APIC and will create the vlan pool.'
    creds = aci.Credentials('apic', description)
    creds.add_argument('-v', '--vlan', help='The name of vlan pool',
                       default=DEFAULT_VLAN_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 VLAN pool
    vlan_pool = aci.NetworkPool(args.vlan, 'vlan', '222', '223', 'dynamic')

    # Push the VLAN pool to the APIC
    resp = session.push_to_apic(vlan_pool.get_url(),
                                vlan_pool.get_json())
    if not resp.ok:
        print('%% Error: Could not push configuration to APIC')
        print(resp.text)


if __name__ == '__main__':
    try:
        main()
    except KeyboardInterrupt:
        pass

Configure VLAN Pool with VLAN range

The provider access function is defined when the hypervisor is using an encapsulation protocol, such as VxLAN/NVGRE, and provides the policies to impacting VxLAN/NvGRE packets from NVGRE. You do not need to provide the encapsulation VLAN and endpoint for the provider access function. The system uses the Infra VLAN (provided during APIC bootup) as the encapsulation and associates it to the default endpoint group under the default tenant. This section describe how you can manage and configure VLAN-pool on APIC using different configuration management code snippet.

Tenant Configuration

HTTP

POST http://APIC-IP/api/mo/uni.json HTTP/1.1
Content-Type: application/json
Cache-Control: no-cache

{
    "fvTenant": {
        "attributes": {
            "name": "test_tenant"
        }
    }
}

Python

import acitoolkit.acitoolkit as aci

# Define static values to pass (edit these if you wish to set differently)
DEFAULT_TENANT_NAME = 'test_tenant'

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)

    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)

    # Push the tenant 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)


if __name__ == '__main__':
    try:
        main()
    except KeyboardInterrupt:
        pass

Configure a tenant

A tenant is a logical container for application policies that enable an administrator to exercise domain-based access control. A tenant represents a unit of isolation from a policy perspective, but it does not represent a private network. Tenants can represent a customer in a service provider setting, an organization or domain in an enterprise setting, or just a convenient grouping of policies. This section describe how you can manage and configure tenant on APIC using different configuration management code snippet.