ranger/orm/services/flavor_manager/fms_rest/logic/flavor_logic.py

1034 lines
35 KiB
Python
Executable File

from orm.services.flavor_manager.fms_rest.data.sql_alchemy.db_models import (
FlavorRegion, FlavorTenant)
from orm.services.flavor_manager.fms_rest.data.wsme.models import (
ExtraSpecsWrapper,
FlavorListFullResponse, FlavorWrapper,
Region, RegionWrapper, TagsWrapper,
TenantWrapper)
from orm.services.flavor_manager.fms_rest.logger import get_logger
from orm.services.flavor_manager.fms_rest.logic.error_base import (
ConflictError, ErrorStatus, NotFoundError)
from orm.common.orm_common.injector import injector
from orm.common.orm_common.utils import utils
from oslo_config import cfg
import oslo_db
LOG = get_logger(__name__)
di = injector.get_di()
def validate_tenants_regions_list(requested_tenants, requested_regions,
action, datamanager):
regions_list, tenants_list = [], []
results = datamanager.get_valid_tenant_region_list(requested_tenants,
requested_regions)
valid_tenants_list, valid_regions_list = [], []
if results:
# the first element in the results tuple is the tenant prep
# result_tenant_list from result_rows and remove NoneTypes from list
result_tenant_list = [x[0] for x in results]
result_tenant_list = filter(None, result_tenant_list)
# lastly clean up valid_tenants_list list by removing duplicate items
valid_tenants_list = list(dict.fromkeys(result_tenant_list))
# second element in the results tuple is the region - compile the
# region data into valid_regions_list and eliminate duplicates
# from the list
valid_regions_list = [x[1] for x in results]
valid_regions_list = list(dict.fromkeys(valid_regions_list))
return valid_tenants_list, valid_regions_list
@di.dependsOn('data_manager')
def create_flavor(flavor, flavor_uuid, transaction_id):
DataManager = di.resolver.unpack(create_flavor)
datamanager = DataManager()
try:
flavor.flavor.handle_region_groups()
flavor.flavor.validate_model("create")
flavor.flavor.id = flavor_uuid
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))
flavor_regions = []
for region in flavor.flavor.regions:
flavor_regions.append(region.name)
# Execute the following logic only if at least one region AND one
# tenant are provided in a private flavor:
# Validate which tenants from the original tenants list to
# be assigned to the private flavor; if no valid tenants
# found, the valid_tenants_list will return empty list
if (flavor_regions and flavor.flavor.visibility == 'private' and
flavor.flavor.tenants):
valid_tenants_list, valid_regions_list = \
validate_tenants_regions_list(flavor.flavor.tenants,
flavor_regions,
'create', datamanager)
# replace the original tenant list in the private flavor
# with the valid_tenants_list
flavor.flavor.tenants = valid_tenants_list
sql_flavor = flavor.to_db_model()
flavor_rec = datamanager.get_record('flavor')
datamanager.begin_transaction()
flavor_rec.insert(sql_flavor)
datamanager.flush() # Get any exception created by this insert
existing_region_names = []
send_to_rds_if_needed(
sql_flavor, existing_region_names, "post", transaction_id)
datamanager.commit()
ret_flavor = get_flavor_by_uuid(flavor_uuid)
return ret_flavor
except oslo_db.exception.DBDuplicateEntry as exception:
raise ErrorStatus(
409.2, "Flavor name '{}' already exists".format(
flavor.flavor.name))
except Exception as exp:
LOG.log_exception("FlavorLogic - Failed to CreateFlavor",
str(exp))
datamanager.rollback()
if "Duplicate entry" in str(exp):
raise ConflictError(
409,
"Flavor {} already exists".format(flavor.flavor.name))
raise
finally:
datamanager.close()
@di.dependsOn('rds_proxy')
def send_to_rds_if_needed(sql_flavor,
existing_region_names,
http_action,
transaction_id):
rds_proxy = di.resolver.unpack(send_to_rds_if_needed)
if (sql_flavor.flavor_regions and len(sql_flavor.flavor_regions) > 0) \
or len(existing_region_names) > 0:
flavor_dict = sql_flavor.todict()
update_region_actions(flavor_dict, existing_region_names, http_action)
LOG.debug("Flavor is valid to send to RDS - sending to RDS Proxy ")
rds_proxy.send_flavor(flavor_dict, transaction_id, http_action)
else:
LOG.debug("Flavor with no regions - wasn't sent to RDS Proxy " +
str(sql_flavor))
@di.dependsOn('data_manager')
def update_flavor(flavor, flavor_uuid, transaction_id): # pragma: no cover
DataManager = di.resolver.unpack(update_flavor)
datamanager = DataManager()
try:
flavor.validate_model("update")
sql_flavor = flavor.to_db_model()
sql_flavor.id = flavor_uuid
sql_flavor.name = calculate_name(flavor)
LOG.debug("Flavor name is [{}] ".format(sql_flavor.name))
datamanager.begin_transaction()
flavor_rec = datamanager.get_record('flavor')
db_flavor = flavor_rec.get_flavor_by_id(flavor_uuid)
if db_flavor is None:
raise Exception("Flavor {0} not found".format(flavor_uuid))
existing_region_names = db_flavor.get_existing_region_names()
flavor_rec.delete_by_uuid(flavor_uuid)
del(db_flavor)
flavor_rec.insert(sql_flavor)
# get any exception created by this insert method
datamanager.flush()
send_to_rds_if_needed(
sql_flavor, existing_region_names, "put", transaction_id)
datamanager.commit()
ret_flavor = get_flavor_by_uuid(flavor_uuid)
return ret_flavor
except Exception as exp:
LOG.log_exception("FlavorLogic - Failed to update flavor", str(exp))
datamanager.rollback()
raise
finally:
datamanager.close()
@di.dependsOn('data_manager')
def delete_flavor_by_uuid(flavor_uuid): # , transaction_id):
DataManager = di.resolver.unpack(delete_flavor_by_uuid)
datamanager = DataManager()
try:
datamanager.begin_transaction()
flavor_rec = datamanager.get_record('flavor')
sql_flavor = flavor_rec.get_flavor_by_id(flavor_uuid)
if sql_flavor is None:
raise NotFoundError(
message="Flavor '{}' not found".format(flavor_uuid))
existing_region_names = sql_flavor.get_existing_region_names()
if len(existing_region_names) > 0:
# Do not delete a flavor that still has some regions
msg = "Cannot delete a flavor that has regions. " \
"Please delete the regions first and then " \
"delete the flavor."
LOG.info(msg)
raise ErrorStatus(405, msg)
else:
expected_status = 'Success'
# Get status from resource status table
uuid = [sql_flavor.id]
resource_status_dict = utils.get_resource_status_from_db(
datamanager.get_session(), uuid)
status_model = resource_status_dict.get(sql_flavor.id)
if status_model:
status = status_model.status
LOG.debug(
'Status from resource_status table: {}'.format(status))
else:
# Flavor not found in table, that means it never had any
# regions. So it is OK to delete it
status = expected_status
LOG.debug('Resource not found in table, so it is OK to delete')
if status != expected_status:
msg = "The flavor has not been deleted " \
"successfully from all of its regions " \
"(either the deletion failed on one of the " \
"regions or it is still in progress)"
LOG.error('Invalid flavor status received from RDS')
raise ErrorStatus(409, msg)
# OK to delete
flavor_rec.delete_by_uuid(flavor_uuid)
# get any exception created by this delete
datamanager.flush()
datamanager.commit()
except Exception as exp:
LOG.log_exception("FlavorLogic - Failed to delete flavor", str(exp))
datamanager.rollback()
raise
finally:
datamanager.close()
@di.dependsOn('data_manager')
def add_regions(flavor_uuid, regions, transaction_id):
DataManager = di.resolver.unpack(add_regions)
datamanager = DataManager()
try:
flavor_rec = datamanager.get_record('flavor')
sql_flavor = flavor_rec.get_flavor_by_id(flavor_uuid)
if not sql_flavor:
raise ErrorStatus(404,
'flavor id {0} not found'.format(flavor_uuid))
existing_region_names = sql_flavor.get_existing_region_names()
flvr_tenant_list, flvr_region_list = [], []
for region in regions.regions:
if region.name == '' or region.name.isspace():
raise ErrorStatus(400, 'Cannot add region with an empty name')
if region.type == "group":
raise ErrorStatus(400,
"Adding \'group\' type region is supported"
" only when creating a flavor")
db_region = FlavorRegion(region_name=region.name,
region_type='single')
sql_flavor.add_region(db_region)
flvr_region_list.append(region.name)
# get any exception created by previous actions against the database
datamanager.flush()
# private flavor new logic
# validate tenants assigned to the flavor
for tenant in sql_flavor.flavor_tenants:
flvr_tenant_list.append(tenant.tenant_id)
valid_tenants_list, valid_regions_list = \
validate_tenants_regions_list(flvr_tenant_list,
flvr_region_list,
'create', datamanager)
# update tenant list
for tenant in flvr_tenant_list:
if tenant not in valid_tenants_list:
sql_flavor.remove_tenant(tenant)
send_to_rds_if_needed(
sql_flavor, existing_region_names, "put", transaction_id)
datamanager.commit()
flavor = get_flavor_by_uuid(flavor_uuid)
ret = RegionWrapper(regions=flavor.flavor.regions)
return ret
except ErrorStatus as exp:
LOG.log_exception("FlavorLogic - Failed to update flavor", str(exp))
datamanager.rollback()
raise exp
except Exception as exp:
LOG.log_exception("FlavorLogic - Failed to add regions", str(exp))
datamanager.rollback()
if "conflicts with persistent instance" in str(exp):
raise ConflictError(409,
"One or more regions already exists in Flavor")
raise exp
finally:
datamanager.close()
@di.dependsOn('data_manager')
def delete_region(flavor_uuid, region_name, transaction_id, force_delete):
DataManager = di.resolver.unpack(delete_region)
datamanager = DataManager()
try:
flavor_rec = datamanager.get_record('flavor')
sql_flavor = flavor_rec.get_flavor_by_id(flavor_uuid)
if not sql_flavor:
raise ErrorStatus(404,
'flavor id {0} not found'.format(flavor_uuid))
existing_region_names = sql_flavor.get_existing_region_names()
sql_flavor.remove_region(region_name)
# get any exception created by previous actions against the database
datamanager.flush()
send_to_rds_if_needed(sql_flavor, existing_region_names, "put",
transaction_id)
if force_delete:
datamanager.commit()
else:
datamanager.rollback()
except ErrorStatus as exp:
LOG.log_exception("FlavorLogic - Failed to update flavor", str(exp))
datamanager.rollback()
raise exp
except Exception as exp:
LOG.log_exception("FlavorLogic - Failed to delete region", str(exp))
datamanager.rollback()
raise exp
finally:
datamanager.close()
@di.dependsOn('data_manager')
def add_tenants(flavor_uuid, tenants, transaction_id):
DataManager = di.resolver.unpack(add_tenants)
datamanager = DataManager()
valid_tenants_list, valid_regions_list = [], []
try:
flavor_rec = datamanager.get_record('flavor')
sql_flavor = flavor_rec.get_flavor_by_id(flavor_uuid)
if not sql_flavor:
raise ErrorStatus(404,
'Flavor id {0} not found'.format(flavor_uuid))
if sql_flavor.visibility == "public":
raise ErrorStatus(405, 'Cannot add tenant to a public flavor')
existing_region_names = sql_flavor.get_existing_region_names()
existing_region_list = []
for x in existing_region_names:
existing_region_list.append(x)
if tenants.tenants:
valid_tenants_list, valid_regions_list = \
validate_tenants_regions_list(tenants.tenants,
existing_region_list,
'create', datamanager)
if not valid_tenants_list:
raise ValueError("At least one valid tenant must be provided")
for tenant in valid_tenants_list:
if not isinstance(tenant, str):
raise ValueError("tenant type must be a string type,"
" got {} type".format(type(tenant)))
db_tenant = FlavorTenant(tenant_id=tenant)
sql_flavor.add_tenant(db_tenant)
# get any exception created by previous actions against the database
datamanager.flush()
send_to_rds_if_needed(
sql_flavor, existing_region_names, "put", transaction_id)
datamanager.commit()
flavor = get_flavor_by_uuid(flavor_uuid)
ret = TenantWrapper(tenants=flavor.flavor.tenants)
return ret
except (ErrorStatus, ValueError) as exp:
LOG.log_exception("FlavorLogic - Failed to update flavor", str(exp))
datamanager.rollback()
raise
except Exception as exp:
datamanager.rollback()
LOG.log_exception("FlavorLogic - Failed to add tenants", str(exp))
if "conflicts with persistent instance" in str(exp):
raise ConflictError(409, "One or more tenants already exist")
raise
finally:
datamanager.close()
@di.dependsOn('data_manager')
def delete_tenant(flavor_uuid, tenant_id, transaction_id):
DataManager = di.resolver.unpack(delete_tenant)
datamanager = DataManager()
try:
flavor_rec = datamanager.get_record('flavor')
sql_flavor = flavor_rec.get_flavor_by_id(flavor_uuid)
if not sql_flavor:
raise ErrorStatus(404,
'flavor id {0} not found'.format(flavor_uuid))
# if trying to delete the only one tenant then return value error
if sql_flavor.visibility == "public":
raise ValueError("{} is a public flavor, delete tenant"
" action is not relevant".format(flavor_uuid))
existing_region_names = sql_flavor.get_existing_region_names()
sql_flavor.remove_tenant(tenant_id)
# get any exception created by previous actions against the database
datamanager.flush()
send_to_rds_if_needed(
sql_flavor, existing_region_names, "put", transaction_id)
datamanager.commit()
except NotFoundError as exp:
datamanager.rollback()
LOG.log_exception("FlavorLogic - Flavor not found", str(exp))
raise
except ErrorStatus as exp:
datamanager.rollback()
if exp.status_code == 404:
LOG.log_exception("FlavorLogic - Tenant not found", str(exp))
raise
else:
LOG.log_exception(
"FlavorLogic - failed to delete tenant", str(exp))
raise
except Exception as exp:
LOG.log_exception("FlavorLogic - Failed to delete tenant", str(exp))
datamanager.rollback()
raise
finally:
datamanager.close()
def extra_spec_in_default(extra_spec, default_extra_specs):
for default_extra_spec in default_extra_specs:
if extra_spec == default_extra_spec.key_name:
return True
return False
@di.dependsOn('data_manager')
def get_extra_specs_uuid(flavor_id, transaction_id):
DataManager = di.resolver.unpack(get_extra_specs_uuid)
datamanager = DataManager()
try:
LOG.debug("LOGIC - get extra specs")
datamanager.begin_transaction()
flavor_rec = datamanager.get_record("flavor")
sql_flavor = flavor_rec.get_flavor_by_id(flavor_id)
if not sql_flavor:
raise NotFoundError(404, 'flavor id {0} not found'.format(
flavor_id))
result = ExtraSpecsWrapper.from_db_model(sql_flavor.flavor_extra_specs)
except NotFoundError as exp:
datamanager.rollback()
LOG.log_exception("FlavorLogic - Flavor Not Found", str(exp))
raise
except Exception as exp:
datamanager.rollback()
LOG.log_exception("FlavorLogic - Flavor Not Found", str(exp))
raise
finally:
datamanager.close()
return result
@di.dependsOn('data_manager')
def delete_extra_specs(flavor_id, transaction_id, extra_spec=None):
DataManager = di.resolver.unpack(delete_extra_specs)
datamanager = DataManager()
try:
LOG.debug("LOGIC - delete extra specs")
datamanager.begin_transaction()
flavor_rec = datamanager.get_record("flavor")
sql_flavor = flavor_rec.get_flavor_by_id(flavor_id)
if not sql_flavor:
raise NotFoundError(404, 'flavor id {0} not found'.format(
flavor_id))
existing_region_names = sql_flavor.get_existing_region_names()
# calculate default flavor extra
flavor_wrapper = FlavorWrapper.from_db_model(sql_flavor)
default_extra_specs = flavor_wrapper.get_extra_spec_needed()
# check if delete all or one
if extra_spec:
if not extra_spec_in_default(extra_spec, default_extra_specs):
sql_flavor.remove_extra_spec(extra_spec)
else:
raise ErrorStatus(400,
"Bad request, this key cannot be deleted")
else:
sql_flavor.delete_all_extra_specs()
sql_flavor.add_extra_specs(default_extra_specs)
# get any exception created by previous actions against the database
datamanager.flush()
send_to_rds_if_needed(sql_flavor, existing_region_names, "put",
transaction_id)
datamanager.commit()
except NotFoundError as exp:
datamanager.rollback()
LOG.log_exception("FlavorLogic - Flavor not found", str(exp))
raise
except ErrorStatus as exp:
datamanager.rollback()
if exp.status_code == 404:
LOG.log_exception("FlavorLogic - extra specs not found", str(exp))
raise
else:
LOG.log_exception("FlavorLogic - failed to delete extra specs",
str(exp))
raise
except Exception as exp:
datamanager.rollback()
LOG.log_exception("FlavorLogic - fail to delete extra spec", str(exp))
raise
finally:
datamanager.close()
return
@di.dependsOn('data_manager')
def get_tags(flavor_uuid):
DataManager = di.resolver.unpack(get_tags)
datamanager = DataManager()
flavor_record = datamanager.get_record('flavor')
sql_flavor = flavor_record.get_flavor_by_id(flavor_uuid)
if not sql_flavor:
raise ErrorStatus(404, 'flavor id {0} not found'.format(flavor_uuid))
flavor_wrapper = FlavorWrapper.from_db_model(sql_flavor)
datamanager.close()
return flavor_wrapper.flavor.tag
@di.dependsOn('data_manager')
def delete_tags(flavor_id, tag, transaction_id):
DataManager = di.resolver.unpack(delete_tags)
datamanager = DataManager()
try:
LOG.debug("LOGIC - delete tags")
datamanager.begin_transaction()
flavor_rec = datamanager.get_record("flavor")
sql_flavor = flavor_rec.get_flavor_by_id(flavor_id)
if not sql_flavor:
raise NotFoundError(404,
'flavor id {0} not found'.format(flavor_id))
if tag:
sql_flavor.remove_tag(tag)
else:
sql_flavor.remove_all_tags()
datamanager.flush()
datamanager.commit()
except NotFoundError as exp:
datamanager.rollback()
LOG.log_exception("FlavorLogic - Flavor not found", exp)
raise
except ErrorStatus as exp:
if exp.status_code == 404:
LOG.log_exception("FlavorLogic - Tag not found", exp)
raise
else:
LOG.log_exception("FlavorLogic - failed to delete tags", exp)
raise
except Exception as exp:
datamanager.rollback()
LOG.log_exception("FlavorLogic - failed to delete tags", exp)
raise
finally:
datamanager.close()
@di.dependsOn('data_manager')
def update_tags(flavor_id, tags, transaction_id):
DataManager = di.resolver.unpack(update_tags)
datamanager = DataManager()
try:
LOG.debug("LOGIC - update tags")
datamanager.begin_transaction()
flavor_rec = datamanager.get_record("flavor")
sql_flavor = flavor_rec.get_flavor_by_id(flavor_id)
if not sql_flavor:
raise NotFoundError(404, "flavor id {} not found".format(
flavor_id))
tags_models = tags.to_db_model()
sql_flavor.replace_tags(tags_models)
datamanager.flush()
datamanager.commit()
# create return json to wsme
result = TagsWrapper.from_db_model(tags_models)
except NotFoundError as exp:
datamanager.rollback()
LOG.log_exception("flavor id {} not found".format(flavor_id), exp)
raise
except Exception as exp:
datamanager.rollback()
LOG.log_exception("failed to update tags", exp)
raise
finally:
datamanager.close()
return result
@di.dependsOn('data_manager')
def add_extra_specs(flavor_id, extra_specs, transaction_id):
DataManager = di.resolver.unpack(add_extra_specs)
datamanager = DataManager()
try:
LOG.debug("LOGIC - add extra specs")
datamanager.begin_transaction()
flavor_rec = datamanager.get_record("flavor")
sql_flavor = flavor_rec.get_flavor_by_id(flavor_id)
if not sql_flavor:
raise NotFoundError(404, 'flavor id {0} not found'.format(
flavor_id))
existing_region_names = sql_flavor.get_existing_region_names()
extra_specs_model = extra_specs.to_db_model()
sql_flavor.add_extra_specs(extra_specs_model)
# get any exception created by previous actions against the database
datamanager.flush()
send_to_rds_if_needed(sql_flavor, existing_region_names, "put",
transaction_id)
datamanager.commit()
# create return json to wsme
result = ExtraSpecsWrapper.from_db_model(sql_flavor.flavor_extra_specs)
except NotFoundError as exp:
datamanager.rollback()
LOG.log_exception("FlavorLogic - Flavor Not Found", exp)
raise
except Exception as exp:
datamanager.rollback()
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
finally:
datamanager.close()
return result
@di.dependsOn('data_manager')
def update_extra_specs(flavor_id, extra_specs, transaction_id):
DataManager = di.resolver.unpack(update_extra_specs)
datamanager = DataManager()
try:
LOG.debug("LOGIC - update extra specs")
datamanager.begin_transaction()
flavor_rec = datamanager.get_record("flavor")
sql_flavor = flavor_rec.get_flavor_by_id(flavor_id)
if not sql_flavor:
raise NotFoundError(404, "flavor id {} not found".format(
flavor_id))
extra_specs_models = extra_specs.to_db_model()
existing_region_names = sql_flavor.get_existing_region_names()
# remove old extra specs
sql_flavor.delete_all_extra_specs()
# calculate default flavor extra
flavor_wrapper = FlavorWrapper.from_db_model(sql_flavor).to_db_model()
default_extra_specs = flavor_wrapper.flavor_extra_specs
# add default extra specs to user extra specs and add to DB
extra_specs_models += default_extra_specs
sql_flavor.add_extra_specs(extra_specs_models)
# get exception if there is any from previous action with the database
datamanager.flush()
send_to_rds_if_needed(sql_flavor, existing_region_names, "put",
transaction_id)
LOG.debug("extra specs updated and sent to rds")
datamanager.commit()
# create return json to wsme
result = ExtraSpecsWrapper.from_db_model(extra_specs_models)
except NotFoundError as exp:
datamanager.rollback()
LOG.log_exception("flavor id {} not found".format(flavor_id), exp)
raise
except Exception as exp:
datamanager.rollback()
LOG.log_exception("failed to update extra specs", exp)
raise
finally:
datamanager.close()
return result
@di.dependsOn('data_manager')
def get_flavor_by_uuid(flavor_uuid):
DataManager = di.resolver.unpack(get_flavor_by_uuid)
datamanager = DataManager()
try:
flavor_record = datamanager.get_record('flavor')
sql_flavor = flavor_record.get_flavor_by_id(flavor_uuid)
if not sql_flavor:
raise ErrorStatus(
404, 'flavor id {0} not found'.format(flavor_uuid))
flavor_wrapper = get_flavor_status(
sql_flavor, datamanager.get_session())
except Exception as exp:
LOG.log_exception("Failed to get_flavor_by_uuid", exp)
raise
return flavor_wrapper
@di.dependsOn('data_manager')
def add_tags(flavor_id, tags, transaction_id):
DataManager = di.resolver.unpack(add_tags)
datamanager = DataManager()
try:
LOG.debug("LOGIC - add tags")
datamanager.begin_transaction()
flavor_rec = datamanager.get_record("flavor")
sql_flavor = flavor_rec.get_flavor_by_id(flavor_id)
if not sql_flavor:
raise NotFoundError(404, 'flavor id {0} not found'.format(
flavor_id))
tags_model = tags.to_db_model()
sql_flavor.add_tags(tags_model)
datamanager.flush()
datamanager.commit()
# create return json to wsme
result = TagsWrapper.from_db_model(sql_flavor.flavor_tags)
except NotFoundError as exp:
datamanager.rollback()
LOG.log_exception("FlavorLogic - Flavor Not Found", exp)
raise
except Exception as exp:
datamanager.rollback()
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)
raise
finally:
datamanager.close()
return result
def get_flavor_status(sql_flavor, session):
flavor_wrapper = FlavorWrapper.from_db_model(sql_flavor)
region_names = [reg.region_name for reg in sql_flavor.flavor_regions]
if len(region_names):
uuid = [sql_flavor.id]
resource_status_dict = utils.get_resource_status_from_db(
session, uuid)
status_model = resource_status_dict.get(sql_flavor.id)
update_region_statuses(
flavor_wrapper.flavor, region_names, status_model)
else:
# flavor has no regions
flavor_wrapper.flavor.status = "no regions"
return flavor_wrapper
@di.dependsOn('data_manager')
def get_flavor_by_uuid_or_name(flavor_uuid_or_name):
DataManager = di.resolver.unpack(get_flavor_by_uuid_or_name)
datamanager = DataManager()
try:
flavor_record = datamanager.get_record('flavor')
sql_flavor = flavor_record.get_flavor_by_id_or_name(
flavor_uuid_or_name)
if not sql_flavor:
raise ErrorStatus(
404,
'flavor id or name {0} not found'.format(flavor_uuid_or_name))
flavor_wrapper = get_flavor_status(
sql_flavor, datamanager.get_session())
except Exception as exp:
LOG.log_exception("Failed to get_flavor_by_uuid_or_name", exp)
raise
finally:
datamanager.close()
return flavor_wrapper
def update_region_statuses(flavor, region_names, status_model):
# remove the regions comes from database and return the regions which
# return from rds, because there might be group region there (in the db)
# and in the response from the rds we will have a list of all regions
# belong to this group
flavor.regions[:] = []
flavor.status = 'no regions'
error_status = submitted_status = success_status = 0
if status_model and status_model.regions_status:
# get region status if region in flavor_regions_list
if region_names:
for status in status_model.regions_status:
# check that the region read from RDS is in the
# flavor_regions_list
if status.region in region_names:
flavor.regions.append(
Region(name=status.region, type="single",
status=status.status,
error_message=status.error_msg))
flavor.status = status_model.status
@di.dependsOn('data_manager')
def get_flavor_list_by_params(visibility, region, tenant, series, vm_type,
vnf_name, starts_with, contains, alias):
DataManager = di.resolver.unpack(get_flavor_list_by_params)
datamanager = DataManager()
try:
flavor_record = datamanager.get_record('flavor')
sql_flavors = flavor_record.get_flavors_by_criteria(
visibility=visibility,
region=region,
tenant=tenant,
series=series,
vm_type=vm_type,
vnf_name=vnf_name,
starts_with=starts_with,
contains=contains,
alias=alias)
response = FlavorListFullResponse()
if sql_flavors:
uuids = [sql_flavor.id for sql_flavor in sql_flavors]
resource_status_dict = utils.get_resource_status_from_db(
datamanager.get_session(), uuids)
for sql_flavor in sql_flavors:
flavor_wrapper = FlavorWrapper.from_db_model(sql_flavor)
region_names = [reg.region_name for reg
in sql_flavor.flavor_regions]
status_model = resource_status_dict.get(sql_flavor.id)
update_region_statuses(
flavor_wrapper.flavor, region_names, status_model)
response.flavors.append(flavor_wrapper.flavor)
except Exception as exp:
LOG.log_exception("Fail to get_flavor_list_by_params", exp)
raise
finally:
datamanager.close()
return response
def calculate_name(flavor):
""" 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 = xx.c1r1d1s4e5.i2n0
where xx : flavor series name
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
"""
option_order = ['n0', 'i2', 't0']
name = "{0}.c{1}r{2}d{3}".format(flavor.flavor.series, flavor.flavor.vcpus,
int(flavor.flavor.ram) // 1024,
flavor.flavor.disk)
# 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
series_metadata = cfg.CONF['flavor_series_metadata'][flavor.flavor.series]
valid_options = [series_metadata[x] for x in
series_metadata if x.startswith("valid_options_")]
options = [n for n in valid_options if n in
list(flavor.flavor.options.keys()) and
flavor.flavor.options[n].lower() == 'true']
if 'i2' in options and 'n0' not in options:
options.remove('i2')
if 't0' in options and flavor.flavor.visibility.lower() != 'private':
options.remove('t0')
if options:
name += '.'
for item in option_order:
if item in options:
name += item
return name
def update_region_actions(flavor_dict, existing_region_names, action="put"):
if action == "delete":
set_regions_action(flavor_dict, "delete")
elif action == "post":
set_regions_action(flavor_dict, "create")
else: # put
for region in flavor_dict["regions"]:
if region["name"] in existing_region_names:
region["action"] = "modify"
else:
region["action"] = "create"
# add deleted regions
for exist_region_name in existing_region_names:
if region_name_exist_in_regions(exist_region_name,
flavor_dict["regions"]):
continue
else:
flavor_dict["regions"].append({"name": exist_region_name,
"action": "delete"})
def region_name_exist_in_regions(region_name, regions):
for region in regions:
if region["name"] == region_name:
return True
return False
def set_regions_action(flavor_dict, action):
for region in flavor_dict["regions"]:
region["action"] = action