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
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)
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 😉
No one ?
lamw ? (Sorry to bother, but you are the only one I can think about - no one answered depsite several "ups"...)
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
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 ?
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 :
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 😉