CX Drive (CXD)

Note

This page builds upon the command execution feature in Command execution. No additional service configuration is required for CXD.

CXD Introduction

Cisco Customer eXperience Drive (CXD) is a multi-protocol file transfer service with a full automation and orchestration backend. It allows file uploads using simple protocols that are supported by all devices rather than complex APIs.

Uploading data to CXD can be done using HTTPS PUT, FTPS, implicit and explicit TLS, SCP, and SFTP, with basic authentication using a target ID and an upload token as credentials.

A target is defined by the intended destination for the data:

  • for a TAC Service Request, the target is the SR number;

  • for a CS Engagement, the target is the engagement ID;

CXD in RADKit

RADKit allows a user to query the upload tokens of targets, as well as to trigger direct data uploads from remote devices to CXD targets.

For example, a user can run a set of show commands on a device and have the results attached directly to a TAC SR.

The cxd object

The RADKit Client provides a CXD instance that allows the user to interact with CXD. The object is called cxd and is part of the global context in the REPL. Alternatively, this object can also be accessed through client.integrations.cxd.

>>> type(cxd)
<class 'radkit_client.sync.integrations.cxd.CXD'>

In a standalone Python script, a similar object can be created by deriving the CXD object from a Client object:

from radkit_client import Client

with Client.create() as client:
    client.sso_login("user@domain")
    cxd = client.integrations.cxd

Authentication (optional)

Note

This step can be skipped if radkit-client is already authenticated by executing something like:

client.sso_login("user@domain", provider="okta")

In order to upload to CXD, we need a CXD upload token. If we got an upload token already (for a specific CXD target), then we can go ahead and upload straight to the target using the upload token (see next section). Otherwise authentication is required for retrieving an upload token. This can be done in two ways:

  1. A Cisco OAuth token. This works both for internal and external users. The OAuth token must be an OKTA-provided token as CXD supports OKTA only. Okta is the default provider for RADKit.

  2. Dedicated client credentials provisioned by the CXD team. This is Cisco Internal Only.

If radkit-client is already authenticated to the cloud, then the CXD object will automatically make use of this authenticated connection, and take the oauth bearer token from there. However, if this is not the case, or if multiple cloud connections have been established previously, then we can specify an authenticator. We can do that when adding a target (see next section), or we can set a default authenticator using any of these methods:

Once the authenticator is set, it will be able to retrieve and store CXD Upload Tokens that will be used in all upload requests to CXD.

Note that CXD handles authorization through Support Case Manager (SCM) and CS Console, the logged-in user must be authorized to upload files to the target to be able to retrieve an upload token.

# Derive from the Client instance (recommended)
client.sso_login("user@domain", provider="okta")

# The 'cxd' object:
client.integrations.cxd

# Passing a OAuth Token
client.sso_login("user@domain")
cxd.set_default_authenticator_from_oauth_token(token=client.access_token)

# Credentials authentication
cxd.set_default_authenticator_from_client_id_secret(
    client_id="fdsfsabc-12x34r2433-13123313", client_secret="*********"
)

Adding targets

Note

Adding targets explicitly is only needed if they have to be associated with a specific authenticator or upload token. Otherwise, this can be skipped, and the default authenticator or cloud connection will be used.

Targets can be added using any of the following methods.

That targets that have been added are accessible through targets, and can be removed again through remove_target().

Retrieving target upload parameters

There are multiple parameters that need to be obtained for a successful file transfer. To save the user from having to handle all those details, RADKit Client provides the UploadParameters to handle that information.

When the cxd object is called, a target ID and a destination file name must be provided, based on that information the cxd object will return an HTTPUploadParameters object that can be passed to any subsequent operation that supports CXD, described below.

# Retrieve UploadParameters for TAC SR 6xxxxxxxx destination file name show_commands.txt
upload_params = cxd("6xxxxxxxx", "show_commands.txt")

# The above is a shorthand for:
upload_params = cxd.get_upload_parameters("6xxxxxxxx", "show_commands.txt")

Uploading local files to CXD

Local files and piped outputs can be uploaded through CXD using the upload_to_cxd method. When the upload_to_cxd method is called, a target ID and local filename (the file to upload) are required. Optionally, a target ID, destination filename and data string can be provided. When a destination filename is not provided, the local filename will be used.

# upload /temp/myfile.txt to CXD (destination file name will be: myfile.txt)
cxd.upload_to_cxd('6xxxxxxxx', "/temp/myfile.txt")

# upload /temp/myfile.txt to CXD, change the destination file name to newfile.txt
cxd.upload_to_cxd('6xxxxxxxx', "/temp/myfile.txt", destination_file_name="newfile.txt")

# upload the output from an exec command with a destination file name as "exec-output.txt"
res = csr.exec("show ver").wait()
cxd.upload_to_cxd("6xxxxxxxx", destination_file_name="exec-output.txt", data=res.result.data)

A Pipe is also implemented:

# Pipe data into upload_to_cxd
res = csr.exec("show ver").wait()
res.result.data | upload_to_cxd("6xxxxxxxx", "exec-output.txt")

exec() and upload result to CXD

Using exec (see Command execution), the user can pass an upload_to parameter, which is an UploadParameters object of the type returned by cxd (see above).

The user can execute one or multiple commands on one or more devices. The outputs from each device are always uploaded to CXD separately as <device-name>_<destination-file-name>.

# Execute a single command and redirect command output to CXD
>>> upload = csr1.exec("show run", upload_to=cxd("6xxxxxxxxx", "running_config.txt"))

>>> upload
[SUCCESS] <radkit_client.sync.request.TransformedFillerRequest object at 0x105a4db80>
...

Secure-Copy (SCP) to CXD

For devices that support SCP, RADKit Client allows the user to request to copy files from the device directly to a CXD target. This SCP operation is proxied by the RADKit Service, and the data does not go through the Client at all.

Similar to exec(), this can be used with one device or multiple devices. Here is an example of using SCP to copy the file debug.log from the device bootflash: file system to TAC SR 6xxxxxxxx as an attachment with the name <device-name>_failure_debug.log:

>>> csr1.scp_to_destination("bootflash:debug.log", cxd("6xxxxxxxx", "failure_debug.log"))

>>> _
[SUCCESS] <radkit_client.sync.request.FillerRequest object {status='SUCCESS'} at 0x105d696a0>
...

Offline Tokens

CXD supports offline tokens, which are tokens that are passed directly to the CXD client object. This is beneficial for users who want to use CXD but cannot retrieve a CXD Upload Token for any reason and a token was provided to them out of band.

Note that CXD upload tokens are designed to be shared if needed, as they are limited only to upload and no data can be retrieved using them.

To use an offline token, the add_target_from_upload_token() method has to be called to create a target and associate it with the token.

Examples:

# First register the target, using the token.
cxd.add_target_from_upload_token("6xxxxxxxx", "mytoken")

# After that, this token will be used whenever we address the above target.
# Some examples:
cxd.upload_to_cxd("6xxxxxxxx", "myfile.txt")
service.inventory['device'].exec("show ver", upload_to=cxd("6xxxxxxxx", "show_ver.txt"))
service.inventory['device'].exec("show ver").wait().result.text | upload_to_cxd("6xxxxxxxx", "show_ver.txt")