72
79
def convert_unit_to_machinename(unit):
73
80
juju_status = get_juju_status(unit)
74
81
service = unit.split('/')[0]
75
return int(juju_status['services'][service]['units'][unit]['machine'])
83
juju_status[kiki.applications()][service]['units'][unit]['machine'])
78
86
def convert_machineno_to_unit(machineno, juju_status=None):
79
87
if not juju_status:
80
88
juju_status = get_juju_status()
81
services = [service for service in juju_status['services']]
89
services = [service for service in juju_status[kiki.applications()]]
82
90
for svc in services:
83
if 'units' in juju_status['services'][svc]:
84
for unit in juju_status['services'][svc]['units']:
85
unit_info = juju_status['services'][svc]['units'][unit]
91
if 'units' in juju_status[kiki.applications()][svc]:
92
for unit in juju_status[kiki.applications()][svc]['units']:
93
unit_info = juju_status[
94
kiki.applications()][svc]['units'][unit]
86
95
if unit_info['machine'] == machineno:
90
99
def remote_shell_check(unit, timeout=None):
100
cmd = [kiki.cmd(), 'run']
93
102
cmd.extend(['--timeout', str(timeout)])
94
103
cmd.extend(['--unit', unit, 'uname -a'])
216
225
logging.info('Setting %s to %s' % (service, option))
217
subprocess.check_call(['juju', 'set', service, option])
226
subprocess.check_call([kiki.cmd(), kiki.set_config(),
219
229
juju_wait_finished()
222
232
def juju_get_config_keys(service):
223
cmd = ['juju', 'get', service]
233
cmd = [kiki.cmd(), kiki.get_config(), service]
224
234
juju_get_output = subprocess.Popen(cmd, stdout=subprocess.PIPE).stdout
225
235
service_config = yaml.load(juju_get_output)
226
236
return service_config['settings'].keys()
229
239
def juju_get(service, option):
230
cmd = ['juju', 'get', service]
240
cmd = [kiki.cmd(), kiki.get_config(), service]
231
241
juju_get_output = subprocess.Popen(cmd, stdout=subprocess.PIPE).stdout
232
242
service_config = yaml.load(juju_get_output)
242
252
def get_juju_environments_yaml():
253
""" Get the environments.yaml data from a Juju 1 environment
255
@returns Dictionary of the data from the environments.yaml file
243
257
juju_env_file = open(os.environ['HOME'] + "/.juju/environments.yaml", 'r')
244
258
return yaml.load(juju_env_file)
261
def get_cloud_from_controller():
262
""" Get the cloud name from the Juju 2.x controller
264
@returns String name of the cloud for the current Juju 2.x controller
266
cmd = [kiki.cmd(), 'show-controller', '--format=yaml']
267
cloud_config = yaml.load(subprocess.check_output(cmd))
268
# There will only be one top level controller from show-controller,
269
# but we do not know its name.
270
assert len(cloud_config) == 1
272
return cloud_config.values()[0]['details']['cloud']
274
raise KeyError("Failed to get cloud information from the controller")
247
277
def get_provider_type():
248
juju_env = subprocess.check_output(['juju', 'switch']).strip('\n')
249
juju_env_contents = get_juju_environments_yaml()
250
return juju_env_contents['environments'][juju_env]['type']
278
""" Get the type of the undercloud
280
@returns String name of the undercloud type
282
juju_env = subprocess.check_output([kiki.cmd(), 'switch']).strip('\n')
283
if kiki.version() < 2:
284
juju_env_contents = get_juju_environments_yaml()
285
return juju_env_contents['environments'][juju_env]['type']
287
cloud = get_cloud_from_controller()
289
# If the controller was deployed from this system with
290
# the cloud configured in ~/.local/share/juju/clouds.yaml
291
# Determine the cloud type directly
292
cmd = [kiki.cmd(), 'show-cloud', cloud, '--format=yaml']
293
return yaml.load(subprocess.check_output(cmd))['type']
295
# If the controller was deployed elsewhere
296
# show-controllers unhelpfully returns an empty string for cloud
297
# For now assume openstack
301
class MissingOSAthenticationException(Exception):
253
305
def get_undercloud_auth():
254
juju_env = subprocess.check_output(['juju', 'switch']).strip('\n')
255
juju_env_contents = get_juju_environments_yaml()
256
novarc_settings = juju_env_contents['environments'][juju_env]
258
'OS_AUTH_URL': novarc_settings['auth-url'],
259
'OS_TENANT_NAME': novarc_settings['tenant-name'],
260
'OS_USERNAME': novarc_settings['username'],
261
'OS_PASSWORD': novarc_settings['password'],
262
'OS_REGION_NAME': novarc_settings['region'],
306
""" Get the undercloud OpenStack authentication settings from the
309
@raises MissingOSAthenticationException if one or more settings are
311
@returns Dictionary of authentication settings
314
os_auth_url = os.environ.get('OS_AUTH_URL')
316
api_version = os_auth_url.split('/')[-1].translate(None, 'v')
318
logging.error('Missing OS authentication setting: OS_AUTH_URL')
319
raise MissingOSAthenticationException(
320
'One or more OpenStack authetication variables could '
321
'be found in the environment. Please export the OS_* '
322
'settings into the environment.')
324
logging.info('AUTH_URL: {}, api_ver: {}'.format(os_auth_url, api_version))
326
if api_version == '2.0':
328
logging.info('Using keystone API V2 for undercloud auth')
330
'OS_AUTH_URL': os.environ.get('OS_AUTH_URL'),
331
'OS_TENANT_NAME': os.environ.get('OS_TENANT_NAME'),
332
'OS_USERNAME': os.environ.get('OS_USERNAME'),
333
'OS_PASSWORD': os.environ.get('OS_PASSWORD'),
334
'OS_REGION_NAME': os.environ.get('OS_REGION_NAME'),
337
elif api_version >= '3':
339
logging.info('Using keystone API V3 (or later) for undercloud auth')
340
domain = os.environ.get('OS_DOMAIN_NAME')
342
'OS_AUTH_URL': os.environ.get('OS_AUTH_URL'),
343
'OS_USERNAME': os.environ.get('OS_USERNAME'),
344
'OS_PASSWORD': os.environ.get('OS_PASSWORD'),
345
'OS_REGION_NAME': os.environ.get('OS_REGION_NAME'),
349
auth_settings['OS_DOMAIN_NAME': 'admin_domain'] = domain
351
auth_settings['OS_USER_DOMAIN_NAME'] = (
352
os.environ.get('OS_USER_DOMAIN_NAME'))
353
auth_settings['OS_PROJECT_NAME'] = (
354
os.environ.get('OS_PROJECT_NAME'))
355
auth_settings['OS_PROJECT_DOMAIN_NAME'] = (
356
os.environ.get('OS_PROJECT_DOMAIN_NAME'))
359
for key, settings in auth_settings.items():
361
logging.error('Missing OS authentication setting: {}'
363
raise MissingOSAthenticationException(
364
'One or more OpenStack authetication variables could '
365
'be found in the environment. Please export the OS_* '
366
'settings into the environment.')
264
368
return auth_settings
267
def get_undercloud_netid():
268
juju_env = subprocess.check_output(['juju', 'switch']).strip('\n')
269
juju_env_contents = get_juju_environments_yaml()
270
if 'network' in juju_env_contents['environments'][juju_env]:
271
return juju_env_contents['environments'][juju_env]['network']
274
371
# Openstack Client helpers
275
372
def get_auth_url(juju_status=None):
276
373
if juju_get('keystone', 'vip'):
277
374
return juju_get('keystone', 'vip')
278
375
if not juju_status:
279
376
juju_status = get_juju_status()
280
unit = juju_status['services']['keystone']['units'].itervalues().next()
377
unit = (juju_status[kiki.applications()]['keystone']['units']
281
380
return unit['public-address']
323
422
def get_mojo_file(filename):
423
"""Search for a stage specific version,
424
then the current working directory,
425
then in the directory where the script was called,
426
then in the directory above where the script was called.
428
@returns string path to configuration file
429
@raises ConfigFileNotFound if no file can be located
324
432
if 'MOJO_SPEC_DIR' in os.environ and 'MOJO_STAGE' in os.environ:
325
mfile = '{}/{}/{}'.format(os.environ['MOJO_SPEC_DIR'],
326
os.environ['MOJO_STAGE'], filename)
328
if os.path.isfile(filename):
434
files.append('{}/{}/{}'.format(os.environ['MOJO_SPEC_DIR'],
435
os.environ['MOJO_STAGE'], filename))
438
files.append(filename)
439
# Called file directory
440
files.append(os.path.join(os.path.dirname(__file__), filename))
441
# Up one directory from called file
442
files.append(os.path.join(
443
os.path.dirname(os.path.dirname(__file__)),
446
for file_path in files:
447
if os.path.isfile(file_path):
333
451
def get_mojo_config(filename):