Session Module

The session module handles tasks that are associated with opening a session to an APIC or Fabric Node.

The session module contains two classes to open sessions with the APIC or Fabric Nodes:

  1. LoginSession - uses a username and password to login
  2. CertSession - uses a private key to generate signatures for every transaction, the user needs to have a X.509 certificate associated with their local user.

The LoginSession is the most robust method allowing access to both the APIC’s and the Fabric Nodes (switches) and can support all methods of RBAC. The CertSession method of generating signatures is limited to only communicating with the APIC and can not support any form of RBAC. One other limitation of CertSession type of sesions is there is no support for eventchannel notifications.

To make changes to the APIC configuration using the Python API, you must use a user with write privileges. When using a LoginSession, once a user is authenticated, the API returns a data structure that includes a session timeout period in seconds and a token that represents the session. The token is also returned as a cookie in the HTTP response header. To maintain your session, you must send login refresh messages to the API within the session timeout period. The token changes each time that the session is refreshed.

The following sections describe the classes in the session module.

AbstractSession

Class that abstracts sessions. This is used by LoginSession and CertSession and should not be instantiated directly. Instead use one of the other session classes.

class cobra.mit.session.AbstractSession(controllerUrl, secure, timeout, requestFormat)[source]

Abstract session class.

Other sessions classes should derive from this class.

secure

Only used for https. If True the remote server will be verified for authenticity. If False the remote server will not be verified for authenticity - readonly

Type:bool
timeout

Request timeout - readonly

Type:int
url

The APIC or fabric node URL - readonly

Type:str
formatType

The format type for the request - readonly

Type:str
formatStr

The format string for the request, either xml or json - readonly

Type:str
__init__(controllerUrl, secure, timeout, requestFormat)[source]

Initialize an AbstractSession instance.

Parameters:
  • controllerURL (str) – The URL to reach the controller or fabric node
  • secure (bool) – Only used for https. If True the remote server will be verified for authenticity. If False the remote server will not be verified for authenticity.
  • timeout (int) – Request timeout
  • requestFormat (str) – The format to send the request in. Valid values are xml or json.
Raises:

NotImplementedError – If the requestFormat is not valid

codec

Get the codec being used for this session.

Returns:The codec being used for this session.
Return type:cobra.mit.codec.AbstractCodec
formatStr

Get the format string for this session.

Returns:
The formatType represented as a string. Currently this is
either ‘xml’ or ‘json’.
Return type:str
formatType

Get the format type for this session.

Returns:The format type represented as an integer
Return type:int
get(queryObject)[source]

Perform a query using the specified queryObject.

Parameters:queryObject (cobra.mit.request.AbstractQuery) – The query object to use for the query.
Returns:The query response parsed into a managed object
Return type:cobra.mit.mo.Mo
login()[source]

Login to the remote server.

A generic login method that should be overridden by classes that derive from this class

logout()[source]

Logout from the remote server.

A generic logout method that should be overridden by classes that derive from this class

post(requestObject)[source]

Perform a request using the specified requestObject.

Parameters:requestObject (cobra.mit.request.AbstractRequest) – The request object to use for the request.
Returns:The raw requests response.
Return type:requests.response
refresh()[source]

Refresh the session to the remote server.

A generic refresh method that should be overridden by classes that derive from this class

secure

Get the secure value.

Returns:
True if the certificate for remote device should be verified,
False otherwise.
Return type:bool
timeout

Get the request timeout value.

Returns:The time a request is allowed to take before an error is raised.
Return type:int
url

Get the URL for the remote system.

Returns:The URl for the remote system.
Return type:str

LoginSession

Class that creates a login session with a username and password.

Example of using a LoginSession:

from cobra.mit.access import MoDirectory
from cobra.mit.session import LoginSession

session = LoginSession('http://10.1.1.1', 'user', 'password', secure=False)
moDir = MoDirectory(session)
moDir.login()
allTenants = moDir.lookupByClass('fvTenant')
for tenant in allTenants:
    print(tenant.name)
