-
Notifications
You must be signed in to change notification settings - Fork 46
/
cluster.py
340 lines (299 loc) · 13.4 KB
/
cluster.py
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
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
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
from distutils.version import LooseVersion
from fabric.api import env, settings, run
from fabos import detect_ostype, get_release, get_build
from fabfile.config import *
from fabfile.utils.config import get_value
from fabfile.utils.interface import get_data_ip
def get_all_hostnames():
if isinstance(env.hostnames.get('all', None), list):
# Maintaining backward compatability with old testbed.py
hostnames = env.hostnames['all']
else:
hostnames = []
for host in env.roledefs['all']:
# Return hostnames in the same order in which the 'all'
# role is defined.
hostnames.append(env.hostnames[host])
return hostnames
def get_hostname(host_string):
if isinstance(env.hostnames.get('all', None), list):
# Maintaining backward compatability with old testbed.py
hostnames = dict(zip(env.roledefs['all'], env.hostnames['all']))
else:
hostnames = env.hostnames
return hostnames[host_string]
def get_orchestrator():
return getattr(env, 'orchestrator', 'openstack')
def get_mode(compute_host):
mode = get_orchestrator()
esxi_info = getattr(testbed, 'esxi_hosts', None)
if not esxi_info:
print 'Info: esxi_hosts block is not defined in testbed file. Exiting'
return
if esxi_info:
for host in esxi_info.keys():
esxi_data = esxi_info[host]
if 'contrail_vm' not in esxi_data:
continue #For vcenter gateway 'contrail_vm' not present in testbed.py
data = esxi_data['contrail_vm']
if (esxi_data['contrail_vm']['host'] == compute_host):
if 'mode' in data.keys():
mode = esxi_data['contrail_vm']['mode']
return mode
def is_lbaas_enabled():
if 'enable_lbaas' not in env.keys():
return False
else:
return env.enable_lbaas
def get_sriov_details(compute_host_string):
sriov_string = ""
if 'sriov' not in env.keys():
return sriov_string
if compute_host_string not in env.sriov:
return sriov_string
intf_list = env.sriov[compute_host_string]
for intf in intf_list:
if 'interface' in intf:
if not intf.get('VF'):
continue
if not intf.get('physnets'):
continue
if not len(intf['physnets']):
continue
if sriov_string:
sriov_string += ","
sriov_string += intf['interface'] + ":" + str(intf['VF']) + ":"
for phynet in intf['physnets']:
sriov_string += phynet
if intf['physnets'][-1] != phynet:
sriov_string += "%"
return sriov_string
def get_vgw_details(compute_host_string):
# Check and collect the VGW details for given compute host
set_vgw = False
vgw_intf_list = []
public_subnet = []
public_vn_name = []
gateway_routes = []
vgw_details = (set_vgw, gateway_routes, public_subnet, public_vn_name, vgw_intf_list)
if ('vgw' not in env.roledefs or
compute_host_string not in env.roledefs['vgw']):
return vgw_details
set_vgw = True
vgw_intf_list = env.vgw[compute_host_string].keys()
for vgw_intf in vgw_intf_list:
public_subnet.append(env.vgw[compute_host_string][vgw_intf]['ipam-subnets'])
public_vn_name.append(env.vgw[compute_host_string][vgw_intf]['vn'])
if 'gateway-routes' in env.vgw[compute_host_string][vgw_intf].keys():
gateway_routes.append(env.vgw[compute_host_string][vgw_intf]['gateway-routes'])
vgw_details = (set_vgw, gateway_routes, public_subnet, public_vn_name, vgw_intf_list)
return vgw_details
def get_compute_as_gateway_list():
gateway_server_ip_list = []
gateway_mode_info = getattr(env, 'compute_as_gateway_mode', None)
if gateway_mode_info:
for host in gateway_mode_info.keys():
if( gateway_mode_info[host] == 'server' ):
gateway_server_ip_list.append(get_data_ip(host)[0])
return gateway_server_ip_list
def get_vmware_details(compute_host_string):
esxi_data = {}
esxi_info = getattr(testbed, 'esxi_hosts', None)
if esxi_info:
for host in esxi_info.keys():
esxi_data = esxi_info[host]
if 'contrail_vm' not in esxi_data:
continue #For vcenter gateway contrail_vm not present in testbed.py
data = esxi_data['contrail_vm']
if (esxi_data['contrail_vm']['host'] == compute_host_string):
return esxi_data
else:
continue
return None
def get_vmware_datacenter_mtu(vcenter_server_string):
vcenter_data = {}
datacenter_mtu = 1500
vcenter_info = getattr(env, 'vcenter_servers', None)
if vcenter_server_string in vcenter_info.keys():
vcenter_server = vcenter_info[vcenter_server_string]
if 'datacenter_mtu' in vcenter_server.keys():
datacenter_mtu = vcenter_server['datacenter_mtu']
return datacenter_mtu
def get_esxi_ssl_thumbprint(esxi_data):
host_string = '%s@%s' %(esxi_data['username'], esxi_data['ip'])
with settings(host_string = host_string, password = esxi_data['password'],
warn_only = True, shell = '/bin/sh -l -c'):
# Do not change to sudo, It should be run/sudo will not work in eski hosts.
out = run('openssl x509 -in /etc/vmware/ssl/rui.crt -fingerprint -sha1 -noout')
out = out.split()
out = out[7].split('=')
ssl_thumbprint = out[1]
print 'ssl thumbprint of the ESXi host %s is %s' % (esxi_data['ip'], ssl_thumbprint)
return ssl_thumbprint
def get_esxi_vms_and_hosts(esxi_info, vcenter_server, host_list, compute_list, password_list):
hosts = []
vms = []
clusters = []
for host in host_list:
with settings(host=host):
if host in esxi_info.keys():
esxi_data = esxi_info[host]
vm_name = "ContrailVM"
ssl_thumbprint = get_esxi_ssl_thumbprint(esxi_data)
esx_list=esxi_data['ip'],esxi_data['username'],esxi_data['password'],ssl_thumbprint,esxi_data['cluster']
hosts.append(esx_list)
modified_vm_name = vm_name+"-"+vcenter_server['datacenter']+"-"+esxi_data['ip']
for host_string in compute_list:
try:
if host_string == esxi_data['contrail_vm']['host']:
break
except Exception as e:#Handling exception in case
print '%s'%e #contrail_vm not present(vcenter gateway)
password = password_list[host_string]
vm_info_list = modified_vm_name, host_string, password
vms.append(vm_info_list)
else:
print 'Info: esxi_hosts block does not have the esxi host.Exiting'
return
clusters = vcenter_server['cluster']
return (hosts,clusters,vms)
def create_esxi_vrouter_map_file(vcenter_server_name, vcenter_server, host_string):
#create the static esxi:vrouter map file
esxi_info = getattr(testbed, 'esxi_hosts', None)
if not esxi_info:
print 'Info: esxi_hosts block is not defined in testbed file. Exiting'
return
esxi_hosts = []
for host in esxi_info.keys():
if esxi_info[host]['vcenter_server'] is vcenter_server_name:
esxi_hosts.append(host)
with settings(host_string=host_string, warn_only=True):
tmp_fname = "/tmp/ESXiToVRouterIp-%s" %(host_string)
for esxi_host in esxi_hosts:
if esxi_info[esxi_host]['cluster'] in vcenter_server['cluster']:
esxi_ip = esxi_info[esxi_host]['ip']
vrouter_ip_string = esxi_info[esxi_host]['contrail_vm']['host']
vrouter_ip = vrouter_ip_string.split('@')[1]
local("echo '%s:%s' >> %s" %(esxi_ip, vrouter_ip, tmp_fname))
put(tmp_fname, "/etc/contrail/ESXiToVRouterIp.map", use_sudo=True)
local("rm %s" %(tmp_fname))
def get_nodes_to_upgrade_pkg(package, os_type, *args, **kwargs):
"""get the list of nodes in which th given package needs to be upgraded"""
nodes = []
version = kwargs.get('version', None)
for host_string in args:
with settings(host_string=host_string, warn_only=True):
if os_type in ['ubuntu']:
installed = sudo("dpkg -l | grep %s" % package)
elif os_type in ['centos', 'redhat', 'centoslinux']:
installed = sudo("rpm -qa | grep %s" % package)
else:
raise RuntimeError('Unsupported OS type!')
if not installed:
nodes.append(host_string)
elif (version and
version != '%s-%s' %
(get_release(package), get_build(package))):
nodes.append(host_string)
else:
print 'Required package %s installed. Skipping!' % package
return nodes
def get_package_installed_info(package, os_type, *nodes):
"""Check if given package is installed in nodes and return
installation info
"""
pkg_status = {'installed': [], 'not_installed': []}
for host_string in nodes:
with settings(host_string=host_string, warn_only=True):
if os_type.lower() in ['ubuntu']:
cmd = 'dpkg -l %s' % package
elif os_type.lower() in ['centos', 'redhat', 'fedora', 'centoslinux']:
cmd = 'rpm -q %s' % package
else:
raise RuntimeError('[%s]: Unsupported OS Type (%s)' % (host_string, os_type))
if sudo(cmd).succeeded:
pkg_status['installed'].append(host_string)
continue
pkg_status['not_installed'].append(host_string)
return pkg_status
def reboot_nodes(*args):
"""reboots the given nodes"""
for host_string in args:
with settings(host_string=host_string):
os_type = detect_ostype()
print "Rebooting (%s) to boot with new kernel version" % host_string
try:
if os_type.lower() in ['ubuntu']:
sudo('sync; reboot --force', timeout=3)
else:
sudo('sleep 5; shutdown -r now', timeout=3)
except CommandTimeout:
pass
def get_tsn_nodes():
"""Identifies the list of nodes to be provisioned as
tsn nodes.
"""
try:
return env.roledefs['tsn']
except KeyError:
return []
def get_toragent_nodes():
"""Identifies the list of nodes to be provisioned as
toragent nodes.
"""
try:
return env.roledefs['toragent']
except KeyError:
return []
def get_ntp_server():
return getattr(env, 'ntp_server', None)
def get_metadata_secret():
""" Retrieves metadata secret
1. if metadata secret is supplied in testbed, retrieve its value from testbed
2. if not defined in testbed, depending on orchestrator, retrieve it from
the first orchestrator node
"""
metadata_secret = None
orch = get_orchestrator()
if orch.lower() == 'openstack':
openstack_host = env.roledefs['openstack'][0]
# Use metadata_secret provided in testbed. If not available
# retrieve metadata secret from openstack node
metadata_secret = getattr(testbed,
'neutron_metadata_proxy_shared_secret',
None)
if not metadata_secret:
with settings(host_string=openstack_host):
ostype = detect_ostype()
# For Juno, use service_metadata_proxy metadata_proxy_shared_secret
# from neutron section in /etc/nova/nova.conf
if ostype.lower() in ['centos', 'redhat', 'centoslinux']:
api_version = sudo("rpm -q --queryformat='%{VERSION}' openstack-nova-api")
is_juno_or_higher = LooseVersion(api_version) >= LooseVersion('2014.2.2')
elif ostype.lower() in ['ubuntu']:
api_version = sudo("dpkg-query -W -f='${VERSION}' nova-api")
is_juno_or_higher = LooseVersion(api_version) >= LooseVersion('2014.2.2')
else:
raise RuntimeError("Unknown ostype (%s)" % ostype)
if is_juno_or_higher:
status, secret = get_value('/etc/nova/nova.conf',
'neutron',
'service_metadata_proxy',
'metadata_proxy_shared_secret')
else:
status, secret = get_value('/etc/nova/nova.conf',
'DEFAULT',
'service_neutron_metadata_proxy',
'neutron_metadata_proxy_shared_secret')
metadata_secret = secret if status == 'True' else None
else:
print "WARNING get_metadata_secret: Orchestrator(%s) is not supported" % orch
return metadata_secret
def is_contrail_node(node):
'''Assuming that all contrail nodes are installed with
package - contrail-setup, returns True if the package is installed in the node
'''
package_info = ''
with settings(host_string=node, warn_only=True):
package_info = get_build('contrail-setup')
return True if package_info else False