#!/usr/bin/env python import sys, os, string, socket, re import shlex, multiprocessing, time, shutil, json from novaclient import client as nvclient from cinderclient import client as cdclient import novaclient.exceptions as nvexceptions from keystoneclient import client as ksclient from joblib import Parallel, delayed from multiprocessing import Process, Manager, Pool def gatherInfo(md_key,md_value,authDict,project_id,inventory): ## Fetch the Nova Object from keystoneclient import client as ksclient from keystoneauth1.identity import v3 from keystoneauth1 import session auth = v3.Password(project_id=project_id,**authDict) sess = session.Session(auth=auth) nc = nvclient.Client('2.0',session=sess) cc = cdclient.Client('2.0',session=sess) for server in nc.servers.list(): if server.metadata and \ 'ansible_host_groups' in server.metadata and \ md_key in server.metadata: if server.metadata[md_key].strip() != md_value.strip(): continue unwantedChars = """][")(""" rgx = re.compile('[%s]' % unwantedChars) ansible_groups = rgx.sub('', server.metadata['ansible_host_groups']).split(',') hostname = server.name novaVolumes = cc.volumes.list(server.id) # 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 if not hostname in inventory['_meta']['hostvars']: inventory['_meta']['hostvars'][hostname] = {} for md in server.metadata.items(): if md[0] not in (md_key,'ansible_host_groups'): inventory['_meta']['hostvars'][hostname].update({ md[0]:md[1] }) if novaVolumes: volDict = {} for volume in novaVolumes: try: if volume.attachments[0]['server_id'] == server.id: volDict[volume.name] = {'dev':'/dev/disk/by-id/virtio-' + volume.id[:20],'uuid':volume.id} except IndexError: continue if volDict: inventory['_meta']['hostvars'][hostname]['ansible_host_volumes'] = volDict network_name=None if len(list(server.networks.keys())) > 1: for nn in server.networks.keys(): if 'internal' in nn: network_name = nn else: inventory['_meta']['hostvars'][hostname]['public_host'] = server.networks[nn][0] if network_name == None: network_name = list(server.networks.keys())[0] inventory['_meta']['hostvars'][hostname]['ansible_host'] = server.networks[network_name][0] else: continue return inventory def merge(i,j): for k in i.keys(): v=i[k] if k in j: if isinstance(v,list): j[k].extend(v) if isinstance(v,dict): merge(i[k],j[k]) else: j[k]=i[k] if __name__ == "__main__": inventory = {} inventory['_meta'] = { 'hostvars': {} } authDict={} try: authDict['auth_url'] = os.environ['OS_AUTH_URL'] authDict['username'] = os.environ['OS_USERNAME'] authDict['password'] = os.environ['OS_PASSWORD'] authDict['user_domain_name'] = os.environ['OS_USER_DOMAIN_NAME'] except KeyError: print("Env Variables not set, Please run: source <openstack rc file>") sys.exit() if sys.argv[1] == "static": static=True md_key="project_name" md_value=sys.argv[2] else: static=False md_key="project_name" md_value=sys.argv[1] from keystoneclient import client as ksclient import keystoneclient from keystoneauth1.identity import v3 from keystoneauth1 import session # auth = v3.Password(username=userName, password=passwd, auth_url=authUrl,user_domain_name=domainName) auth = v3.Password(unscoped=True,**authDict) sess = session.Session(auth=auth) kc = ksclient.Client(session=sess) kc.include_metadata = False authmgr = keystoneclient.v3.auth.AuthManager(kc) projects = authmgr.projects() enabled_projects = [ x for x in projects if x.enabled ] inventory_list = Parallel(n_jobs=len(projects))(delayed(gatherInfo) (md_key,md_value, authDict, proj.id, inventory) for proj in enabled_projects) inventory={} for i in inventory_list: merge(i,inventory) if not inventory['_meta']['hostvars']: print("I could not find any resouces tagged with {}: {}".format(md_key,md_value)) else: if static: print( "#!/bin/bash\necho '"+json.dumps(inventory,indent=4)+"'") else: print(json.dumps(inventory))