#!/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)