Geaux Virtual

Helping virtualize the datacenter…

Automatically add ESX(i) to vCenter from ESX(i)

with 3 comments

I have to say, I love my job.  Since starting at the end of May, I have had the opportunity to work with some great people and tackle tasks that I have been wanting to complete yet never had the time to do at previous employers.  Specifically, I am talking about automating ESX(i) deployments.  I have performed many scripted installs before (in fact I had not done a full load of ESX for over 3 years and only recently did so because CNA drivers were not in the ISO), but now I am in the situation where build after build must be exactly the same no matter who is performing the builds.  With that, our team started looking at the ESX Deployment Appliance (great appliance BTW), but I quickly noticed some lacking features which I quickly added to fit our current needs.  (Keep your eyes out for announcement in the near future on a collaboration myself and @lynxbat will put together regarding a deployment appliance).

With the work I’ve been doing lately, I asked myself the question: why couldn’t an ESX(i) host add itself to vCenter?  The easiest answer to this question is that VMware has not written a program or script to perform this task.  But is their a technical reason why this would not be possible?

In order to perform any type of action on vCenter, API access is required.  There are two ways to access the vCenter APIs: MOB and Web Services API.  The MOB, or Managed Object Browser, is a web site that allows retrieving and setting values for vCenter.  Traversing the MOB is not easy and requires frequent trips to the vSphere API documentation for assistance.  The Web Services API is a web service that can be used to retrieve and set values via a SOAP client.  VMware even provides SDKs for Java and Perl.

Do we have an SDK available on ESX(i)? No.  This means we must see if we can access the MOB or Web Services API from ESX(i) by writing a script that does not rely on an SDK.  Looking through an ESXi host, I noticed python was on the host.  Why is python on the host?  The MOB is written in python.  There is no SOAP client libs loaded for python on ESX(i)(if there are, please post a comment), and this solution should not require loading of additional libraries to ESX(i).  With that I set out and wrote a script that will connect an ESX(i) host to vCenter.

***DISCLAIMER***

Use at your own risk.  I provide this script as an academic example of how to do this.  I am not responsible if it does havoc on your environment.  This script has only been tested with vSphere 4.1 ESXi and vCenter.  ESX 4.1, ESX 4.0, and vCenter 4.0  have not been tested.

***DISCLAIMER***

First we must import the libraries we need.

import re,os,urllib,urllib2

Next, let’s set some variables that will be needed.  This is where it starts to get interesting.  <CLUSTER> below needs to be replaced with the cluster the host will be added to. For this exercise, this is a static assignment. This name will be in the form of domain-c21 or something similar and can be found in the MOB.

url = "https://vcenteraddress/mob/?moid=<CLUSTER>&method=addHost"
username = "vcenterusername"
password = "vcenterpassword"

This section configures the authentication for when we connect to the MOB.

passman = urllib2.HTTPPasswordMgrWithDefaultRealm()
passman.add_password(None,url,username,password)
authhandler = urllib2.HTTPBasicAuthHandler(passman)
opener = urllib2.build_opener(authhandler)
urllib2.install_opener(opener)

This next section computes the SHA1 hash for the host and strips out all unnecessary characters.  As you can tell, my regex skills are a bit rusty, and this probably could be cleaned up.

cmd = "openssl x509 -sha1 -in /etc/vmware/ssl/rui.crt -noout -fingerprint"
tmp = os.popen(cmd)
tmp_sha1 = tmp.readline()
tmp.close()
s1 = re.split('=',tmp_sha1)
s2 = s1[1]
s3 = re.split('\n', s2)
sha1 = s3[0]

This next section creates the ConnectHostSpec information that needs to be passed to the addHost method.

xml = """<spec xsi:type="HostConnectSpec">
<hostName>192.168.188.130</hostName>
<sslThumbprint>%s</sslThumbprint>
<userName>root</userName>
<password>rootpassword</password>
<force>1</force>
</spec>"""
xml = xml.replace("%s",sha1)

Once the ConnectHostSpec is created, we can now encode the parameters that must be sent with the POST to the addHost method.  As you can see, besides the ConnectHostSpec, we must also pass values for asConnected, resoursePool, and license.  Only spec and asConnected require a value.  After the values are encoded, a request can be created and the data sent to the URL.

params = {'spec':xml,'asConnected':'1','resourcePool':'','license':''}
e_params = urllib.urlencode(params)
req = urllib2.Request(url,e_params)
page = urllib2.urlopen(req).read()

And that’s it. This small script will take the parameters needed to add an ESX(i) host to vCenter through the MOB and complete this task from the host itself.  I am currently testing integrating this script with scripted installs.  Stay tuned as I am already getting more ideas for this script.

Written by jguidroz

July 25, 2010 at 3:57 pm

Posted in Scripting, VMware

3 Responses

Subscribe to comments with RSS.

  1. Nice script, though the problem is you still need to hard code these values such as the credentials to both vCenter & host to actually join the host to vCenter. The next problem is that you either have to leave a default cluster or keep updating the cluster MOID value for different cluster and again this can be tedious as you have more clusters.

    I think the most ideal solution for this is to basically have your host, whether this is ESX or ESXi to ping back a system with a fully functional SDK environment. This environment can be Windows or Linux, take your pick and based on a configuration file, you can join your host to vCenter. Not only does this not require any additional logic to run on the host installation, you can change things on the fly including additional post configurations that just can not be performed directly on a host.

    Check out Maish’s 4 part series using this setup that has a client/server model using python script that I had reference him. What happens after the build is the ESXi host will ping back a Windows box that has a python script listening for incoming requests and then can process the host and join it to vCenter and perform any other post configurations that may needed.

    http://technodrone.blogspot.com/2010/04/esxi-deployment-solution-beginning.html
    http://technodrone.blogspot.com/2010/04/esxi-deployment-solution-part-2.html
    http://technodrone.blogspot.com/2010/04/esxi-deployment-solution-part-3.html
    http://technodrone.blogspot.com/2010/05/esxi-deployment-solution-part-4.html

    –William

    William Lam

    July 25, 2010 at 6:27 pm

    • Thanks for the comment. You are correct, editing a script of this nature could be tedious if doing it by hand, especially with looking up the MOID values. My end goal is combine this with a deployment appliance that will populate all values when the KS is dynamically created for each host. The cluster name can be provided for each host, and the appliance will handle grabbing the correct MOID to place the cluster in. Sure there are other ways to handle this, and you provided a great example. This is an example that if you want to write against the API, you can configure anything on the ESX host. For what I want, I am looking for one script that is run and that provides full configuration of an ESX(i) and finishes with adding to vCenter. The script will also validate that the settings were set correctly. It may be easier using an already written SDK, but this is just another option.

      jguidroz

      July 26, 2010 at 8:04 pm

  2. Looks great, thanks for the information.

    Will try this in my lab. Any reasons why this should not work with vSphere4 ESX(i) and vCenter.

    Chris Leygraf

    July 27, 2010 at 5:11 am


Leave a reply to William Lam Cancel reply