Add flavor series p1
Add some changes for ord-notifier. Also clean up unnecessary code. Change-Id: I60fb157a8159fa1e30f2effb99cb9273d09a9ddd
This commit is contained in:
parent
91bb6db686
commit
4ec114add6
@ -14,14 +14,20 @@ use_handlers = 'console,logfile'
|
||||
[keystone_authtoken]
|
||||
username = 'admin'
|
||||
password = 'password'
|
||||
user_role= 'admin'
|
||||
project_name = 'admin'
|
||||
region = 'RegionOne'
|
||||
project_domain_name = 'default'
|
||||
user_domain_name = 'default'
|
||||
# Ranger shall be using keystone v3 by default
|
||||
auth_version = 'v3'
|
||||
auth_enabled = False
|
||||
# project_name defaults to 'admin' - change as needed
|
||||
# project_name = ''
|
||||
# user_role defaults to 'admin' - change as needed
|
||||
# user_role= ''
|
||||
# region defaults to 'RegionOne' - change as needed
|
||||
# region = ''
|
||||
# project_domain_name defaults to 'default' - change as needed
|
||||
# project_domain_name = ''
|
||||
# user_domain_name defaults to 'default' - change as needed
|
||||
# user_domain_name = ''
|
||||
# Ranger shall be using keystone v3 by default - change as needed
|
||||
# auth_version = 'v3'
|
||||
# auth_enabled (authorization) is set to True by default - change as needed
|
||||
# auth_enabled = False
|
||||
|
||||
[database]
|
||||
connection = 'mysql://user:pass@localhost:3306/orm'
|
||||
|
@ -33,38 +33,15 @@ database = {
|
||||
|
||||
# this table is for calculating default extra specs needed
|
||||
extra_spec_needed_table = {
|
||||
"ns": {
|
||||
"aggregate_instance_extra_specs____ns": "true",
|
||||
"p1": {
|
||||
"aggregate_instance_extra_specs____p1": "true",
|
||||
"hw____mem_page_size": "large"
|
||||
},
|
||||
"nd": {
|
||||
"aggregate_instance_extra_specs____nd": "true",
|
||||
"hw____mem_page_size": "large"
|
||||
},
|
||||
"nv": {
|
||||
"aggregate_instance_extra_specs____nv": "true",
|
||||
"hw____mem_page_size": "large"
|
||||
},
|
||||
"gv": {
|
||||
"aggregate_instance_extra_specs____gv": "true",
|
||||
"aggregate_instance_extra_specs____c2": "true"
|
||||
},
|
||||
"ss": {
|
||||
"aggregate_instance_extra_specs____ss": "true"
|
||||
}
|
||||
}
|
||||
|
||||
# any key will be added to extra_spec_needed_table need to be added here
|
||||
default_extra_spec_calculated_table = {
|
||||
"aggregate_instance_extra_specs____ns": "",
|
||||
"aggregate_instance_extra_specs____nd": "",
|
||||
"aggregate_instance_extra_specs____nv": "",
|
||||
"aggregate_instance_extra_specs____gv": "",
|
||||
"aggregate_instance_extra_specs____c2": "",
|
||||
"aggregate_instance_extra_specs____ss": "",
|
||||
"aggregate_instance_extra_specs____c2": "",
|
||||
"aggregate_instance_extra_specs____c4": "",
|
||||
"aggregate_instance_extra_specs____v": "",
|
||||
"aggregate_instance_extra_specs____p1": "",
|
||||
"hw____mem_page_size": "",
|
||||
"hw____cpu_policy": "",
|
||||
"hw____numa_nodes": ""
|
||||
@ -95,33 +72,37 @@ api = {
|
||||
|
||||
}
|
||||
|
||||
flavor_series = {
|
||||
'valid_series': [
|
||||
'p1'
|
||||
]
|
||||
}
|
||||
|
||||
# valid_flavor_options
|
||||
flavor_options = {
|
||||
'valid_cpin_opt_values': [
|
||||
'c2', 'c4'
|
||||
],
|
||||
'valid_stor_opt_values': [
|
||||
's1', 's2'
|
||||
],
|
||||
'valid_vnf_opt_values': [
|
||||
'v1', 'v2', 'v3', 'v4', 'v5', 'v6', 'v7'
|
||||
],
|
||||
'valid_numa_values': ['n0'],
|
||||
'valid_nd_vnf_values': ['v8'],
|
||||
'valid_ss_vnf_values': ['v3']
|
||||
'valid_p1_numa_value': 'n0',
|
||||
'valid_p1_opt_values': [
|
||||
'n0', 'i2'
|
||||
]
|
||||
}
|
||||
|
||||
flavor_limits = {
|
||||
# All flavor limits will be converted to integers, and must not
|
||||
# have any non-numeric values.
|
||||
# Root disk, block storage and object storage don't have limits
|
||||
"vcpu_limit": "64",
|
||||
# vram_limit is in MB and must be a multiple of 1024
|
||||
"vram_limit": "393216",
|
||||
# swap_file_limit is in MB and must be a multiple of 1024
|
||||
"swap_file_limit": "393216",
|
||||
# ephemeral_limit is in GB
|
||||
"ephemeral_limit": "10000"
|
||||
# All flavor limits will be converted to integers, and must not be non-numeric.
|
||||
# Root disk, block storage and object storage don't have set limits
|
||||
# vcpu_limit and ephemeral_limit values are in GB
|
||||
# vram_limit and swap_file_limit values are in MB and must be a multiple of 1024
|
||||
|
||||
"swap_file_limit": "327680",
|
||||
"ephemeral_limit": "2000",
|
||||
|
||||
# for 'p1' series:
|
||||
# vcpu_limit and vram_limit for 'p1' series with "n0":"true" option
|
||||
"p1_n0_vcpu_limit": "80",
|
||||
"p1_n0_vram_limit": "327680",
|
||||
# vcpu_limit and vram_limit for 'p1' series with "n0":"false" option
|
||||
"p1_nx_vcpu_limit": "40",
|
||||
"p1_nx_vram_limit": "163840"
|
||||
|
||||
}
|
||||
|
||||
verify = config.CONF.ssl_verify
|
||||
|
@ -4,6 +4,7 @@ from orm.services.flavor_manager.fms_rest.logger import get_logger
|
||||
from orm.services.flavor_manager.fms_rest.logic.error_base import ErrorStatus
|
||||
|
||||
from oslo_db.sqlalchemy import models
|
||||
from pecan import conf
|
||||
from sqlalchemy import BigInteger, Column, ForeignKey, Integer, String
|
||||
from sqlalchemy.ext.declarative import declarative_base
|
||||
from sqlalchemy.orm import relationship, validates
|
||||
@ -123,8 +124,10 @@ class Flavor(Base, FMSBaseModel):
|
||||
|
||||
@validates("series")
|
||||
def validate_series(self, key, series):
|
||||
if series not in ['ns', 'nd', 'nv', 'gv', 'ss']:
|
||||
raise ValueError("Series must be one of: 'ns' 'nd' 'nv' 'gv' 'ss'")
|
||||
valid_flvr_series = conf.flavor_series.valid_series
|
||||
if series not in valid_flvr_series:
|
||||
raise ValueError("Series must be one of {}:".format(str(valid_flvr_series)))
|
||||
|
||||
return series
|
||||
|
||||
def add_region(self, flavor_region):
|
||||
|
@ -217,7 +217,7 @@ class Flavor(Model):
|
||||
self.vcpus = vcpus
|
||||
self.disk = disk
|
||||
self.swap = swap
|
||||
self.ephemeral = "0" if not ephemeral else ephemeral
|
||||
self.ephemeral = ephemeral
|
||||
self.extra_specs = extra_specs
|
||||
self.tag = tag
|
||||
self.options = options
|
||||
@ -227,14 +227,44 @@ class Flavor(Model):
|
||||
self.status = status
|
||||
|
||||
def validate_model(self, context=None):
|
||||
|
||||
bundle = ['b1', 'b2']
|
||||
numa = ['n0', 'n1']
|
||||
numa = ['n0']
|
||||
vlan = ['v1', 'v2', 'v3', 'v4', 'v5', 'v6']
|
||||
vcpu_limit = int(conf.flavor_limits.vcpu_limit)
|
||||
vram_limit = int(conf.flavor_limits.vram_limit)
|
||||
swap_file_limit = int(conf.flavor_limits.swap_file_limit)
|
||||
ephemeral_limit = int(conf.flavor_limits.ephemeral_limit)
|
||||
|
||||
# validate that input entries are valid
|
||||
try:
|
||||
# flavor option values must be either 'true' or 'false' (in quotes)
|
||||
bools = ['true', 'false']
|
||||
|
||||
if self.options:
|
||||
option_values = self.options.values()
|
||||
invalid_opt_vals = [x for x in option_values if (x.lower()
|
||||
not in bools)]
|
||||
if invalid_opt_vals:
|
||||
raise ErrorStatus(400, "All flavor option values must have"
|
||||
" a value of 'true' or 'false'")
|
||||
|
||||
# validate series and set flavor limits
|
||||
if self.series:
|
||||
valid_flavor_series = conf.flavor_series.valid_series
|
||||
if self.series not in valid_flavor_series:
|
||||
raise ErrorStatus(400, "series possible values are {}".format(
|
||||
valid_flavor_series))
|
||||
|
||||
if self.series == 'p1':
|
||||
if {'n0'}.issubset(self.options.keys()) and \
|
||||
eval(self.options.get('n0').lower().capitalize()):
|
||||
vcpu_limit = int(conf.flavor_limits.p1_n0_vcpu_limit)
|
||||
vram_limit = int(conf.flavor_limits.p1_n0_vram_limit)
|
||||
else:
|
||||
vcpu_limit = int(conf.flavor_limits.p1_nx_vcpu_limit)
|
||||
vram_limit = int(conf.flavor_limits.p1_nx_vram_limit)
|
||||
|
||||
# determine other flavor limits
|
||||
swap_file_limit = int(conf.flavor_limits.swap_file_limit)
|
||||
ephemeral_limit = int(conf.flavor_limits.ephemeral_limit)
|
||||
|
||||
isValid = validate_description(self.description)
|
||||
if not isValid:
|
||||
raise ErrorStatus(400, "Flavor description does not allow special characters :"
|
||||
@ -247,13 +277,8 @@ class Flavor(Model):
|
||||
raise ErrorStatus(400, "disk must be a number")
|
||||
if not self.swap.isdigit():
|
||||
raise ErrorStatus(400, "swap must be a number")
|
||||
if not self.ephemeral.isdigit():
|
||||
if self.ephemeral and not self.ephemeral.isdigit():
|
||||
raise ErrorStatus(400, "ephemeral must be a number")
|
||||
if self.series:
|
||||
allowed_series = conf.extra_spec_needed_table.to_dict().keys()
|
||||
if self.series not in allowed_series:
|
||||
raise ErrorStatus(400, "series possible values are {}".format(
|
||||
allowed_series))
|
||||
if int(self.ram) not in range(1024, vram_limit + 1, 1024):
|
||||
raise ErrorStatus(400,
|
||||
"ram value is out of range. Expected range is 1024(1GB)-"
|
||||
@ -264,9 +289,13 @@ class Flavor(Model):
|
||||
"%2d" % (vcpu_limit))
|
||||
if int(self.disk) < 0:
|
||||
raise ErrorStatus(400, "disk cannot be less than zero")
|
||||
if int(self.ephemeral) not in range(0, ephemeral_limit + 1):
|
||||
|
||||
if not self.ephemeral:
|
||||
self.ephemeral = "0"
|
||||
elif self.ephemeral and int(self.ephemeral) not in range(0, ephemeral_limit + 1):
|
||||
raise ErrorStatus(400, "ephemeral value is out of range. Expected range is 0-"
|
||||
"%5d(%2dTB)" % (ephemeral_limit, ephemeral_limit / 1000))
|
||||
|
||||
if int(self.swap) not in range(0, swap_file_limit + 1, 1024):
|
||||
raise ErrorStatus(400,
|
||||
"swap value is out of range. Expected range is 0-"
|
||||
@ -274,6 +303,7 @@ class Flavor(Model):
|
||||
(swap_file_limit, swap_file_limit / 1024))
|
||||
except ValueError:
|
||||
raise ErrorStatus(400, "ram, vcpus, disk, ephemeral and swap must be integers")
|
||||
|
||||
for symbol, value in self.extra_specs.iteritems():
|
||||
if symbol == 'bundle' and value not in bundle:
|
||||
raise ErrorStatus(400,
|
||||
@ -321,7 +351,7 @@ class Flavor(Model):
|
||||
for symbol, value in self.options.iteritems():
|
||||
option = db_models.FlavorOption()
|
||||
option.key_name = symbol
|
||||
option.key_value = value
|
||||
option.key_value = value.lower()
|
||||
options.append(option)
|
||||
|
||||
for region in self.regions:
|
||||
@ -408,10 +438,6 @@ class Flavor(Model):
|
||||
return False
|
||||
|
||||
def get_extra_spec_needed(self):
|
||||
valid_vnf_opts = conf.flavor_options.valid_vnf_opt_values[:]
|
||||
valid_stor_opts = conf.flavor_options.valid_stor_opt_values[:]
|
||||
valid_cpin_opts = conf.flavor_options.valid_cpin_opt_values[:]
|
||||
|
||||
extra_spec_needed = []
|
||||
items = conf.extra_spec_needed_table.to_dict()
|
||||
for symbol, value in items[self.series].iteritems():
|
||||
@ -419,19 +445,11 @@ class Flavor(Model):
|
||||
es.key_name = symbol.replace("____", ":")
|
||||
es.key_value = value
|
||||
|
||||
# update extra_spec default values as needed
|
||||
if self.series == "gv" and "c2" in es.key_name:
|
||||
if "c4" in self.options and self.options['c4'].lower() == "true":
|
||||
es.key_name = es.key_name.replace("c2", "c4")
|
||||
elif self.series == "ss" and "s1" in es.key_name:
|
||||
if "s2" in self.options and self.options['s2'].lower() == "true":
|
||||
es.key_name = es.key_name.replace("s1", "s2")
|
||||
extra_spec_needed.append(es)
|
||||
|
||||
options_items = self.options
|
||||
# check some keys if they exist in option add values to extra specs
|
||||
if self.series in ('ns', 'nv', 'nd', 'ss'):
|
||||
c2_c4_in = False
|
||||
if self.series in 'p1':
|
||||
n0_in = False
|
||||
for symbol, value in options_items.iteritems():
|
||||
es = db_models.FlavorExtraSpec()
|
||||
@ -443,69 +461,24 @@ class Flavor(Model):
|
||||
es.key_value = 2
|
||||
es.key_name = "hw:numa_nodes"
|
||||
extra_spec_needed.append(es)
|
||||
# format cpu pinnin extra spec as appropriate
|
||||
elif symbol in valid_cpin_opts and options_items[symbol].lower() == "true":
|
||||
c2_c4_in = True
|
||||
extra_spec_needed.append(es)
|
||||
# format vnf profile extra spec as appropriate
|
||||
try:
|
||||
if self.series == 'ns' and symbol in valid_vnf_opts and options_items[symbol].lower() == "true":
|
||||
extra_spec_needed.append(es)
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
# if c4, c2 and n0 not in options keys add these values to extra specs
|
||||
if not c2_c4_in:
|
||||
es = db_models.FlavorExtraSpec()
|
||||
es.key_name = "hw:cpu_policy"
|
||||
es.key_value = "dedicated"
|
||||
extra_spec_needed.append(es)
|
||||
# add the default extra specs
|
||||
es = db_models.FlavorExtraSpec()
|
||||
es.key_name = "hw:cpu_policy"
|
||||
es.key_value = "dedicated"
|
||||
extra_spec_needed.append(es)
|
||||
|
||||
if not n0_in:
|
||||
es = db_models.FlavorExtraSpec()
|
||||
es.key_value = 1
|
||||
es.key_name = "hw:numa_nodes"
|
||||
extra_spec_needed.append(es)
|
||||
if {'v5', 'i1'}.issubset(options_items.keys()) and self.series in 'ns' and not \
|
||||
{'i2'}.issubset(options_items.keys()):
|
||||
es = db_models.FlavorExtraSpec()
|
||||
es.key_name = "hw:cpu_sockets"
|
||||
es.key_value = "1"
|
||||
extra_spec_needed.append(es)
|
||||
|
||||
es = db_models.FlavorExtraSpec()
|
||||
es.key_name = "hw:cpu_threads"
|
||||
es.key_value = "1"
|
||||
extra_spec_needed.append(es)
|
||||
|
||||
es = db_models.FlavorExtraSpec()
|
||||
es.key_name = "hw:pci_numa_custom_policy"
|
||||
es.key_value = "ignore"
|
||||
extra_spec_needed.append(es)
|
||||
|
||||
es = db_models.FlavorExtraSpec()
|
||||
es.key_name = "hw:cpu_cores"
|
||||
es.key_value = self.vcpus
|
||||
extra_spec_needed.append(es)
|
||||
if {'i2'}.issubset(options_items.keys()) and self.series in 'ns' and not \
|
||||
{'i1'}.issubset(options_items.keys()):
|
||||
if self.series in ['p1'] and {'i2'}.issubset(options_items.keys()):
|
||||
es = db_models.FlavorExtraSpec()
|
||||
es.key_name = "hw:pci_numa_affinity_policy"
|
||||
es.key_value = "dedicated"
|
||||
extra_spec_needed.append(es)
|
||||
if {'up'}.issubset(options_items.keys()) and self.series in 'ns' and not \
|
||||
{'tp'}.issubset(options_items.keys()) and not \
|
||||
{'i1'}.issubset(options_items.keys()):
|
||||
es = db_models.FlavorExtraSpec()
|
||||
es.key_name = "aggregate_instance_extra_specs:up"
|
||||
es.key_value = "true"
|
||||
extra_spec_needed.append(es)
|
||||
if {'tp'}.issubset(options_items.keys()) and self.series in 'ns' and not \
|
||||
{'up'}.issubset(options_items.keys()) and not \
|
||||
{'i1'}.issubset(options_items.keys()):
|
||||
es = db_models.FlavorExtraSpec()
|
||||
es.key_name = "aggregate_instance_extra_specs:tp"
|
||||
es.key_value = "true"
|
||||
extra_spec_needed.append(es)
|
||||
|
||||
# convert the key_value to a string to avoid/fix pecan json rendering error in update extra_specs
|
||||
i = 0
|
||||
|
@ -25,6 +25,7 @@ def create_flavor(flavor, flavor_uuid, transaction_id):
|
||||
if not flavor.flavor.ephemeral or flavor.flavor.ephemeral.isspace():
|
||||
flavor.flavor.ephemeral = '0'
|
||||
flavor.flavor.name = calculate_name(flavor)
|
||||
|
||||
LOG.debug("Flavor name is [{}] ".format(flavor.flavor.name))
|
||||
|
||||
sql_flavor = flavor.to_db_model()
|
||||
@ -44,9 +45,9 @@ def create_flavor(flavor, flavor_uuid, transaction_id):
|
||||
return ret_flavor
|
||||
|
||||
except Exception as exp:
|
||||
LOG.log_exception("FlavorLogic - Failed to CreateFlavor", exp)
|
||||
LOG.log_exception("FlavorLogic - Failed to CreateFlavor", str(exp.args))
|
||||
datamanager.rollback()
|
||||
if "Duplicate entry" in str(exp.message):
|
||||
if "Duplicate entry" in exp.args:
|
||||
raise ConflictError(409, "Flavor {} already exists".format(flavor.flavor.name))
|
||||
raise
|
||||
finally:
|
||||
@ -217,7 +218,7 @@ def add_regions(flavor_uuid, regions, transaction_id):
|
||||
except Exception as exp:
|
||||
LOG.log_exception("FlavorLogic - Failed to add regions", exp)
|
||||
datamanager.rollback()
|
||||
if "conflicts with persistent instance" in str(exp.message):
|
||||
if "conflicts with persistent instance" in str(exp.args):
|
||||
raise ConflictError(409, "One or more regions already exists in Flavor")
|
||||
raise exp
|
||||
finally:
|
||||
@ -304,7 +305,7 @@ def add_tenants(flavor_uuid, tenants, transaction_id):
|
||||
except Exception as exp:
|
||||
datamanager.rollback()
|
||||
LOG.log_exception("FlavorLogic - Failed to add tenants", exp)
|
||||
if "conflicts with persistent instance" in str(exp.message):
|
||||
if "conflicts with persistent instance" in str(exp.args):
|
||||
raise ConflictError(409, "One or more tenants already exist")
|
||||
raise
|
||||
finally:
|
||||
@ -590,7 +591,7 @@ def add_extra_specs(flavor_id, extra_specs, transaction_id):
|
||||
|
||||
except Exception as exp:
|
||||
datamanager.rollback()
|
||||
if "conflicts with persistent instance" in str(exp.message):
|
||||
if "conflicts with persistent instance" in str(exp.args):
|
||||
raise ConflictError(409, "one or all extra specs {} already exists".format(extra_specs.os_extra_specs))
|
||||
LOG.log_exception("FlavorLogic - fail to add extra spec", exp)
|
||||
raise
|
||||
@ -702,7 +703,7 @@ def add_tags(flavor_id, tags, transaction_id):
|
||||
|
||||
except Exception as exp:
|
||||
datamanager.rollback()
|
||||
if "conflicts with persistent instance" in str(exp.message):
|
||||
if "conflicts with persistent instance" in str(exp.args):
|
||||
raise ConflictError(409, "one or all tags {} already exists".format(
|
||||
tags.tags))
|
||||
LOG.log_exception("FlavorLogic - fail to add tags", exp)
|
||||
@ -849,74 +850,64 @@ def get_flavor_list_by_params(visibility, region, tenant, series, vm_type,
|
||||
|
||||
def calculate_name(flavor):
|
||||
|
||||
valid_vnf_opts = conf.flavor_options.valid_vnf_opt_values[:]
|
||||
valid_stor_opts = conf.flavor_options.valid_stor_opt_values[:]
|
||||
valid_cpin_opts = conf.flavor_options.valid_cpin_opt_values[:]
|
||||
valid_numa_opts = conf.flavor_options.valid_numa_values[:]
|
||||
valid_ss_vnf_opts = conf.flavor_options.valid_ss_vnf_values[:]
|
||||
""" calculate_name function returns the ranger flavor_name:
|
||||
Ranger flavor name is made up of the following components, each separated by a DOT separator:
|
||||
- flavor series
|
||||
- flavor attributes (cores, ram, disk, swap file, ephemeral disks)
|
||||
- flavor options (OPTIONAL)
|
||||
|
||||
Following is a sample flavor name:
|
||||
name = p1.c1r1d1s4e5.i2n0
|
||||
|
||||
where p1 : flavor series name of 'p1'
|
||||
c1 : number of cores (or cpu); sample shows vcpu = 1
|
||||
r1 : RAM value divided by units of 1024 MB; sample ram = 1024 (in MB)
|
||||
d3 : disk value measured in units of GB; sample shows disk = 3
|
||||
s4 : (optional) swap disk value divided by units of 1024 MB; sample swap value = 4096 (in MB)
|
||||
e5 : (optional) ephemeral disk measured in units of GB - sample shows ephemeral = 5 (in GB)
|
||||
|
||||
Anything after the second dot separator are flavor options 'i2' and 'n0' - flavor options are OPTIONAL
|
||||
"""
|
||||
|
||||
valid_p1_opts = conf.flavor_options.valid_p1_opt_values[:]
|
||||
|
||||
name = "{0}.c{1}r{2}d{3}".format(flavor.flavor.series, flavor.flavor.vcpus,
|
||||
int(flavor.flavor.ram) / 1024,
|
||||
flavor.flavor.disk)
|
||||
series = name[:2]
|
||||
|
||||
# validate if a flavor is assigned with incompatible or invalid flavor options
|
||||
n0_in = True
|
||||
|
||||
if series in 'p1':
|
||||
if ({'n0'}.issubset(flavor.flavor.options.keys()) and
|
||||
flavor.flavor.options['n0'].lower() == 'false') or \
|
||||
not ({'n0'}.issubset(flavor.flavor.options.keys())):
|
||||
n0_in = False
|
||||
|
||||
if {'i2'}.issubset(flavor.flavor.options.keys()) and not n0_in:
|
||||
raise ConflictError(409, "Flavor option i2 must be used with "
|
||||
"flavor option 'n0' set to 'true'")
|
||||
|
||||
# add swap disk info to flavor name IF provided
|
||||
swap = getattr(flavor.flavor, 'swap', 0)
|
||||
if swap and int(swap):
|
||||
name += '{}{}'.format('s', int(swap) / 1024)
|
||||
|
||||
# add ephemeral disk info to flavor name IF provided
|
||||
ephemeral = getattr(flavor.flavor, 'ephemeral', 0)
|
||||
if ephemeral and int(ephemeral):
|
||||
name += '{}{}'.format('e', ephemeral)
|
||||
|
||||
# add the valid option keys to the flavor name
|
||||
if len(flavor.flavor.options) > 0:
|
||||
v_option = ""
|
||||
for key in sorted(flavor.flavor.options.iterkeys()):
|
||||
if key[0] == 'v':
|
||||
v_option = key
|
||||
|
||||
for key in sorted(flavor.flavor.options):
|
||||
# only include valid option parameters in flavor name
|
||||
if ((series == 'ns' and key[0] == 'v' and key in valid_vnf_opts) or
|
||||
(series == 'ss' and key[0] == 'v' and key in valid_ss_vnf_opts) or
|
||||
(key[0] == 'n' and key in valid_numa_opts) or
|
||||
(key[0] == 's' and key in valid_stor_opts) or
|
||||
(key[0] == 'c' and key in valid_cpin_opts)):
|
||||
|
||||
if series == 'p1' and key in valid_p1_opts and n0_in:
|
||||
if name.count('.') < 2:
|
||||
name += '.'
|
||||
name += key
|
||||
|
||||
if {'i2', v_option}.issubset(flavor.flavor.options.keys()) and \
|
||||
v_option not in valid_vnf_opts:
|
||||
raise ConflictError(409, "Flavor i2 option must be used with one of "
|
||||
"these choices %s" % str(valid_vnf_opts))
|
||||
|
||||
if {'i1', 'i2'}.issubset(flavor.flavor.options.keys()):
|
||||
raise ConflictError(409, "Flavor i1 and i2 options cannot be used together")
|
||||
|
||||
if {'i1'}.issubset(flavor.flavor.options.keys()) and not \
|
||||
{'v5'}.issubset(flavor.flavor.options.keys()):
|
||||
raise ConflictError(409, "Flavor i1 option must be used with v5 option")
|
||||
|
||||
if {'i2', 'tp', 'up', v_option}.issubset(flavor.flavor.options.keys()) or \
|
||||
{'i2', 'tp', 'up'}.issubset(flavor.flavor.options.keys()) or \
|
||||
{'i2', 'up', v_option}.issubset(flavor.flavor.options.keys()) or \
|
||||
{'i2', 'tp', v_option}.issubset(flavor.flavor.options.keys()):
|
||||
raise ConflictError(409, "Flavor i2 option can only be used with one "
|
||||
"of the following: vx, tp, or up")
|
||||
|
||||
if series in 'ns':
|
||||
if {'v5', 'i1'}.issubset(flavor.flavor.options.keys()):
|
||||
name += 'i1'
|
||||
if {'i2', 'up'}.issubset(flavor.flavor.options.keys()) and not \
|
||||
{'i1'}.issubset(flavor.flavor.options.keys()):
|
||||
name += 'upi2'
|
||||
if {'i2', 'tp'}.issubset(flavor.flavor.options.keys()) and not \
|
||||
{'i1'}.issubset(flavor.flavor.options.keys()):
|
||||
name += 'tpi2'
|
||||
if {'i2'}.issubset(flavor.flavor.options.keys()) and \
|
||||
v_option in valid_vnf_opts and not \
|
||||
{'i1'}.issubset(flavor.flavor.options.keys()):
|
||||
name += 'i2'
|
||||
|
||||
return name
|
||||
|
||||
|
||||
|
@ -13,7 +13,7 @@ create table if not exists flavor
|
||||
name varchar(250) not null,
|
||||
alias varchar(64) null,
|
||||
description varchar(100) not null,
|
||||
series enum('ns', 'nd', 'nv', 'gv', 'ss') not null,
|
||||
series enum('p1') not null,
|
||||
ram integer not null,
|
||||
vcpus integer not null,
|
||||
disk integer not null,
|
||||
|
@ -123,10 +123,16 @@ def _notify(ord_url,
|
||||
try:
|
||||
# Added the header to support the older version of requests
|
||||
headers = {'Content-Type': 'application/json'}
|
||||
response = requests.post('%s/v1/ord/ord_notifier' % (ord_url,),
|
||||
data=json.dumps(data_to_send),
|
||||
headers=headers,
|
||||
cert=conf.ordupdate.cert_path)
|
||||
if not conf.ordupdate.cert_path:
|
||||
response = requests.post('%s/v1/ord/ord_notifier' % (ord_url,),
|
||||
data=json.dumps(data_to_send),
|
||||
headers=headers,
|
||||
verify=conf.verify)
|
||||
else:
|
||||
response = requests.post('%s/v1/ord/ord_notifier' % (ord_url,),
|
||||
data=json.dumps(data_to_send),
|
||||
headers=headers,
|
||||
cert=conf.ordupdate.cert_path)
|
||||
except requests.exceptions.SSLError:
|
||||
logger.debug('Received an SSL error (is the certificate valid?)')
|
||||
raise
|
||||
|
@ -55,65 +55,36 @@ database = {
|
||||
'host': 'localhost',
|
||||
'username': 'root',
|
||||
'password': 'xxxxxxxxxxx',
|
||||
'db_name': 'orm_fms_db',
|
||||
'db_name': 'orm',
|
||||
|
||||
}
|
||||
|
||||
flavor_series = {
|
||||
'valid_series': [
|
||||
'p1'
|
||||
]
|
||||
}
|
||||
|
||||
# valid_flavor_options
|
||||
flavor_options = {
|
||||
'valid_cpin_opt_values': [
|
||||
'c2', 'c4'
|
||||
],
|
||||
'valid_stor_opt_values': [
|
||||
's1', 's2'
|
||||
],
|
||||
'valid_vnf_opt_values': [
|
||||
'v1', 'v2', 'v3', 'v4', 'v5', 'v6', 'v7'
|
||||
],
|
||||
'valid_numa_values': ['n0'],
|
||||
'valid_nd_vnf_values': ['v8'],
|
||||
'valid_ss_vnf_values': ['v3']
|
||||
|
||||
'valid_p1_numa_value': 'n0',
|
||||
'valid_p1_opt_values': [
|
||||
'n0', 'i2'
|
||||
]
|
||||
}
|
||||
|
||||
# this table is for calculating default extra specs needed
|
||||
extra_spec_needed_table = {
|
||||
"ns": {
|
||||
"aggregate_instance_extra_specs____ns": "true",
|
||||
"p1": {
|
||||
"aggregate_instance_extra_specs____p1": "true",
|
||||
"hw____mem_page_size": "large"
|
||||
},
|
||||
"nd": {
|
||||
"aggregate_instance_extra_specs____nd": "true",
|
||||
"aggregate_instance_extra_specs____v8": "true",
|
||||
"hw____mem_page_size": "large"
|
||||
},
|
||||
"nv": {
|
||||
"aggregate_instance_extra_specs____nv": "true",
|
||||
"hw____mem_page_size": "large"
|
||||
},
|
||||
"gv": {
|
||||
"aggregate_instance_extra_specs____gv": "true",
|
||||
"aggregate_instance_extra_specs____c2": "true"
|
||||
},
|
||||
"ss": {
|
||||
"aggregate_instance_extra_specs____ss": "true",
|
||||
"aggregate_instance_extra_specs____s1": "true",
|
||||
"aggregate_instance_extra_specs____v3": "true"
|
||||
}
|
||||
}
|
||||
|
||||
# any key will be added to extra_spec_needed_table need to be added here
|
||||
default_extra_spec_calculated_table = {
|
||||
"aggregate_instance_extra_specs____ns": "",
|
||||
"aggregate_instance_extra_specs____nd": "",
|
||||
"aggregate_instance_extra_specs____nv": "",
|
||||
"aggregate_instance_extra_specs____gv": "",
|
||||
"aggregate_instance_extra_specs____ss": "",
|
||||
"aggregate_instance_extra_specs____c2": "",
|
||||
"aggregate_instance_extra_specs____c4": "",
|
||||
"aggregate_instance_extra_specs____v": "",
|
||||
"aggregate_instance_extra_specs____s1": "",
|
||||
"aggregate_instance_extra_specs____v3": "",
|
||||
"aggregate_instance_extra_specs____v8": "",
|
||||
"aggregate_instance_extra_specs____p1": "",
|
||||
"hw____mem_page_size": "",
|
||||
"hw____cpu_policy": "",
|
||||
"hw____numa_nodes": ""
|
||||
@ -158,15 +129,20 @@ authentication = {
|
||||
}
|
||||
|
||||
flavor_limits = {
|
||||
# All flavor limits will be converted to integers, and must not
|
||||
# have any non-numeric values.
|
||||
# Root disk, block storage and object storage don't have limits
|
||||
# in ORM, but may be limited via SSP
|
||||
"vcpu_limit": "64",
|
||||
# vram_limit is in MB and must be a multiple of 1024
|
||||
"vram_limit": "393216",
|
||||
# swap_file_limit is in MB and must be a multiple of 1024
|
||||
"swap_file_limit": "393216",
|
||||
# ephemeral_limit is in GB
|
||||
"ephemeral_limit": "10000",
|
||||
# All flavor limits will be converted to integers, and must not be non-numeric.
|
||||
# Root disk, block storage and object storage don't have set limits
|
||||
# vcpu_limit and ephemeral_limit values are in GB
|
||||
# vram_limit and swap_file_limit values are in MB and must be a multiple of 1024
|
||||
|
||||
"swap_file_limit": "327680",
|
||||
"ephemeral_limit": "2000",
|
||||
|
||||
# for 'p1' series:
|
||||
# vcpu_limit and vram_limit for 'p1' series with "n0":"true" option
|
||||
"p1_n0_vcpu_limit": "80",
|
||||
"p1_n0_vram_limit": "327680",
|
||||
# vcpu_limit and vram_limit for 'p1' series with "n0":"false" option
|
||||
"p1_nx_vcpu_limit": "40",
|
||||
"p1_nx_vram_limit": "163840"
|
||||
|
||||
}
|
||||
|
@ -57,17 +57,16 @@ class TestFlavorLogic(FunctionalTest):
|
||||
error = 31
|
||||
injector.override_injected_dependency(
|
||||
('rds_proxy', get_rds_proxy_mock()))
|
||||
|
||||
res_flavor = flavor_logic.create_flavor(get_flavor_mock(), 'uuid',
|
||||
'transaction')
|
||||
self.assertEqual(res_flavor.flavor.profile, 'N1')
|
||||
self.assertEqual(res_flavor.flavor.ram, '1024')
|
||||
self.assertEqual(res_flavor.flavor.vcpus, '1')
|
||||
self.assertEqual(res_flavor.flavor.series, 'ss')
|
||||
self.assertEqual(res_flavor.flavor.series, 'p1')
|
||||
self.assertEqual(res_flavor.flavor.id, 'g')
|
||||
|
||||
flavor = get_flavor_mock()
|
||||
flavor.flavor.ephemeral = ''
|
||||
flavor.flavor.swap = '1024000'
|
||||
self.assertRaises(flavor_logic.ErrorStatus, flavor_logic.create_flavor,
|
||||
flavor, 'uuid', 'transaction')
|
||||
|
||||
@ -76,8 +75,8 @@ class TestFlavorLogic(FunctionalTest):
|
||||
'transaction')
|
||||
self.assertEqual(res_flavor.flavor.profile, 'N1')
|
||||
self.assertEqual(res_flavor.flavor.ram, '1024')
|
||||
self.assertEqual(res_flavor.flavor.vcpus, '1')
|
||||
self.assertEqual(res_flavor.flavor.series, 'ss')
|
||||
self.assertEqual(res_flavor .flavor.vcpus, '1')
|
||||
self.assertEqual(res_flavor.flavor.series, 'p1')
|
||||
self.assertEqual(res_flavor.flavor.id, 'g')
|
||||
|
||||
#
|
||||
@ -720,7 +719,7 @@ def get_rds_proxy_mock():
|
||||
|
||||
def get_flavor_mock():
|
||||
flavor_mock = FlavorWrapper()
|
||||
flavor_mock.flavor = Flavor(ram='1024', vcpus='1', series='ss', id='g')
|
||||
flavor_mock.flavor = Flavor(ram='1024', vcpus='1', series='p1', id='g')
|
||||
flavor_mock.flavor.profile = 'N1'
|
||||
|
||||
return flavor_mock
|
||||
|
@ -6,6 +6,7 @@ from orm.tests.unit.fms import FunctionalTest
|
||||
|
||||
class TestWsmeModels(FunctionalTest):
|
||||
def test_flavor_wrapper_from_db_model(self):
|
||||
|
||||
sql_flavor = db_models.Flavor()
|
||||
sql_flavor.description = 'desc'
|
||||
sql_flavor.disk = 1
|
||||
@ -25,7 +26,7 @@ class TestWsmeModels(FunctionalTest):
|
||||
sql_flavor.ram = 1
|
||||
sql_flavor.visibility = 'visibility'
|
||||
sql_flavor.vcpus = 1
|
||||
sql_flavor.series = "gv"
|
||||
sql_flavor.series = "p1"
|
||||
sql_flavor.swap = 1
|
||||
sql_flavor.disk = 1
|
||||
sql_flavor.name = 'name'
|
||||
@ -57,7 +58,7 @@ class TestWsmeModels(FunctionalTest):
|
||||
flavor_wrapper.flavor.swap = '1'
|
||||
flavor_wrapper.flavor.disk = '1'
|
||||
flavor_wrapper.flavor.name = 'name'
|
||||
flavor_wrapper.flavor.series = 'ns'
|
||||
flavor_wrapper.flavor.series = 'p1'
|
||||
|
||||
sql_flavor = flavor_wrapper.to_db_model()
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user