class cobra.mit.session.LoginSession(controllerUrl, user, password, secure=False, timeout=90, requestFormat='xml')[source]

A login session with a username and password.

Note

The username and password are stored in memory.

user

The username to use for this session - readonly

Type:str
password

The password to use for this session - readonly

Type:str
cookie

The authentication cookie string for this session

Type:str or None
challenge

The authentication challenge string for this session

Type:str or None
version

The APIC software version returned once successfully logged in - readonly

Type:str or None
refreshTime

The relative login refresh time. The session must be refreshed by this time or it times out - readonly

Type:str or None
refreshTimeoutSeconds

The number of seconds for which this session is valid - readonly

Type:str or None
domains

A list of possible login domains. The list is only populated once getLoginDomains() is called and this method can be called prior to logging in.

Type:list
loginDomain

The login domain that should be used to login to the remote device. This is used to build a username that uses the loginDomain.

Type:str
banner

The banner set on the APIC. This is set when the getLoginDomains() method is called.

Type:str
secure

Only used for https. If True the remote server will be verified for authenticity. If False the remote server will not be verified for authenticity - readonly

Type:bool
timeout

Request timeout - readonly

Type:int
url

The APIC or fabric node URL - readonly

Type:str
formattype

The format type for the request - readonly

Type:str
formatStr

The format string for the request, either xml or json - readonly

Type:str
__init__(controllerUrl, user, password, secure=False, timeout=90, requestFormat='xml')[source]

Initialize a LoginSession instance.

Parameters:
  • controllerURL (str) – The URL to reach the controller or fabric node
  • user (str) – The username to use to authenticate
  • password (str) – The password to use to authenticate
  • secure (bool) – Only used for https. If True the remote server will be verified for authenticity. If False the remote server will not be verified for authenticity.
  • timeout (int) – Request timeout
  • requestFormat (str) – The format to send the request in. Valid values are xml or json.
banner

Get the banner.

Returns:
The banner or an empty string if the getLoginDomains method has
not been called.
Return type:str
challenge

Get the challenge key value.

Returns:The challeng key value.
Return type:str
cookie

Get the session cookie value.

Returns:The value of the session cookie.
Return type:str
domains

Get the session login domains.

Returns:The list of login domains.
Return type:list
getHeaders(uriPathAndOptions, data)[source]

Get the HTTP headers for a given URI path and options string.

Parameters:
  • uriPathAndOptions (str) – The full URI path including the options string
  • data (str) – The payload
Returns:

The headers for this session class

Return type:

dict

getLoginDomains()[source]

Get the possible login domains prior to login.

The domains are returned as a list.

login()[source]

Login in to the remote server (APIC or Fabric Node).

Raises:LoginError – If there was an error during login or the response could not be parsed.
loginDomain

Get the loginDomain.

Returns:The loginDomain.
Return type:str
logout()[source]

Logout of the remote server (APIC or Fabric Node).

Currently this method does nothing

password

Get the password being used for this session.

Returns:The session password.
Return type:str
refresh()[source]

Refresh a session with the remote server (APIC or Fabric Node).

Raises:LoginError – If there was an error when refreshing the session or the response could not be parsed.
refreshTime

Get the refresh time.

Returns:The refresh time returned by the login request.
Return type:int
refreshTimeoutSeconds

Get the refresh timeout in seconds.

Returns:The refresh timeout in seconds returned by the login request.
Return type:int
user

Get the username being used for this session.

This can not be changed. If you need to change the session username, instantiate a new session object.

If the loginDomain is set, the username is set to:

apic:<loginDomain>\<user>
Returns:The username for this session.
Return type:str
version

Get the version.

Returns:The version returned by the login request.
Return type:str

CertSession

Class that creates a unique token per URI path based on a signature created by a SSL. Locally this uses a private key to create that signature. On the APIC you have to already have provided a certificate with the users public key via the aaaUserCert class. This uses PyOpenSSL if it is available (install Cobra with the [ssl] option). If PyOpenSSL is not available this will try to fallback to openssl using subprocess and temporary files that should work for most platforms.

