Send a Tweet Directly from a VMware ESXi Host

For my VMworld 2016 breakout sessions this year, I wanted to demonstrate new functionality that was added to Auto Deploy.  After exploring a few ideas, I settled on leveraging the new Script Bundle feature to send a post-boot tweet directly from stateless ESXi hosts.  I figured sending a tweet would be an effective way to highlight the ability to integrate with arbitrary REST-based services. Interestingly, I ran into someone recently who was part of a DevOps team that used a private Twitter account for posting various alerts for the group to see – so it’s not as far-fetched as it seems!

I heard you like tweeting about vSphere.

Below is a Python script that can send a tweet directly from the console of a VMware ESXi 6.0 host.  vCenter Server 6.5 with Auto Deploy supports multiple versions of ESXi, and I chose to use 6.0 here.  Note that ESXi 6.5 includes Python 3, so this script would need some modification to work with that release.  I got a head start on the functionality by taking some ideas from Chris Wood.

In order to authenticate with Twitter, it is first necessary to visit the Twitter App Management portal to generate a consumer key and access token.  Plug them into the script accordingly.

The script accepts one argument: a string, wrapped in quotes, that will be posted to your Twitter timeline.

./ “Sent from an ESXi host”

The demo I ran at the INF8920 breakout session was slightly different because scripts cannot accept arguments in that case. Hopefully the recording will eventually be posted on the VMworld site, but the fate is unclear at the moment.

#!/usr/bin/env python

# Send a tweet from ESXi 6.0
# Eric Gray  -- Inspired by Chris Wood

import base64
import urllib, urllib2
import hashlib
import random
import time, os, sys

if len(sys.argv) != 2:
    print "Pass this script a string (wrapped in quotes) to tweet."

# Twitter credentials
consumer_key = ""
consumer_secret = "hcDZ...i9"
access_token = "7833...Fq"
token_secret = "G2c1...jmv"

status = sys.argv[1]
method = "POST"
url = ""

parameters = {
    "oauth_consumer_key": consumer_key,
    "oauth_nonce": hashlib.sha1(str(random.random())).hexdigest(),
    "oauth_signature_method": "HMAC-SHA1",
    "oauth_timestamp": str(int(time.time())),
    "oauth_token": access_token,
    "oauth_version": "1.0",
    "status": status

# Build the string that forms the base of the signature
base_string = "%s&%s&%s" % (method, urllib.quote(url, ""),
                            urllib.quote('&'.join(sorted("%s=%s" % (key, value)
                                                         for key, value in
                                                         parameters.iteritems())), ""))

# because ESXi does not have the hmac Python module...
trans_5C = "".join([chr(x ^ 0x5C) for x in xrange(256)])
trans_36 = "".join([chr(x ^ 0x36) for x in xrange(256)])
outer = hashlib.sha1()
inner = hashlib.sha1()
KEY = "%s&%s" % (urllib.quote(consumer_secret, ""), urllib.quote(token_secret, ""))
KEY = hashlib.sha1(KEY).digest()
KEY = KEY + chr(0) * (inner.block_size - len(KEY))

parameters['oauth_signature'] = base64.b64encode(outer.digest().rstrip('\n'))
auth_header = 'OAuth %s' % ', '.join(sorted('%s="%s"' % (urllib.quote(key, ""),
                                                         urllib.quote(value, ""))
                                            for key, value in parameters.iteritems() if key != 'status'))

body = "status=%s" % status

twitter_request = urllib2.Request(url, body)
twitter_request.add_header("Authorization", auth_header)
twitter_request.add_header('Content-Type', 'application/x-www-form-urlencoded')

For more information on the Script Bundle feature, check out William Lam’s recent post on the topic.

(Visited 3,453 times, 1 visits today)
This entry was posted in Virtualizationism and tagged , . Bookmark the permalink.