vRealize Operations REST APIs for ESXi-ARM GPIO CPU Temp

vRealize Operations REST APIs for ESXi-ARM GPIO CPU Temp


As an IOT device, I've been thinking of possible data collection scenarios for the Raspberry Pi 4 running ESXi-ARM. My first proof of concept was to collect hygrometer data and send to vRealize Log Insight. You can watch that VLOG post here. The super geniuses on the vExpert Slack channel responded with "That's nice, but can you do vRealize Operations?" 

I'm always up for "sharpening the saw", so I looked into how to do this. Most of the skills required I did not have (REST, Postman, Python JSON), so this was a very thorough self-education experience for me. William Lam, VMware, pointed me to this tutorial on vRealize Operations REST which was very helpful. The examples in that tutorial are images not text, so no copy/paste. For copy/paste examples, refer to the vRealize Operations REST API Documentation (https://[VROPS FQDN]/suite-api/docs/rest/index.html). Each call has example text that can be used. For example, here is the "POST /api/resources/{id}/properties" example code:

  "property-content" : [ {
    "statKey" : "system|availability",
    "timestamps" : [ 1119844280663, 1119844280693, 1119844280713 ],
    "values" : [ "UP", "UP", "DOWN" ],
    "others" : [ ],
    "otherAttributes" : { }
  }, {
    "statKey" : "config|num|processes",
    "timestamps" : [ 1119844280663, 1119844280693, 1119844280713, 1119844280718 ],
    "data" : [ 93.0, 95.0, 97.0, 99.0 ],
    "others" : [ ],
    "otherAttributes" : { }
  } ]


Parts List

What was needed to pull the CPU Temperature from a Raspberry Pi 4 running ESXi-ARM and send that data to vRealize Operations?

  • Raspberry Pi 4
  • ESXi-ARM Fling
  • Tom Hebel's ESXi-ARM GPIO VIB 
  • Tom Hebel's ESXi-ARM GPIO Python library and sample code
  • VMware vRealize Operations REST API Tutorial
  • Postman for REST API Testing
  • vRealize Operations (vROps)

Part I - Postman REST API Testing

Authenticate to vROps and Get a Token

I used Postman to build successful vROPs REST API queries and then saved those queries as Python code for automation. I will go through the Postman steps and then the Python steps.

The first step is to use the REST API use gain access to your vROps server with an authentication token. In Postman, create a new POST request to https://{{vrops}}/suite-api/api/auth/token/acquire after defining the {{vrops}} variable to your vROps FQDN.

Note: You can find all these Postman queries on my GitHub repo here.

Add these two values in the Headers section:
  1. Content-Type: application/json
  2. Accept: application/json

Use this JSON for the Body section (After defining the vROps {{user}} and {{password}} variables as you did for the {{vrops}} variable)

"username" : "{{user}}",
"password" : "{{password}}"

Click "Send" and you should see something like this in Body section below including the "token": variable:

Authentication tokens are good for 6 hours. You can now save this token into a {{token}} variable for use in other Postman queries. 

Find the ID of your Raspberry Pi 4 in VROps

Now that we have an authentication token to use for the next six hours, we need the vROps ID for our Raspberry Pi 4 to add Custom Properties to.

In Postman, create a GET query to https://{{vrops}}/suite-api/api/resources?adapterKind=VMWARE&resourceKind=HostSystem&name={{rpi4}} 

Create your own {{rpi4}} variable that holds the FQDN of your ESXi-ARM Raspberry Pi 4 host.

Use these three values in the Headers section. If you create this new GET query by copying the previous POST query, the Headers section will already be filled in except for the Authorization value.

  1. Content-Type: application/json
  2. Authorization: vRealizeOpsToken {{token}}
  3. Accept: application/json

When you hit Send, you will get a few pages of JSON returned including the status of the vROps badges for your host. The last line of text in the JSON is the identifier for your host. The last few lines of my JSON look like this:

"href": "/suite-api/api/credentials/",
"rel": "RELATED",
"name": "credentialsOfResource"
"identifier": "85965d5f-de89-4f79-9131-8552d007d0a7"

We will use the host identifier value to send Custom Properties to the host in vROps.

Send Custom Properties Metrics to vROps

We now have everything we need to add metrics to a Custom Property for our ESXi-ARM host. Once all this is working, we will use the Tom Hebel Python code to pull the CPU Temp from the Raspberry Pi and send to vROps. In this Postman test, we will use dummy temperatures.