Steps to utilize CertSession

  1. Create a local user on the APIC with a X.509 certificate in PEM format
  2. Instantiate a CertSession class with the users certificate Dn and the private key
  3. Make POST/GET requests using the Python SDK

Step 1: Create a local user with X.509 Certificate

The following is an example of how to use the Python SDK to configure a local user with a X.509 certificate. This is a required step and can be completed using the GUI, the REST API or the Python SDK. Once the local user exists and has a X.509 certificate attached to the local user, then the CertSession class can be used for that user.

# Generation of a certificate and private key using the subprocess module to
# make direct calls to openssl at the shell level.  This assumes that
# openssl is installed on the system.

from subprocess import Popen, CalledProcessError, PIPE
from cobra.mit.access import MoDirectory
from cobra.mit.session import LoginSession
from cobra.mit.request import ConfigRequest
from cobra.model.pol import Uni as PolUni
from cobra.model.aaa import UserEp as AaaUserEp
from cobra.model.aaa import User as AaaUser
from cobra.model.aaa import UserDomain as AaaUserDomain
from cobra.model.aaa import UserRole as AaaUserRole
from cobra.model.aaa import UserCert as AaaUserCert

certUser = 'myuser'
pKeyFile = 'myuser.key'
certFile = 'myuser.cert'

# Generate the certificate in the current directory
cmd = ["openssl", "req", "-new", "-newkey", "rsa:1024", "-days", "36500",
       "-nodes", "-x509", "-keyout", pKeyFile, "-out", certFile,
       "-subj", "/CN=Generic/O=Acme/C=US"]
proc = Popen(cmd, stdin=PIPE, stdout=PIPE, stderr=PIPE)
out, error = proc.communicate()
# If an error occurs, fail
if proc.returncode != 0:
    print("Output: {0}, Error {1}".format(out, error))
    raise CalledProcessError(proc.returncode, " ".join(cmd))

# At this point pKeyFile and certFile exist as files in the local directory.
# pKeyFile will be used when we want to generate signatures.  certFile is
# contains the X.509 certificate (with public key) that needs to be pushed
# to the APIC for a local user.

with open(certFile, "r") as file:
    PEMdata = file.read()

# Generate a local user to commit to the APIC
polUni = PolUni('')
aaaUserEp = AaaUserEp(polUni)
aaaUser = AaaUser(aaaUserEp, certUser)
aaaUserDomain = AaaUserDomain(aaaUser, name='all')
# Other aaaUserRoles maybe needed to give the user other privileges
aaaUserRole = AaaUserRole(aaaUserDomain, name='read-all',
                          privType='readPriv')
# Attach the certificate to that user.
aaaUserCert = AaaUserCert(aaaUser, certUser + '-cert')
# Using the data read in from the certificate file.
aaaUserCert.data = PEMdata

# Push the new local user to the APIC
session = LoginSession('https://10.1.1.1', 'admin', 'ins3965!', secure=False)
moDir = MoDirectory(session)
moDir.login()
cr = ConfigRequest()
cr.addMo(aaaUser)
moDir.commit(cr)

Steps 2 and 3: Instantiate and use a CertSession class

This step requires you know two pieces of information:

  1. The users certificate distinguished name (Dn)
  2. The private key that was created at the time of the certificate

The private key should be kept secret to ensure the highest levels of security for this type of session.

The certificate Dn will be in the form of:

uni/userext/user-<userid>/usercert-<certName>

You can also use a aaaUserCert managed object to get this Dn - as in the example below. The following example shows how to query the APIC for all tentants using a CertSession:

from cobra.mit.access import MoDirectory
from cobra.mit.session import CertSession
from cobra.model.pol import Uni as PolUni
from cobra.model.aaa import UserEp as AaaUserEp
from cobra.model.aaa import User as AaaUser
from cobra.model.aaa import UserCert as AaaUserCert

certUser = 'myuser'
pKeyFile = 'myuser.key'

