Skip to content
Snippets Groups Projects
make_inventory.py 4.96 KiB
Newer Older
#!/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))