Skip to content
Snippets Groups Projects
dynamicInventory-mcc2 3.21 KiB
#!/usr/bin/env python
import sys, os, string, socket, re
import shlex, multiprocessing, time, shutil, json
from novaclient import client as nvclient
import novaclient.exceptions as nvexceptions
import keystoneclient.v2_0.client as ksclient
from joblib import Parallel, delayed
from multiprocessing import Process, Manager, Pool
from libnmap.process import NmapProcess
from libnmap.parser import NmapParser, NmapParserException

def gatherInfo(tenantName, tenantID, userName, passwd, authUrl, inventory):
	## Fetch the Nova Object
	projectName = os.path.basename(sys.argv[0])
	nc = nvclient.Client(	auth_url=authUrl,
		username=userName,
		api_key=passwd,
		project_id=tenantName,
		tenant_id=tenantID,
		version="2"
		)
	for server in nc.servers.list():
		if server.metadata and \
		'ansible_host_groups' in server.metadata and \
		'project_name' in  server.metadata:
			if server.metadata['project_name'].strip() != projectName.strip(): continue
			unwantedChars = """][")("""
			rgx = re.compile('[%s]' % unwantedChars)
			ansible_groups = rgx.sub('', server.metadata['ansible_host_groups']).split(',')
			hostname = socket.gethostbyaddr(server.networks.values()[0][0])[0]
			novaVolumes = nc.volumes.get_server_volumes(server.id)
			# Let's do some port scanning using nmap
			nmproc = NmapProcess(hostname, "-p 22 -sV -Pn")
			rc = nmproc.run()
			if rc != 0: continue
			parsed = NmapParser.parse(nmproc.stdout)
			# Set Ansible Host Group
			for group in ansible_groups:
				groupName = group.strip()
				if groupName not in inventory: inventory[groupName] = []
				inventory[groupName].append(hostname)
			# Add other metadata
			for key, value in server.metadata.iteritems():
				if key not in ('project_name','ansible_host_groups'):
					inventory['_meta']['hostvars'][hostname] = { key:value }
			if novaVolumes:
				inventory['_meta']['hostvars'][hostname]['volumeList'] = [ volume.id for volume in novaVolumes ]
			inventory['_meta']['hostvars'][hostname]['status']  = parsed.hosts[0].status
		else:
			continue
	#print inventory

if __name__ == "__main__":
	inventory = {}
	inventory['_meta'] = { 'hostvars': {} }
	try:
		authUrl = os.environ['OS_AUTH_URL']
		userName = os.environ['OS_USERNAME']
		passwd = os.environ['OS_PASSWORD']
	except KeyError:
		print "Env Variables not set, Please run: source <openstack rc file>"
		sys.exit()
	kc = ksclient.Client(auth_url=authUrl, username=userName, password=passwd)
	tenancies = kc.tenants.list()
	Parallel(n_jobs=len(tenancies), backend="threading")(delayed(gatherInfo)
	(tenant.name, tenant.id, userName, passwd, authUrl, inventory)
	for tenant in tenancies)
	if not inventory['_meta']['hostvars']:
		print "I could not find any project called ", os.path.basename(sys.argv[0]), "in any of "
		for tenancy in tenancies: print tenancy.name
		print "\n1. You can select a project by symlinking to it, for example if you have a project called myProject do ln -s dynamicInventory-mcc2 myProject\n and then run ./myProject"
		print "2. It is also possible that none of your VMs are allocated to myProject, please add them to the project: e.g. by running"
		print 'nova --os-tenant-name TF_NNF --os-tenant-id 033asdda60d7046b6affdf31d14asdasb meta nodex set project_name="myProject"'
		sys.exit()
	else:
		print json.dumps(inventory)