VMware Cloud Community
franckehret
Enthusiast
Enthusiast
Jump to solution

kickstart & python script issue

Dear all,

After some work I was able to put together an automated ESXi deployment with WDS (in my lab, all nested VMs).

After pure "deployment", I wanted to add automatically the hosts to a lab vCenter. So I use the excellent script that can be found here.

This script join all hosts to my vcenter successfully but it adds them with the IP address, which is expected.

But I don't like that and I would like to add the hosts with their DNS name as William Lam did here previously.

So I added the part in bold, but it doesn't work... And worst : I don't know where to find the logs nor tell if the syntax is ok.

Can you give me some help please ? Thanks in advance Smiley Wink

The script :

import sys,re,os,urllib,base64,syslog,socket

import urllib.request as request

import ssl

# used for unverified SSL/TLS certs. Insecure, not good for public.

ssl._create_default_https_context = ssl._create_unverified_context

## Variables that need to be filled out for different environments ##

# URL of vcenter, just the IP address

vcenter = "vcenterfqdn"

# Data center

#cluster = "<datacenter>/host/<cluster>"

cluster = "DatacenterName/host/ClusterName"

# vCenter credentials

user = "account"

password = "password"

# host ESXi credentials

host_username = "root"

host_password = "password"

url = "https://" + vcenter + "/mob/?moid=SearchIndex&method=findByInventoryPath"

passman = request.HTTPPasswordMgrWithDefaultRealm()

passman.add_password(None,url, user, password)

authhandler = request.HTTPBasicAuthHandler(passman)

opener = request.build_opener(authhandler)

request.install_opener(opener)

#cont = ssl._create_unverified_context()

#ssl._create_default_https_context = ssl._create_unverified_context()

req = request.Request(url)

#cont = ssl._create_unverified_context()

#page = request.urlopen(req, context=context)

page = request.urlopen(req)

page_content = page.read().decode('utf-8')

#print(page_content)

reg = re.compile('name="vmware-session-nonce" type="hidden" value="?([^\s^"]+)"')

nonce = reg.search(page_content).group(1)

headers = page.info()

cookie = headers.get("Set-Cookie")

params = {'vmware-session-nonce':nonce,'inventoryPath':cluster}

e_params = urllib.parse.urlencode(params)

#print(e_params)

bin_data = e_params.encode('utf8')

req = request.Request(url, bin_data, headers={"Cookie":cookie})

page = request.urlopen(req)

page_content = page.read().decode('utf-8')

#print(page_content)

clusterMoRef = re.search('domain-c[0-9]*',page_content)

if clusterMoRef:

print("Found cluster: " + cluster)

else:

opener.close()

sys.exit(1)

# cert stuff

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]

if sha1:

print("Hash: ", sha1)

else:

opener.close()

sys.exit(1)

xml = '<spec xsi:type="HostConnectSpec"><hostName>%hostname</hostName><sslThumbprint>%sha</sslThumbprint><userName>%user</userName><password>%pass</password><force>1</force></spec>'

# Code to extract IP Address to perform DNS lookup to add FQDN to vCenter

hostip = socket.gethostbyname(socket.gethostname())

if hostip:

print("IP address of host: ", hostip.strip())

else:

opener.close()

sys.exit(1)

try:

        host = socket.getnameinfo((hostip, 0), 0)[0]

except IOError, e:

        print("Failed to perform DNS lookup for " + hostip.strip())

        sys.exit(1)

else:

        print("Successfully performed DNS lookup for " + hostip.strip() + ' is ' + host)

sys.exit(0)

# could add logic to do DNS lookup, but no dns in our environment.

xml = xml.replace("%hostname",host)

xml = xml.replace("%sha",sha1)

xml = xml.replace("%user",host_username)

xml = xml.replace("%pass",host_password)

print(xml)

# now join to vcenter cluster

try:

url = "https://" + vcenter + "/mob/?moid=" + clusterMoRef.group() + "&method=addHost"

params = {'vmware-session-nonce':nonce,'spec':xml,'asConnected':'1','resourcePool':'','license':''}

e_params = urllib.parse.urlencode(params)

bin_data = e_params.encode('utf8')

req = request.Request(url, bin_data, headers={"Cookie":cookie})

page = request.urlopen(req).read()

except IOError as e:

opener.close()

print("Couldn't join cluster", e)

sys.exit(1)

else:

print("Joined vcenter cluster!")

url = "https://" + vcenter + "/mob/?moid=SessionManager&method=logout"

params = {'vmware-session-nonce':nonce}

e_params = urllib.parse.urlencode(params)

bin_data = e_params.encode('utf8')

req = request.Request(url, bin_data, headers={"Cookie":cookie})

page = request.urlopen(req).read()

sys.exit(0)

Reply
0 Kudos
1 Solution

Accepted Solutions
franckehret
Enthusiast
Enthusiast
Jump to solution

Took me a while to test it directly on the host, I had penty of other projects the last year and I forgot a little about this.

I had a "typo" in the line :

xml = xml.replace("%hostname",hostip)

Should have been :

xml = xml.replace("%hostname",host)

Thanks to all that participated helping me finding the solution.

I hope it can server others 😉

View solution in original post

Reply
0 Kudos
5 Replies
franckehret
Enthusiast
Enthusiast
Jump to solution

No one ? Smiley Wink

lamw​ ? (Sorry to bother, but you are the only one I can think about - no one answered depsite several "ups"...)

Reply
0 Kudos
BaijuParambil
Contributor
Contributor
Jump to solution

franckehret

Replace below section in your script :

if hostip:

print("IP address of host: ", hostip.strip())

else:

opener.close()

sys.exit(1)

try:

        host = socket.getnameinfo((hostip, 0), 0)[0]

except IOError, e:

        print("Failed to perform DNS lookup for " + hostip.strip())

        sys.exit(1)

else:

        print("Successfully performed DNS lookup for " + hostip.strip() + ' is ' + host)

sys.exit(0)

With :

if hostip:

    print("Successfully extracted IP Address - %s" % hostip.strip())

else:

    opener.close()

    print("Failed to extract IP Address!")

    sys.exit(1)

try:

    host = socket.getnameinfo((hostip, 0), 0)[0]

    print("Successfully performed DNS lookup - %s" % host)

except IOError:

    print("Failed to perform DNS lookup for %s, host will be added to vCenter using IP Address" % hostipt.strip())

    host = hostip

If you don't want to add Host with IP Address in case DNS lookup fails, replace the line 12 in above block "host = hostip" with sys.exit(1)

Hope it helps..

Thanks

Reply
0 Kudos
franckehret
Enthusiast
Enthusiast
Jump to solution

Hi BaijuParambil

Thanks a lot for your answer, I've just tried but no luck, the host is still added with the IP despite the code change.

If I login on host, Hostname, DNS suffix and DNS servers IPs are all OK.

What is strange, I stared at screen and no error/informational message came up during the script.

Any idea how to troubleshoot it ? Smiley Wink

Reply
0 Kudos
BaijuParambil
Contributor
Contributor
Jump to solution

Can you try to execute the script manually on a host and check the DNS lookup in the result, sample screenshot below using the same script :

addhost.jpg

franckehret
Enthusiast
Enthusiast
Jump to solution

Took me a while to test it directly on the host, I had penty of other projects the last year and I forgot a little about this.

I had a "typo" in the line :

xml = xml.replace("%hostname",hostip)

Should have been :

xml = xml.replace("%hostname",host)

Thanks to all that participated helping me finding the solution.

I hope it can server others 😉

Reply
0 Kudos