Add flavor series p1

Add  some changes for ord-notifier.
Also clean up unnecessary code.

Change-Id: I60fb157a8159fa1e30f2effb99cb9273d09a9ddd
This commit is contained in:
stewie925 2018-11-16 14:57:38 -08:00
parent 91bb6db686
commit 4ec114add6
10 changed files with 196 additions and 260 deletions

View File

@ -14,14 +14,20 @@ use_handlers = 'console,logfile'
[keystone_authtoken] [keystone_authtoken]
username = 'admin' username = 'admin'
password = 'password' password = 'password'
user_role= 'admin' # project_name defaults to 'admin' - change as needed
project_name = 'admin' # project_name = ''
region = 'RegionOne' # user_role defaults to 'admin' - change as needed
project_domain_name = 'default' # user_role= ''
user_domain_name = 'default' # region defaults to 'RegionOne' - change as needed
# Ranger shall be using keystone v3 by default # region = ''
auth_version = 'v3' # project_domain_name defaults to 'default' - change as needed
auth_enabled = False # 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] [database]
connection = 'mysql://user:pass@localhost:3306/orm' connection = 'mysql://user:pass@localhost:3306/orm'

View File

@ -33,38 +33,15 @@ database = {
# this table is for calculating default extra specs needed # this table is for calculating default extra specs needed
extra_spec_needed_table = { extra_spec_needed_table = {
"ns": { "p1": {
"aggregate_instance_extra_specs____ns": "true", "aggregate_instance_extra_specs____p1": "true",
"hw____mem_page_size": "large" "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 # any key will be added to extra_spec_needed_table need to be added here
default_extra_spec_calculated_table = { default_extra_spec_calculated_table = {
"aggregate_instance_extra_specs____ns": "", "aggregate_instance_extra_specs____p1": "",
"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": "",
"hw____mem_page_size": "", "hw____mem_page_size": "",
"hw____cpu_policy": "", "hw____cpu_policy": "",
"hw____numa_nodes": "" "hw____numa_nodes": ""
@ -95,33 +72,37 @@ api = {
} }
flavor_series = {
'valid_series': [
'p1'
]
}
# valid_flavor_options # valid_flavor_options
flavor_options = { flavor_options = {
'valid_cpin_opt_values': [ 'valid_p1_numa_value': 'n0',
'c2', 'c4' 'valid_p1_opt_values': [
], 'n0', 'i2'
'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']
} }
flavor_limits = { flavor_limits = {
# All flavor limits will be converted to integers, and must not # All flavor limits will be converted to integers, and must not be non-numeric.
# have any non-numeric values. # Root disk, block storage and object storage don't have set limits
# Root disk, block storage and object storage don't have limits # vcpu_limit and ephemeral_limit values are in GB
"vcpu_limit": "64", # vram_limit and swap_file_limit values are in MB and must be a multiple of 1024
# vram_limit is in MB and must be a multiple of 1024
"vram_limit": "393216", "swap_file_limit": "327680",
# swap_file_limit is in MB and must be a multiple of 1024 "ephemeral_limit": "2000",
"swap_file_limit": "393216",
# ephemeral_limit is in GB # for 'p1' series:
"ephemeral_limit": "10000" # 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 verify = config.CONF.ssl_verify

View File

@ -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 orm.services.flavor_manager.fms_rest.logic.error_base import ErrorStatus
from oslo_db.sqlalchemy import models from oslo_db.sqlalchemy import models
from pecan import conf
from sqlalchemy import BigInteger, Column, ForeignKey, Integer, String from sqlalchemy import BigInteger, Column, ForeignKey, Integer, String
from sqlalchemy.ext.declarative import declarative_base from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import relationship, validates from sqlalchemy.orm import relationship, validates
@ -123,8 +124,10 @@ class Flavor(Base, FMSBaseModel):
@validates("series") @validates("series")
def validate_series(self, key, series): def validate_series(self, key, series):
if series not in ['ns', 'nd', 'nv', 'gv', 'ss']: valid_flvr_series = conf.flavor_series.valid_series
raise ValueError("Series must be one of: 'ns' 'nd' 'nv' 'gv' 'ss'") if series not in valid_flvr_series:
raise ValueError("Series must be one of {}:".format(str(valid_flvr_series)))
return series return series
def add_region(self, flavor_region): def add_region(self, flavor_region):

View File

@ -217,7 +217,7 @@ class Flavor(Model):
self.vcpus = vcpus self.vcpus = vcpus
self.disk = disk self.disk = disk
self.swap = swap self.swap = swap
self.ephemeral = "0" if not ephemeral else ephemeral self.ephemeral = ephemeral
self.extra_specs = extra_specs self.extra_specs = extra_specs
self.tag = tag self.tag = tag
self.options = options self.options = options
@ -227,14 +227,44 @@ class Flavor(Model):
self.status = status self.status = status
def validate_model(self, context=None): def validate_model(self, context=None):
bundle = ['b1', 'b2'] bundle = ['b1', 'b2']
numa = ['n0', 'n1'] numa = ['n0']
vlan = ['v1', 'v2', 'v3', 'v4', 'v5', 'v6'] vlan = ['v1', 'v2', 'v3', 'v4', 'v5', 'v6']
vcpu_limit = int(conf.flavor_limits.vcpu_limit)
vram_limit = int(conf.flavor_limits.vram_limit) # validate that input entries are valid
swap_file_limit = int(conf.flavor_limits.swap_file_limit)
ephemeral_limit = int(conf.flavor_limits.ephemeral_limit)
try: 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) isValid = validate_description(self.description)
if not isValid: if not isValid:
raise ErrorStatus(400, "Flavor description does not allow special characters :" 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") raise ErrorStatus(400, "disk must be a number")
if not self.swap.isdigit(): if not self.swap.isdigit():
raise ErrorStatus(400, "swap must be a number") 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") 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): if int(self.ram) not in range(1024, vram_limit + 1, 1024):
raise ErrorStatus(400, raise ErrorStatus(400,
"ram value is out of range. Expected range is 1024(1GB)-" "ram value is out of range. Expected range is 1024(1GB)-"
@ -264,9 +289,13 @@ class Flavor(Model):
"%2d" % (vcpu_limit)) "%2d" % (vcpu_limit))
if int(self.disk) < 0: if int(self.disk) < 0:
raise ErrorStatus(400, "disk cannot be less than zero") 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-" raise ErrorStatus(400, "ephemeral value is out of range. Expected range is 0-"
"%5d(%2dTB)" % (ephemeral_limit, ephemeral_limit / 1000)) "%5d(%2dTB)" % (ephemeral_limit, ephemeral_limit / 1000))
if int(self.swap) not in range(0, swap_file_limit + 1, 1024): if int(self.swap) not in range(0, swap_file_limit + 1, 1024):
raise ErrorStatus(400, raise ErrorStatus(400,
"swap value is out of range. Expected range is 0-" "swap value is out of range. Expected range is 0-"
@ -274,6 +303,7 @@ class Flavor(Model):
(swap_file_limit, swap_file_limit / 1024)) (swap_file_limit, swap_file_limit / 1024))
except ValueError: except ValueError:
raise ErrorStatus(400, "ram, vcpus, disk, ephemeral and swap must be integers") raise ErrorStatus(400, "ram, vcpus, disk, ephemeral and swap must be integers")
for symbol, value in self.extra_specs.iteritems(): for symbol, value in self.extra_specs.iteritems():
if symbol == 'bundle' and value not in bundle: if symbol == 'bundle' and value not in bundle:
raise ErrorStatus(400, raise ErrorStatus(400,
@ -321,7 +351,7 @@ class Flavor(Model):
for symbol, value in self.options.iteritems(): for symbol, value in self.options.iteritems():
option = db_models.FlavorOption() option = db_models.FlavorOption()
option.key_name = symbol option.key_name = symbol
option.key_value = value option.key_value = value.lower()
options.append(option) options.append(option)
for region in self.regions: for region in self.regions:
@ -408,10 +438,6 @@ class Flavor(Model):
return False return False
def get_extra_spec_needed(self): 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 = [] extra_spec_needed = []
items = conf.extra_spec_needed_table.to_dict() items = conf.extra_spec_needed_table.to_dict()
for symbol, value in items[self.series].iteritems(): for symbol, value in items[self.series].iteritems():
@ -419,19 +445,11 @@ class Flavor(Model):
es.key_name = symbol.replace("____", ":") es.key_name = symbol.replace("____", ":")
es.key_value = value 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) extra_spec_needed.append(es)
options_items = self.options options_items = self.options
# check some keys if they exist in option add values to extra specs # check some keys if they exist in option add values to extra specs
if self.series in ('ns', 'nv', 'nd', 'ss'): if self.series in 'p1':
c2_c4_in = False
n0_in = False n0_in = False
for symbol, value in options_items.iteritems(): for symbol, value in options_items.iteritems():
es = db_models.FlavorExtraSpec() es = db_models.FlavorExtraSpec()
@ -443,69 +461,24 @@ class Flavor(Model):
es.key_value = 2 es.key_value = 2
es.key_name = "hw:numa_nodes" es.key_name = "hw:numa_nodes"
extra_spec_needed.append(es) 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 # add the default extra specs
if not c2_c4_in: es = db_models.FlavorExtraSpec()
es = db_models.FlavorExtraSpec() es.key_name = "hw:cpu_policy"
es.key_name = "hw:cpu_policy" es.key_value = "dedicated"
es.key_value = "dedicated" extra_spec_needed.append(es)
extra_spec_needed.append(es)
if not n0_in: if not n0_in:
es = db_models.FlavorExtraSpec() es = db_models.FlavorExtraSpec()
es.key_value = 1 es.key_value = 1
es.key_name = "hw:numa_nodes" es.key_name = "hw:numa_nodes"
extra_spec_needed.append(es) 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() if self.series in ['p1'] and {'i2'}.issubset(options_items.keys()):
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()):
es = db_models.FlavorExtraSpec() es = db_models.FlavorExtraSpec()
es.key_name = "hw:pci_numa_affinity_policy" es.key_name = "hw:pci_numa_affinity_policy"
es.key_value = "dedicated" es.key_value = "dedicated"
extra_spec_needed.append(es) 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 # convert the key_value to a string to avoid/fix pecan json rendering error in update extra_specs
i = 0 i = 0

View File

@ -25,6 +25,7 @@ def create_flavor(flavor, flavor_uuid, transaction_id):
if not flavor.flavor.ephemeral or flavor.flavor.ephemeral.isspace(): if not flavor.flavor.ephemeral or flavor.flavor.ephemeral.isspace():
flavor.flavor.ephemeral = '0' flavor.flavor.ephemeral = '0'
flavor.flavor.name = calculate_name(flavor) flavor.flavor.name = calculate_name(flavor)
LOG.debug("Flavor name is [{}] ".format(flavor.flavor.name)) LOG.debug("Flavor name is [{}] ".format(flavor.flavor.name))
sql_flavor = flavor.to_db_model() sql_flavor = flavor.to_db_model()
@ -44,9 +45,9 @@ def create_flavor(flavor, flavor_uuid, transaction_id):
return ret_flavor return ret_flavor
except Exception as exp: except Exception as exp:
LOG.log_exception("FlavorLogic - Failed to CreateFlavor", exp) LOG.log_exception("FlavorLogic - Failed to CreateFlavor", str(exp.args))
datamanager.rollback() 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 ConflictError(409, "Flavor {} already exists".format(flavor.flavor.name))
raise raise
finally: finally:
@ -217,7 +218,7 @@ def add_regions(flavor_uuid, regions, transaction_id):
except Exception as exp: except Exception as exp:
LOG.log_exception("FlavorLogic - Failed to add regions", exp) LOG.log_exception("FlavorLogic - Failed to add regions", exp)
datamanager.rollback() 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 ConflictError(409, "One or more regions already exists in Flavor")
raise exp raise exp
finally: finally:
@ -304,7 +305,7 @@ def add_tenants(flavor_uuid, tenants, transaction_id):
except Exception as exp: except Exception as exp:
datamanager.rollback() datamanager.rollback()
LOG.log_exception("FlavorLogic - Failed to add tenants", exp) 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 ConflictError(409, "One or more tenants already exist")
raise raise
finally: finally:
@ -590,7 +591,7 @@ def add_extra_specs(flavor_id, extra_specs, transaction_id):
except Exception as exp: except Exception as exp:
datamanager.rollback() 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)) 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) LOG.log_exception("FlavorLogic - fail to add extra spec", exp)
raise raise
@ -702,7 +703,7 @@ def add_tags(flavor_id, tags, transaction_id):
except Exception as exp: except Exception as exp:
datamanager.rollback() 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( raise ConflictError(409, "one or all tags {} already exists".format(
tags.tags)) tags.tags))
LOG.log_exception("FlavorLogic - fail to add tags", exp) 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): def calculate_name(flavor):
valid_vnf_opts = conf.flavor_options.valid_vnf_opt_values[:] """ calculate_name function returns the ranger flavor_name:
valid_stor_opts = conf.flavor_options.valid_stor_opt_values[:] Ranger flavor name is made up of the following components, each separated by a DOT separator:
valid_cpin_opts = conf.flavor_options.valid_cpin_opt_values[:] - flavor series
valid_numa_opts = conf.flavor_options.valid_numa_values[:] - flavor attributes (cores, ram, disk, swap file, ephemeral disks)
valid_ss_vnf_opts = conf.flavor_options.valid_ss_vnf_values[:] - 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, name = "{0}.c{1}r{2}d{3}".format(flavor.flavor.series, flavor.flavor.vcpus,
int(flavor.flavor.ram) / 1024, int(flavor.flavor.ram) / 1024,
flavor.flavor.disk) flavor.flavor.disk)
series = name[:2] 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) swap = getattr(flavor.flavor, 'swap', 0)
if swap and int(swap): if swap and int(swap):
name += '{}{}'.format('s', int(swap) / 1024) name += '{}{}'.format('s', int(swap) / 1024)
# add ephemeral disk info to flavor name IF provided
ephemeral = getattr(flavor.flavor, 'ephemeral', 0) ephemeral = getattr(flavor.flavor, 'ephemeral', 0)
if ephemeral and int(ephemeral): if ephemeral and int(ephemeral):
name += '{}{}'.format('e', ephemeral) name += '{}{}'.format('e', ephemeral)
# add the valid option keys to the flavor name
if len(flavor.flavor.options) > 0: if len(flavor.flavor.options) > 0:
v_option = "" for key in sorted(flavor.flavor.options):
for key in sorted(flavor.flavor.options.iterkeys()):
if key[0] == 'v':
v_option = key
# only include valid option parameters in flavor name # only include valid option parameters in flavor name
if ((series == 'ns' and key[0] == 'v' and key in valid_vnf_opts) or if series == 'p1' and key in valid_p1_opts and n0_in:
(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 name.count('.') < 2: if name.count('.') < 2:
name += '.' name += '.'
name += key 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 return name

View File

@ -13,7 +13,7 @@ create table if not exists flavor
name varchar(250) not null, name varchar(250) not null,
alias varchar(64) null, alias varchar(64) null,
description varchar(100) not null, description varchar(100) not null,
series enum('ns', 'nd', 'nv', 'gv', 'ss') not null, series enum('p1') not null,
ram integer not null, ram integer not null,
vcpus integer not null, vcpus integer not null,
disk integer not null, disk integer not null,

View File

@ -123,10 +123,16 @@ def _notify(ord_url,
try: try:
# Added the header to support the older version of requests # Added the header to support the older version of requests
headers = {'Content-Type': 'application/json'} headers = {'Content-Type': 'application/json'}
response = requests.post('%s/v1/ord/ord_notifier' % (ord_url,), if not conf.ordupdate.cert_path:
data=json.dumps(data_to_send), response = requests.post('%s/v1/ord/ord_notifier' % (ord_url,),
headers=headers, data=json.dumps(data_to_send),
cert=conf.ordupdate.cert_path) 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: except requests.exceptions.SSLError:
logger.debug('Received an SSL error (is the certificate valid?)') logger.debug('Received an SSL error (is the certificate valid?)')
raise raise

View File

@ -55,65 +55,36 @@ database = {
'host': 'localhost', 'host': 'localhost',
'username': 'root', 'username': 'root',
'password': 'xxxxxxxxxxx', 'password': 'xxxxxxxxxxx',
'db_name': 'orm_fms_db', 'db_name': 'orm',
} }
flavor_series = {
'valid_series': [
'p1'
]
}
# valid_flavor_options # valid_flavor_options
flavor_options = { flavor_options = {
'valid_cpin_opt_values': [
'c2', 'c4' 'valid_p1_numa_value': 'n0',
], 'valid_p1_opt_values': [
'valid_stor_opt_values': [ 'n0', 'i2'
'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']
} }
# this table is for calculating default extra specs needed # this table is for calculating default extra specs needed
extra_spec_needed_table = { extra_spec_needed_table = {
"ns": { "p1": {
"aggregate_instance_extra_specs____ns": "true", "aggregate_instance_extra_specs____p1": "true",
"hw____mem_page_size": "large" "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 # any key will be added to extra_spec_needed_table need to be added here
default_extra_spec_calculated_table = { default_extra_spec_calculated_table = {
"aggregate_instance_extra_specs____ns": "", "aggregate_instance_extra_specs____p1": "",
"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": "",
"hw____mem_page_size": "", "hw____mem_page_size": "",
"hw____cpu_policy": "", "hw____cpu_policy": "",
"hw____numa_nodes": "" "hw____numa_nodes": ""
@ -158,15 +129,20 @@ authentication = {
} }
flavor_limits = { flavor_limits = {
# All flavor limits will be converted to integers, and must not # All flavor limits will be converted to integers, and must not be non-numeric.
# have any non-numeric values. # Root disk, block storage and object storage don't have set limits
# Root disk, block storage and object storage don't have limits # vcpu_limit and ephemeral_limit values are in GB
# in ORM, but may be limited via SSP # vram_limit and swap_file_limit values are in MB and must be a multiple of 1024
"vcpu_limit": "64",
# vram_limit is in MB and must be a multiple of 1024 "swap_file_limit": "327680",
"vram_limit": "393216", "ephemeral_limit": "2000",
# swap_file_limit is in MB and must be a multiple of 1024
"swap_file_limit": "393216", # for 'p1' series:
# ephemeral_limit is in GB # vcpu_limit and vram_limit for 'p1' series with "n0":"true" option
"ephemeral_limit": "10000", "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"
} }

View File

@ -57,17 +57,16 @@ class TestFlavorLogic(FunctionalTest):
error = 31 error = 31
injector.override_injected_dependency( injector.override_injected_dependency(
('rds_proxy', get_rds_proxy_mock())) ('rds_proxy', get_rds_proxy_mock()))
res_flavor = flavor_logic.create_flavor(get_flavor_mock(), 'uuid', res_flavor = flavor_logic.create_flavor(get_flavor_mock(), 'uuid',
'transaction') 'transaction')
self.assertEqual(res_flavor.flavor.profile, 'N1') self.assertEqual(res_flavor.flavor.profile, 'N1')
self.assertEqual(res_flavor.flavor.ram, '1024') self.assertEqual(res_flavor.flavor.ram, '1024')
self.assertEqual(res_flavor.flavor.vcpus, '1') 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') self.assertEqual(res_flavor.flavor.id, 'g')
flavor = get_flavor_mock() flavor = get_flavor_mock()
flavor.flavor.ephemeral = '' flavor.flavor.swap = '1024000'
self.assertRaises(flavor_logic.ErrorStatus, flavor_logic.create_flavor, self.assertRaises(flavor_logic.ErrorStatus, flavor_logic.create_flavor,
flavor, 'uuid', 'transaction') flavor, 'uuid', 'transaction')
@ -76,8 +75,8 @@ class TestFlavorLogic(FunctionalTest):
'transaction') 'transaction')
self.assertEqual(res_flavor.flavor.profile, 'N1') self.assertEqual(res_flavor.flavor.profile, 'N1')
self.assertEqual(res_flavor.flavor.ram, '1024') self.assertEqual(res_flavor.flavor.ram, '1024')
self.assertEqual(res_flavor.flavor.vcpus, '1') 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') self.assertEqual(res_flavor.flavor.id, 'g')
# #
@ -720,7 +719,7 @@ def get_rds_proxy_mock():
def get_flavor_mock(): def get_flavor_mock():
flavor_mock = FlavorWrapper() 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' flavor_mock.flavor.profile = 'N1'
return flavor_mock return flavor_mock

View File

@ -6,6 +6,7 @@ from orm.tests.unit.fms import FunctionalTest
class TestWsmeModels(FunctionalTest): class TestWsmeModels(FunctionalTest):
def test_flavor_wrapper_from_db_model(self): def test_flavor_wrapper_from_db_model(self):
sql_flavor = db_models.Flavor() sql_flavor = db_models.Flavor()
sql_flavor.description = 'desc' sql_flavor.description = 'desc'
sql_flavor.disk = 1 sql_flavor.disk = 1
@ -25,7 +26,7 @@ class TestWsmeModels(FunctionalTest):
sql_flavor.ram = 1 sql_flavor.ram = 1
sql_flavor.visibility = 'visibility' sql_flavor.visibility = 'visibility'
sql_flavor.vcpus = 1 sql_flavor.vcpus = 1
sql_flavor.series = "gv" sql_flavor.series = "p1"
sql_flavor.swap = 1 sql_flavor.swap = 1
sql_flavor.disk = 1 sql_flavor.disk = 1
sql_flavor.name = 'name' sql_flavor.name = 'name'
@ -57,7 +58,7 @@ class TestWsmeModels(FunctionalTest):
flavor_wrapper.flavor.swap = '1' flavor_wrapper.flavor.swap = '1'
flavor_wrapper.flavor.disk = '1' flavor_wrapper.flavor.disk = '1'
flavor_wrapper.flavor.name = 'name' flavor_wrapper.flavor.name = 'name'
flavor_wrapper.flavor.series = 'ns' flavor_wrapper.flavor.series = 'p1'
sql_flavor = flavor_wrapper.to_db_model() sql_flavor = flavor_wrapper.to_db_model()