# Generate a local user object that matches the one on the APIC
# This is only being used to get the Dn of the user's certificate
polUni = PolUni('')
aaaUserEp = AaaUserEp(polUni)
aaaUser = AaaUser(aaaUserEp, certUser)
# Attach the certificate to that user.
aaaUserCert = AaaUserCert(aaaUser, certUser + '-cert')

# Read in the private key data from a file in the local directory
with open(pKeyFile, "r") as file:
    pKey = file.read()

# Instantiate a CertSession using the dn and private key
session = CertSession('https://10.1.1.1', aaaUserCert.dn, pKey, secure=False)
moDir = MoDirectory(session)

# No login is required for certificate based sessions
allTenants = moDir.lookupByClass('fvTenant')
print(allTenants)
class cobra.mit.session.CertSession(controllerUrl, certificateDn, privateKey, secure=False, timeout=90, requestFormat='xml')[source]

A session using a certificate dn and private key to generate signatures.

certificateDn

The distingushed name (Dn) for the users X.509 certificate - readonly

Type:str
privateKey

The private key to use when calculating signatures. Must be paired with the private key in the X.509 certificate - readonly

Type:str
cookie

The authentication cookie string for this session

Type:str or None
challenge

The authentication challenge string for this session

Type:str or None
version

The APIC software version returned once successfully logged in - readonly

Type:str or None
refreshTime

The relative login refresh time. The session must be refreshed by this time or it times out - readonly

Type:str or None
refreshTimeoutSeconds

The number of seconds for which this session is valid - readonly

Type:str or None
secure

Only used for https. If True the remote server will be verified for authenticity. If False the remote server will not be verified for authenticity - readonly

Type:bool
timeout

Request timeout - readonly

Type:int
url

The APIC or fabric node URL - readonly

Type:str
formattype

The format type for the request - readonly

Type:str
formatStr

The format string for the request, either xml or json - readonly

Type:str
__init__(controllerUrl, certificateDn, privateKey, secure=False, timeout=90, requestFormat='xml')[source]

Initialize a CertSession instance.

Parameters:
  • controllerURL (str) – The URL to reach the controller or fabric node
  • certificateDn (str) – The distinguished name of the users certificate
  • privateKey (str) – The private key to be used to calculate a signature
  • secure (bool) – Only used for https. If True the remote server will be verified for authenticity. If False the remote server will not be verified for authenticity.
  • timeout (int) – Request timeout
  • requestFormat (str) – The format to send the request in. Valid values are xml or json.
certificateDn

Get the certificateDn for the user for this session.

Returns:The certifcate Dn for this session.
Return type:str
getHeaders(uriPathAndOptions, data)[source]

Get the HTTP headers for a given URI path and options string.

Parameters:
  • uriPathAndOptions (str) – The full URI path including the options string
  • data (str) – The payload
Returns:

The headers for this session class

Return type:

dict

getLoginDomains()[source]

The getLoginDomains method.

Not (yet) relevant for CertSession but is included for consistency.

login()[source]

login method.

Not relevant for CertSession but is included for consistency.

logout()[source]

logout method.

Not relevant for CertSession but is included for consistency.

privateKey

Get the private key for this session.

Returns:The private key as a string.
Return type:str
static readFile(fileName=None, mode='r')[source]

Convenience method to read some data from a file.

Parameters:
  • fileName (str) – The file to read from, default = None
  • mode (str) – The read mode, default = “r”, Windows may require “rb”
Returns:

The data read from the file

Return type:

str

refresh()[source]

refresh method.

Not relevant for CertSession but is included for consistency.

static runCmd(cmd)[source]

Convenience method to run a command using subprocess.

Parameters:cmd (str) – The command to run
Returns:The output from the command
Return type:str
Raises:subprocess.CalledProcessError – If an non-zero return code is sent by the process
static writeFile(fileName=None, mode='w', fileData=None)[source]

Convenience method to write data to a file.

Parameters:
  • fileName (str) – The file to write to, default = None
  • mode (str) – The write mode, default = “w”
  • fileData (varies) – The data to write to the file