In Postman, create a POST query to https://{{vrops}}/suite-api/api/resources/{{hostid}}/properties. Create the new variable {{hostid}} that holds the Host ID that we discovered in the last step (85965d5f-de89-4f79-9131-8552d007d0a7).

Also, retain the Headers from the last step:

In the Pre-request Script tab, enter this text which will supply the date and time of the metric that we will push to vROPs

var epoch = (new Date).getTime();
postman.setEnvironmentVariable("epoch", epoch);
postman.setEnvironmentVariable("objectID", "{{hostid}}");

In the Body tab, enter this JSON. The "data" field is the value that we will push to CustomProps|CPUTemp for our Raspberry Pi 4 in VROps

"property-content" : [
"statKey" : "CustomProps|CPUTemp",
"timestamps" : [ {{epoch}} ],
"data" : [ 40 ],
"others" : [ ],
"otherAttributes" : { }

When you click "Send" the return body should not include anything except the tiny "Status 200" status to the right.

If you head on over to vROps > Environment > All Objects > vCenter Adapter > Host System > [Host FQDN] > (Select Your Host) > Metrics > All Properties > CustomProps, you will see the CPUTemp property you just created and pushed data to

Double clicking the CPUTemp Property will add a line chart to the pane at the right. You should see your one data point represented in the chart. Drag the timeline sliders below the chart to zoom in on the timeline if you like. You can see the two 40s that I pushed as I was testing Postman while writing this blog post.

Part II - Automating with Python & Cron

Export Your Working REST API Queries to Python

Our goal is to have CPU Temperature sent to vROPs automatically every five minutes. This means we need a script that will run on ESXi every five minutes. Postman will export code from your successful queries in any one of 26 variations. The key is to export code that will run directly on ESXi. You export code versions of your queries by clicking the word Code in the upper right corner of Postman. 

I am most comfortable with bash (being a *NIX user since 1986), so I started there. The Postman bash code export options are httpie and wget. I started with wget as that is supported on ESXi, but the wget version on ESXi does not support the --method option so no sending --method GET nor --method POST commands. Oh, well. On to Python.

I moved on to Python which also runs on ESXi and is not limited in functionality. Python also has native JSON support. I built my Python script vrops_cpu_temp.py one step at a time. First step, I inserted the Python code generated from "DF - Acquire Token" and tested until it worked. 

I then added the code generated from "DF - Post Host Custom Property". Before I could test this added code, I needed to use the Python function int(time.time()) to get the current time in epoch time for the POST. I also needed to insert the acquired token into the JSON to be sent to vROps with a little Python JSON magic. I tested this code until it worked.

The last Python code to add was Tom Hebel's GPIO CPU code. I took the contents of his pimon_util.py, added to my code, and edited to just return the CPU temperature. I then tested this code until it worked.

Amazingly, my new frankencode worked and running it added the current CPU temperature and used the current time for the timestamp.

Add to crontab to Run Every Five Minutes

The crontab in ESXi is not managed like a *NIX system. In a regular *NIX system, you execute "crontab -e", edit your crontab, and save. In ESXi, you make updates to the /etc/rc.local.d/local.sh file which updates /var/spool/crontabs/[user] on boot. Here are the lines I added to local.sh:

#DMF vRealize Operations CPU Temp Metric
echo '*/5 * * * * /vmfs/volumes/1TB_USB_Direct/scripts/vrops_cpu_temp.sh 2>&1' >> /var/spool/cron/crontabs/root

I store anything I want to remain from boot to boot on an external datastore. In this case, I placed a shell script which runs vrops_cpu_temp.py in a "scripts" folder on the external USB datastore "1TB_USB_Direct". The vrops_cpu_temp.sh script looks like this:

cd /vmfs/volumes/1TB_USB_Direct/scripts
date >> ./vrops_cpu_temp.log
python ./vrops_cpu_temp.py >> ./vrops_cpu_temp.log

I rebooted, crontab was updated, and vRealize Operations received new data and a timestamp every five minutes. Yay. Here's the latest graph since I started running this post. The jump is from when I disconnected the fan from my Pi4 case and ran a stress test last night. The fan itself seems to have a 6 degree impact on the Pi4.

Thank You

Thank you for taking the time to read this post. I hope you have found this helpful, educational, and that I may have saved you some time. I welcome your feedback and improvements.