ranger/orm/orm_client/flavorgen/regionator.py
Nicholas Jones dac751d04b Merge diverged code
Change-Id: I7a88d9bec69371bec1004572a4fa87cdfbbf1f28
2018-05-08 11:50:06 -05:00

162 lines
4.9 KiB
Python

#!/usr/bin/env python
import argparse
import ast
import json
import os
import re
import subprocess
import tempfile
import time
# Default flavor json directory
FLAVOR_DIR = './flavor_dir'
CLI_PATH = '../ormcli/orm'
FID = None
FILE_NAME = None
FLAVOR_NAME = None
REGION_NAME = None
def get_flavor_type(path):
# The last directory name is the flavor type (e.g., 'medium')
return path.split('/')[-2]
def get_region_list(regions):
global REGION_NAME
result = []
for region in regions:
REGION_NAME = region
res, output = sh('get_region')
if not res:
result_region = json.loads(output)
result.append({'name': result_region['name'],
'designType': result_region['designType']})
else:
print 'Failed to get region %s, aborting...' % (region,)
exit(1)
return result
def create_command(cli_command):
if cli_command == 'add_region':
cmd = 'python %s fms add_region %s %s' % (CLI_PATH, FID, FILE_NAME,)
elif cli_command == 'get_flavor':
cmd = 'python %s fms get_flavor test %s' % (CLI_PATH, FLAVOR_NAME,)
elif cli_command == 'get_region':
cmd = 'python %s rms get_region %s' % (CLI_PATH, REGION_NAME,)
else:
raise ValueError('Received an unknown command: %s' % (cli_command,))
if ';' in cmd or '&&' in cmd:
raise Exception("Violation of command injection, cmd is " + cmd)
return cmd
def read_jsonfile(file):
return json.loads(open(file).read())
def calculate_name(flavor):
flavor_name = "{0}.c{1}r{2}d{3}".format(flavor['series'], flavor['vcpus'],
int(flavor['ram']) / 1024,
flavor['disk'])
if 'ephemeral' in flavor and int(flavor['ephemeral']) != 0:
flavor_name += 'e{0}'.format(flavor['ephemeral'])
return flavor_name
def sh(cli_command):
# run a shell command, echoing output, painting error lines red,
# print runtime and status
# return status and output
cmd = create_command(cli_command)
print '>> Starting: ' + cmd
start = time.time()
output = ''
errpat = re.compile('error', re.I)
p = subprocess.Popen(cmd.split(), shell=False, stdout=subprocess.PIPE)
for line in iter(p.stdout.readline, b''):
out = line.rstrip()
print(">>> " + out)
output += out
end = time.time()
span = end - start
retcode = p.wait()
print '>> Ended: %s [%s, %d:%02d]' % (cmd, retcode, span / 60, span % 60)
return retcode, output
parser = argparse.ArgumentParser(prog='regionator',
description='batch add region to flavor')
parser.add_argument('regions',
type=str,
default='',
help='<comma-separated regions to add, e.g. region1,'
'region2>')
parser.add_argument('series',
type=str,
default='',
nargs='?',
help='<comma-separated flavor series to add, e.g. nd,gv>')
args = parser.parse_args()
regions = args.regions.split(',')
series_list = args.series.split(',')
if not regions:
print "Must specify at least one region"
exit(1)
# Get all regions from RMS
region_list = get_region_list(regions)
any_update = False
for file in [os.path.join(dp, f) for dp, dn, fn in
os.walk(os.path.expanduser(FLAVOR_DIR)) for f in fn]:
try:
f = read_jsonfile(file)
except ValueError:
continue
updated = False
flavor_type = get_flavor_type(file)
if not series_list or series_list == [''] or f['series'] in series_list:
data = {'regions': []}
for region in region_list:
# Take only the regions whose design type matches the flavor's
if flavor_type.lower() == region['designType'].lower():
data['regions'].append({'name': region['name']})
updated = True
any_update = True
if updated:
# Create the json file
fh, file_name = tempfile.mkstemp()
FILE_NAME = file_name
os.write(fh, json.dumps(data))
os.close(fh)
FLAVOR_NAME = calculate_name(f)
res, output = sh('get_flavor')
if not res:
flavor = ast.literal_eval(output)
FID = flavor['flavor']['id']
print 'fid: ' + FID
res, output = sh('add_region')
os.unlink(FILE_NAME)
if not any_update:
if not args.series:
exp = 'design type of any of the regions:[{}]'.format(args.regions)
else:
exp = 'combination of regions:[{}] and series:[{}]'.format(
args.regions, args.series)
print('No flavor was updated, please make sure that the {} matches any '
'flavor under the flavor directory'.format(exp))