Skip to content
Snippets Groups Projects
createNode 5.5 KiB
Newer Older
#!/usr/bin/env python
import sys, os, string, subprocess, socket, ansible.runner, re
import copy, shlex,uuid, random, multiprocessing, time, shutil
import novaclient.v1_1.client as nvclient
import novaclient.exceptions as nvexceptions
import glanceclient.v2.client as glclient
import keystoneclient.v2_0.client as ksclient

class Authenticate:
	
	def __init__(self, username, passwd):
		self.username=username
		self.passwd=passwd
		self.tenantName= os.environ['OS_TENANT_NAME']
		self.authUrl="https://keystone.rc.nectar.org.au:5000/v2.0"
		kc = ksclient.Client(   auth_url=self.authUrl,
					username=self.username,
					password=self.passwd)
		self.tenantList=kc.tenants.list()
		self.novaSemaphore = multiprocessing.BoundedSemaphore(value=1)
	
	def createNovaObject(self,tenantName):
		for tenant in self.tenantList:
			if tenant.name == tenantName:
				try:
					nc = nvclient.Client(	auth_url=self.authUrl,
						username=self.username,
						api_key=self.passwd,
						project_id=tenant.name,
						tenant_id=tenant.id,
						service_type="compute"
						)
					return nc
				except nvexceptions.ClientException:
					raise
	
	def gatherInfo(self):

		for tenant in self.tenantList: print tenant.name
		tenantName = raw_input("Please select a project: (Default MCC-On-R@CMON):")
		if not tenantName or tenantName not in [tenant.name for tenant in self.tenantList]: 
			tenantName = "MCC_On_R@CMON"
		print tenantName,"selected\n"
		
		## Fetch the Nova Object

		nc = self.createNovaObject(tenantName)
		
		## Get the Flavor
		flavorList = nc.flavors.list()
		for flavor in flavorList: print flavor.name
		flavorName = raw_input("Please select a Flavor Name: (Default m1.xxlarge):")
		if not flavorName or flavorName not in [flavor.name for flavor in flavorList]:
			flavorName = "m1.xxlarge"
		print flavorName,"selected\n"

		
		## Get the Availability Zones
		az_p1 = subprocess.Popen(shlex.split\
		("nova availability-zone-list"),stdout=subprocess.PIPE)
		az_p2 = subprocess.Popen(shlex.split\
		("""awk '{if ($2 && $2 != "Name")print $2}'"""),\
		stdin=az_p1.stdout,stdout=subprocess.PIPE)
		availabilityZonesList =  subprocess.Popen(shlex.split\
		("sort"),stdin=az_p2.stdout,stdout=subprocess.PIPE).communicate()[0]
		print  availabilityZonesList
		availabilityZone = raw_input("Please select an availability zone: (Default monash-01):")
		if not availabilityZone or \
		availabilityZone not in [ zone for zone in availabilityZonesList.split()]:
			availabilityZone = "monash-01"
		print availabilityZone,"selected\n"
		
		## Get the number of instances to spawn
		numberOfInstances = raw_input\
		("Please specify the number of instances to launch: (Default 1):")
		if not numberOfInstances or \
		not isinstance(int(numberOfInstances), int):
			numberOfInstances = 1
		subprocess.call(['clear'])
		flavorObj = nc.flavors.find(name=flavorName)
		print "Creating",numberOfInstances,\
		"instance(s) in",availabilityZone,"zone..."
		instanceList = []
		for counter in range(0,int(numberOfInstances)):
			nodeName = "MCC-Node"+str(random.randrange(1,1000))
			try:
				novaInstance =  nc.servers.create\
				(name=nodeName,image="ddc13ccd-483c-4f5d-a5fb-4b968aaf385b",\
				flavor=flavorObj,key_name="shahaan",\
				availability_zone=availabilityZone)
				instanceList.append(novaInstance)
			except nvexceptions.ClientException:
				raise
				continue
				
		while 'BUILD' in [novaInstance.status \
		for novaInstance in instanceList]:
			for count in range(0,len(instanceList)):
				time.sleep(5)
				if instanceList[count].status != 'BUILD': 
					continue
				else:
					try:
						instanceList[count] = nc.servers.get(instanceList[count].id)
					except nvexceptions.ClientException or \
					nvexceptions.ConnectionRefused or \
					nvexceptions.InstanceInErrorState:
						raise
						del instanceList[count]
						continue
		activeHostsList = []
		SSHports = []
		for novaInstance in instanceList:
			if novaInstance.status == 'ACTIVE':
				hostname = socket.gethostbyaddr(novaInstance.networks.values()[0][0])[0]
				activeHostsList.append(hostname)
				SSHDict = {}
				SSHDict['IP'] = novaInstance.networks.values()[0][0]
				SSHDict['status'] = 'CLOSED'
				SSHports.append(SSHDict) 
		print "Scanning if port 22 is open..."
		sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
		while 'CLOSED' in [host['status'] for host in SSHports]:
			for instance in range(0,len(SSHports)):
				sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
				if SSHports[instance]['status'] == 'CLOSED' and not sock.connect_ex((SSHports[instance]['IP'], 22)):
					SSHports[instance]['status'] = 'OPEN'
					print "Port 22, opened for IP:",SSHports[instance]['IP']
				else:
					time.sleep(5)
				sock.close()
				
		fr = open('/etc/ansible/hosts.rpmsave','r+')
		fw = open('hosts.temp','w+')
		lines = fr.readlines()
		for line in lines:
			fw.write(line)
			if re.search('\[new-servers\]',line):
				for host in activeHostsList: fw.write(host+'\n')
		fr.close()
		fw.close()
		shutil.move('hosts.temp','/etc/ansible/hosts')
		print "Building the Nodes now..."
		subprocess.call(shlex.split("/mnt/nectar-nfs/root/swStack/ansible/bin/ansible-playbook /mnt/nectar-nfs/root/ansible-config-root/mcc-nectar-dev/buildNew.yml -v"))	

if __name__ == "__main__":
	username = os.environ['OS_USERNAME']
	passwd = os.environ['OS_PASSWORD']
	choice = raw_input(username + " ? (y/n):")
	while choice and choice not in ("n","y"):
		print "y or n please"
		choice = raw_input()
	if choice == "n":
		username = raw_input("username :")
		passwd = raw_input("password :")
	auth = Authenticate(username, passwd)
	auth.gatherInfo()