Newer
Older
#!/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 keystoneclient import session as kssession
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"
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
def _get_keystone_v2_auth(self, v2_auth_url, **kwargs):
auth_token = kwargs.pop('auth_token', None)
tenant_id = kwargs.pop('project_id', None)
tenant_name = kwargs.pop('project_name', None)
if auth_token:
return v2_auth.Token(v2_auth_url, auth_token,
tenant_id=tenant_id,
tenant_name=tenant_name)
else:
return v2_auth.Password(v2_auth_url,
username=kwargs.pop('username', None),
password=kwargs.pop('password', None),
tenant_id=tenant_id,
tenant_name=tenant_name)
def _get_keystone_session(self, **kwargs):
# first create a Keystone session
cacert = kwargs.pop('cacert', None)
cert = kwargs.pop('cert', None)
key = kwargs.pop('key', None)
insecure = kwargs.pop('insecure', False)
timeout = kwargs.pop('timeout', None)
verify = kwargs.pop('verify', None)
# FIXME(gyee): this code should come from keystoneclient
if verify is None:
if insecure:
verify = False
else:
# TODO(gyee): should we do
# heatclient.common.http.get_system_ca_fle()?
verify = cacert or True
if cert and key:
# passing cert and key together is deprecated in favour of the
# requests lib form of having the cert and key as a tuple
cert = (cert, key)
return kssession.Session(verify=verify, cert=cert, timeout=timeout)
def _get_keystone_auth(self, session, auth_url, **kwargs):
# FIXME(dhu): this code should come from keystoneclient
# discover the supported keystone versions using the given url
v2_auth_url=auth_url
v3_auth_url=None
# Determine which authentication plugin to use. First inspect the
# auth_url to see the supported version. If both v3 and v2 are
# supported, then use the highest version if possible.
auth = None
if v3_auth_url and v2_auth_url:
user_domain_name = kwargs.get('user_domain_name', None)
user_domain_id = kwargs.get('user_domain_id', None)
project_domain_name = kwargs.get('project_domain_name', None)
project_domain_id = kwargs.get('project_domain_id', None)
# support both v2 and v3 auth. Use v3 if domain information is
# provided.
if (user_domain_name or user_domain_id or project_domain_name or
project_domain_id):
auth = self._get_keystone_v3_auth(v3_auth_url, **kwargs)
else:
auth = self._get_keystone_v2_auth(v2_auth_url, **kwargs)
elif v3_auth_url:
# support only v3
auth = self._get_keystone_v3_auth(v3_auth_url, **kwargs)
elif v2_auth_url:
# support only v2
auth = self._get_keystone_v2_auth(v2_auth_url, **kwargs)
else:
raise exc.CommandError(_('Unable to determine the Keystone '
'version to authenticate with using the '
'given auth_url.'))
return auth
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):
self.nc = nvclient.Client( auth_url=self.authUrl,
username=self.username,
api_key=self.passwd,
project_id=self.tenantName,
tenant_id=self.tenantID,
service_type="compute"
)
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
kwargs = {
'insecure': False,
}
keystone_session = self._get_keystone_session(**kwargs)
kwargs = {
'username': self.username,
'password': self.passwd,
'project_id': self.tenantID,
'project_name': self.tenantName
}
keystone_auth = self._get_keystone_auth(keystone_session,
self.authUrl,
**kwargs)
endpoint = keystone_auth.get_endpoint(keystone_session,service_type='orchestration', region_name=None)
kwargs = {
'username': self.username,
'include_pass': False,
'session': keystone_session,
'auth_url': self.authUrl,
'region_name': '',
'endpoint_type': 'publicURL',
'service_type': 'orchestration',
'password': self.passwd,
'auth': keystone_auth,
}
api_version=1
self.hc = heat_client.Client(api_version, endpoint, **kwargs)
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
inventory = {}
inventory['_meta'] = { 'hostvars': {} }
for server in nc.servers.list():
if server.id in instance_ids:
Chris Hines
committed
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]
Chris Hines
committed
# 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'
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)