-
Notifications
You must be signed in to change notification settings - Fork 4
/
dynamicInventory
executable file
·141 lines (122 loc) · 6.43 KB
/
dynamicInventory
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
#!/usr/bin/env python
import sys, os, string, subprocess, socket, re
import copy, shlex,uuid, random, multiprocessing, time, shutil, json
#import novaclient.v1_1.client as nvclient
#import novaclient.exceptions as nvexceptions
from keystoneclient.auth.identity import v2 as v2_auth
#from heatclient import client as heat_client
#from novaclient import client as nova_client
#from cinderclient import client as cinder_client
import heatclient
import novaclient
import cinderclient
import heatclient.client
import novaclient.client
import cinderclient.client
import keystoneclient.client
from keystoneclient.auth.identity import v2
from keystoneclient import session
from novaclient import client
from keystoneclient import session as kssession
#NOVA_STANDALONE=True
NOVA_STANDALONE=False
class OpenStackConnection:
def __init__(self, username, passwd):
self.username=username
self.passwd=passwd
self.tenantName= os.environ['OS_TENANT_NAME']
self.tenantID= os.environ['OS_TENANT_ID']
self.authUrl="https://keystone.rc.nectar.org.au:5000/v2.0"
def get_stack_name(self,stack):
stacks=[]
for s in self.hc.stacks.list():
stacks.append(s.stack_name)
if stack in stacks:
return stack
elif len(stacks)==1:
return stacks[0]
elif len(stacks)==0:
raise Exception("You do not have any heat stacks in your OpenStack Project")
else:
raise Exception("You have multiple heat stacks in your OpenStack Project and I'm not sure which one to use.\n You can select a stack by symlinking to a stack, for example if you have a stack called mycluster do ln -s %s mycluster\n"%stack)
def auth(self):
kwargs = {
'username': self.username,
'password': self.passwd,
'tenant_id': self.tenantID,
'auth_url':self.authUrl,
}
auth = v2.Password(**kwargs)
sess = session.Session(auth=auth)
kwargs = {
'session':sess,
}
api_version='2'
self.nc = novaclient.client.Client(api_version, session=sess)
api_version=1
endpoint="https://heat.rc.nectar.org.au:8004/v1/%s"%self.tenantID
self.hc = heatclient.client.Client(api_version, endpoint, session=sess)
api_version=1
self.cc = cinderclient.client.Client(api_version, session=sess)
def recurse_resources(self,stack,resource):
result=[]
if 'OS::Nova::Server' in resource.resource_type:
result.append(resource.physical_resource_id)
if 'OS::Heat::ResourceGroup' in resource.resource_type:
for r in self.hc.resources.list(resource.physical_resource_id):
result.extend(self.recurse_resources(stack,r))
return result
def gatherInfo(self,stack_name):
## Fetch the Nova Object
instance_ids=[]
for i in self.hc.stacks.list():
if i.stack_name == stack_name:
for r in self.hc.resources.list(i.stack_name):
instance_ids.extend(self.recurse_resources(stack=i,resource=r))
nc=self.nc
cc=self.cc
inventory = {}
inventory['_meta'] = { 'hostvars': {} }
for server in nc.servers.list():
if server.id in instance_ids:
if server.metadata and 'ansible_host_groups' in server.metadata:
hostname=server.name
groups = json.loads(server.metadata['ansible_host_groups'])
for group in groups:
if group in inventory:
inventory[group].append(hostname)
else:
inventory[group] = [ hostname ]
elif server.metadata and 'ansible_host_group' in server.metadata:
#hostname = socket.gethostbyaddr(server.networks.values()[0][0])[0]
hostname = server.name
# Set Ansible Host Group
if server.metadata['ansible_host_group'] in inventory:
inventory[server.metadata['ansible_host_group']].append(hostname)
else:
inventory[server.metadata['ansible_host_group']] = [hostname]
#print dir(server)
# Set the other host variables
inventory['_meta']['hostvars'][hostname] = {}
inventory['_meta']['hostvars'][hostname]['ansible_ssh_host'] = server.networks.values()[0][0]
inventory['_meta']['hostvars'][hostname]['ansible_remote_tmp'] = '/tmp/ansible'
for key in server.metadata.keys():
if 'ansible_ssh' in key:
inventory['_meta']['hostvars'][hostname][key] = server.metadata[key]
inventory['_meta']['hostvars'][hostname]['ansible_ssh_user'] = 'ec2-user'
for vol in server.to_dict()['os-extended-volumes:volumes_attached']:
for cv in cc.volumes.findall():
if cv.id == vol['id']:
devname = '/dev/disk/by-id/virtio-'+cv.id[0:20]
if not 'ansible_host_volumes' in inventory['_meta']['hostvars'][hostname]:
inventory['_meta']['hostvars'][hostname]['ansible_host_volumes']={}
inventory['_meta']['hostvars'][hostname]['ansible_host_volumes'][cv.display_name]={'uuid':vol['id'],'dev':devname}
print json.dumps(inventory)
if __name__ == "__main__":
stack_name=os.path.basename(sys.argv[0])
username = os.environ['OS_USERNAME']
passwd = os.environ['OS_PASSWORD']
openstack = OpenStackConnection(username, passwd)
openstack.auth()
stack_name=openstack.get_stack_name(stack_name)
openstack.gatherInfo(stack_name)