Reporting using the Cohesity ReST API

I mentioned the Cohesity REST API when I looked at the developer portal, now I’d like to show you a little about how to access that API and gather information from your Cohesity clusters. For my example I am going to do some very basic work directly with the API using Python. There are language bindings for Python and PowerShell that make accessing the API simpler, but direct access to the API is also worth illustrating. I chose a couple of basic tasks: reporting on capacity reporting and VMs that are not protected. Below I show how I accessed data via the API, I also posted a video of the same process if you prefer to watch.

Disclosure: This post is part of my work with Cohesity.

Setup

Before I could start making ReST requests with Python, I needed to install the Requests library using the Python package manager, pip from the command line on my Mac.

sudo pip install requests

At the top of my python script I needed to import the requests and json libraries and declare the IP address of the cluster that I want to access.

import requests

import json

ClusterIP = “192.168.20.22”

Authentication

Most of the methods in the Cohesity API require authentication using an access token, so the first step is to request that token and setup a variable to pass this token in subsequent request headers.

requestURI = ‘https://’ + ClusterIP + ‘/irisservices/api/v1/public/accessTokens’

tokenresponse = requests.post(requestURI, data=”{ \”domain\”: \”local\”, \”password\”: \”admin\”, \”username\”: \”admin\”}”, verify=False)

token = (tokenresponse.json()[“accessToken”]).encode(“ascii”)

headers = {‘Authorization’ : ‘Bearer ‘ + token }

The first line pops the cluster IP address into the request URI, the second line then posts the request with the default local username and password. It would be a lot better to prompt for credentials or store them separately, but the defaults are easy to show here. The third line extracts the text of the accessToken field into a variable and the final line creates the authorization header text to use in subsequent requests. Here’s the resulting variable:

>>> headers

{‘Authorization’: ‘Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdXRoLXR5cGUiOiIxIiwiZG9tYWluIjoiTE9DQUwiLCJleHBpcmF0aW9uLXRpbWUiOiIxNTY5ODg4MDEzIiwiaW4tY2x1c3RlciI6dHJ1ZSwibG9jYWxlIjoiZW4tdXMiLCJyb2xlcyI6IkNPSEVTSVRZX0FETUlOIiwic2lkcy1oYXNoIjoiV25MUVVybDlyamNvY0F3bWNXWWRhOFMyc09udnZpcmtlNVZzMnNKRFlkNCIsInVzZXItc2lkIjoiUy0xLTEwMC0yMS0zODEwMDQyMy01NDk4ODE5Mi0xIiwidXNlcm5hbWUiOiJhZG1pbiJ9.VVnHAwmBsu_IQYi8ptbMOSH8fMW1wrTd0Ex2NbL0URCLvBVBoaFq8ALkTCnd6ECqDorPlpU3Wz20QHsZ-DsXhMSDj4Z0DQAOuEAMuVbKmPx5sdfMEaSeiqCaHMs2tHVias9D_nXz6Ewf2gYcs8u7b2wvCkKI1JbaPA1diFOGC15CJaVpxomN400QVALzmy0m40OXYCOvfHehaCRZ7dwa0pkG8PKJYlPYEVm8dBukDWHWBWDpHSrQoWrAekJzCh5hMml_7MmI1WHR77hVp_gtxCdJ_3kCiPT-NbVNmuXEQl9uAmaDTWBxhQR0O-4AFbBQspn17EoPwvXbT4vQr_CQZw’}

The access token is valid for 24 hours, so we can use it while this script runs.

Free Capacity

The first thing I want to do is query the amount of free capacity on my Cohesity cluster and trigger a warning if there is less than 15% free space on the cluster. The simplest way to get this is with the Stats method to get storage statistics:

requestURI = ‘https://’ + ClusterIP + ‘/irisservices/api/v1/public/stats/storage’

response = requests.get(requestURI, verify=False, headers=headers)

From there I could extract the total storage capacity and usage, then compute the utilization percentage and choose whether to report a healthy or warning state.

CapacityB = float((response.json()[“totalCapacityBytes”]))

UsedB = float((response.json()[“localUsageBytes”]))

Utilization = int((UsedB/CapacityB)*100)

if (Utilization < 85):

print(‘Storage utilization OK at ‘ + str(Utilization) + ‘%’)

else:

print(‘ ** Warning **’)

print(‘Storage utilization excessive at ‘ + str(Utilization) + ‘%’)

In my case, my cluster is 83% utilized, not quite at my warning threshold but getting close.

Unprotected VMs

The next example is a little more involved, I want to identify the VMs that are in my vSphere inventory but are not protected by any jobs. The first task is to identify every VM that is protected and put their VM names into an array. The protectionSources method will list all of the protection jobs for all sources, or in my case all vSphere sources.

requestURI = ‘https://’ + ClusterIP + ‘/irisservices/api/v1/public/protectionJobs?environments=kVMware’

sourceResponse = requests.get(requestURI, verify=False, headers=headers)

A couple of loops, the first cycles through all the protection jobs and the second cycles through all of the VM IDs covered in the protection job. For each VM ID, I then needed to request the details of that ID and add the VM’s name to an array of protected VM names.

ProtectedVMs = []

for job in sourceResponse.json():

for id in job[“sourceIds”]:

requestURI = ‘https://’ + ClusterIP + ‘/irisservices/api/v1/public/protectionSources/objects/’ + str(id)

VMresponse = requests.get(requestURI, verify=False, headers=headers)

ProtectedVMs.append(VMresponse.json()[“name”].encode(“ascii”))

Now that I have a list of the VMs that are protected by my Cohesity cluster, I now need to get a list of all the VMs that Cohesity sees on my vSphere cluster.

requestURI = ‘https://’ + ClusterIP + ‘/irisservices/api/v1/public/protectionSources/virtualMachines’

response = requests.get(requestURI, verify=False, headers=headers)

Finally, I need to cycle through the list of VMs and add the ones that are not in the protected list to the unprotected list, unless they are in the list of VMs that I don’t ever want protected. One example is the Cohesity Virtual Edition VM itself.

UnProtectedVMs = []

UnProtectableVMs = [‘Cohesity’, ‘T1’]

for vm in response.json():

vmname = vm[“name”].encode(“ascii”)

if not ((vmname in ProtectedVMs) or (vmname in UnProtectableVMs)):

UnProtectedVMs.append(vmname)

The Cohesity ReST API is fairly easy to work with, there are certainly a lot of different endpoints covering every aspect of your Cohesity cluster. It did take me a little while to work out the right way to use the access token and working with nested arrays of data in the returns is sometimes surprisingly easy and sometimes just as surprisingly difficult. There is definitely an easier road to automation using pre-built integrations such as the PowerShell module and the Python SDK however directly manipulating the API allows the most complete access.

© 2019, Alastair. All rights reserved.

About Alastair

I am a professional geek, working in IT Infrastructure. Mostly I help to communicate and educate around the use of current technology and the direction of future technologies.
This entry was posted in General. Bookmark the permalink.