jh629g 64bd786367 Updating Ranger Error Bases
Ranger errors are split out
unecessarily in the code base
and need to be refactored for
python 3.6 best practice

Change-Id: I06b1e2679ff2f0d7cadf7eab4ab0a7cc61e138ca
2020-11-03 01:38:10 +00:00

609 lines
21 KiB
Python
Executable File

import time
from orm.common.orm_common.injector import injector
from orm.common.orm_common.utils import utils
from orm.services.image_manager.ims.logger import get_logger
from orm.common.orm_common.utils.error_base import \
ErrorStatus, NotFoundError
from orm.services.image_manager.ims.persistency.sql_alchemy.db_models import \
ImageCustomer, ImageRegion
from orm.services.image_manager.ims.persistency.wsme.models import (
ImageSummary, ImageSummaryResponse, ImageWrapper, RegionWrapper)
from orm.services.image_manager.ims.utils import utils as ImsUtils
import oslo_db
LOG = get_logger(__name__)
di = injector.get_di()
@di.dependsOn('data_manager')
def create_image(image_wrapper, image_uuid, transaction_id):
DataManager = di.resolver.unpack(create_image)
datamanager = DataManager()
image_wrapper.image.id = image_uuid
image_wrapper.image.created_at = str(int(time.time()))
image_wrapper.image.updated_at = image_wrapper.image.created_at
try:
image_wrapper.handle_region_group()
image_wrapper.validate_model()
sql_image = image_wrapper.to_db_model()
image_rec = datamanager.get_record('image')
datamanager.begin_transaction()
image_rec.insert(sql_image)
datamanager.flush() # i want to get any exception created by this
# insert
existing_region_names = []
send_to_rds_if_needed(sql_image, existing_region_names, "post",
transaction_id)
datamanager.commit()
ret_image = get_image_by_uuid(image_uuid)
return ret_image
except oslo_db.exception.DBDuplicateEntry as exception:
utils.delete_uuid(image_uuid)
raise ErrorStatus(
"Image name '{}' already exists".format(
image_wrapper.image.name),
409)
except Exception as exp:
LOG.log_exception("ImageLogic - Failed to CreateImage", exp)
datamanager.rollback()
utils.delete_uuid(image_uuid)
raise
@di.dependsOn('rds_proxy')
def send_to_rds_if_needed(sql_image, existing_region_names, http_action,
transaction_id):
rds_proxy = di.resolver.unpack(send_to_rds_if_needed)
if (sql_image.regions and len(sql_image.regions) > 0) or len(
existing_region_names) > 0:
image_dict = sql_image.get_proxy_dict()
update_region_actions(image_dict, existing_region_names, http_action)
if image_dict['regions'] or len(existing_region_names) > 0:
LOG.debug("Image is valid, sending to RDS Proxy ")
rds_proxy.send_image(image_dict, transaction_id, http_action)
else:
LOG.debug("Group with no regions, not sending to RDS Proxy " + str(
sql_image))
else:
LOG.debug("Image with no regions, not sending to RDS Proxy " + str(
sql_image))
@di.dependsOn('data_manager')
def update_image(image_wrapper, image_uuid, transaction_id, http_action="put"):
DataManager = di.resolver.unpack(update_image)
datamanager = DataManager()
try:
image_wrapper.validate_model('update')
new_image = image_wrapper.to_db_model()
new_image.id = image_uuid
image_rec = datamanager.get_record('image')
sql_image = image_rec.get_image_by_id(image_uuid)
if sql_image is None:
raise NotFoundError(
status_code=404,
message="Image {0} does not exist for update".format(
image_uuid))
image_wrapper.validate_update(sql_image, new_image)
datamanager.begin_transaction()
new_image.owner = sql_image.owner
existing_regions = sql_image.get_existing_region_names()
new_image.created_at = int(sql_image.created_at)
new_image.updated_at = int(time.time())
# result = image_rec.delete_image_by_id(image_uuid)
datamanager.get_session().delete(sql_image)
# del sql_image
image_rec.insert(new_image)
datamanager.flush()
send_to_rds_if_needed(new_image, existing_regions, http_action,
transaction_id)
datamanager.commit()
ret_image = get_image_by_uuid(image_uuid)
return ret_image
except Exception as exp:
datamanager.rollback()
LOG.log_exception("ImageLogic - Failed to update image", exp)
raise
@di.dependsOn('data_manager')
def delete_image_by_uuid(image_uuid, transaction_id):
DataManager = di.resolver.unpack(delete_image_by_uuid)
datamanager = DataManager()
try:
datamanager.begin_transaction()
image_rec = datamanager.get_record('image')
sql_image = image_rec.get_image_by_id(image_uuid)
if sql_image is None:
message_not_found = "Image '{}' not found".format(image_uuid)
raise NotFoundError(message_not_found)
image_existing_region_names = sql_image.get_existing_region_names()
if len(image_existing_region_names) > 0:
# Do not delete an image that still has region(s)
raise ErrorStatus("Cannot delete a image with regions. "
"Please delete the regions first and then "
"delete the image.",
405)
# Get status from resource status table
uuid = [sql_image.id]
resource_status_dict = utils.get_resource_status_from_db(
datamanager.get_session(), uuid, True)
status_model = resource_status_dict.get(sql_image.id)
if status_model:
status = status_model.status
LOG.debug('Status from resource_status table: {}'.format(status))
else:
# Image not found in table, that means it never had any
# regions. So it is OK to delete it
status = 'Success'
LOG.debug('Resource not found in table, so it is OK to delete')
if status != 'Success':
raise ErrorStatus("not allowed as aggregate status "
"have to be Success (either the deletion "
"failed on one of the regions or it is "
"still in progress)",
405)
image_rec.delete_image_by_id(image_uuid)
datamanager.flush() # i want to get any exception created by this
# delete
datamanager.commit()
# after successful image delete, delete image id from uuids table
utils.delete_uuid(image_uuid)
except Exception as exp:
LOG.log_exception("ImageLogic - Failed to delete image", exp)
datamanager.rollback()
raise
@di.dependsOn('data_manager')
def add_regions(image_uuid, regions, transaction_id):
DataManager = di.resolver.unpack(add_regions)
datamanager = DataManager()
try:
image_rec = datamanager.get_record('image')
sql_image = image_rec.get_image_by_id(image_uuid)
if not sql_image:
raise NotFoundError('image with id: {0} not found'.format(
image_uuid))
existing_region_names = sql_image.get_existing_region_names()
for region in regions.regions:
db_region = ImageRegion(region_name=region.name,
region_type=region.type)
sql_image.add_region(db_region)
datamanager.flush() # i want to get any exception created by
# previous actions against the database
send_to_rds_if_needed(sql_image, existing_region_names, "put",
transaction_id)
datamanager.commit()
image_wrapper = get_image_by_uuid(image_uuid)
ret = RegionWrapper(regions=image_wrapper.image.regions)
return ret
except ErrorStatus as exp:
LOG.log_exception("ImageLogic - Failed to add regions", exp)
datamanager.rollback()
raise
except Exception as exp:
LOG.log_exception("ImageLogic - Failed to add regions", exp)
datamanager.rollback()
raise
@di.dependsOn('data_manager')
def replace_regions(image_uuid, regions, transaction_id):
DataManager = di.resolver.unpack(replace_regions)
datamanager = DataManager()
try:
image_rec = datamanager.get_record('image')
sql_image = image_rec.get_image_by_id(image_uuid)
if not sql_image:
raise NotFoundError('image with id: {0} not found'.format(
image_uuid))
existing_region_names = sql_image.get_existing_region_names()
sql_image.remove_all_regions()
datamanager.flush()
for region in regions.regions:
db_region = ImageRegion(region_name=region.name,
region_type=region.type)
sql_image.add_region(db_region)
datamanager.flush() # i want to get any exception created by
# previous actions against the database
send_to_rds_if_needed(sql_image, existing_region_names, "put",
transaction_id)
datamanager.commit()
image_wrapper = get_image_by_uuid(image_uuid)
ret = RegionWrapper(regions=image_wrapper.image.regions)
return ret
except ErrorStatus as exp:
LOG.error("ImageLogic - Failed to replace regions", exp)
datamanager.rollback()
raise
except Exception as exp:
LOG.error("ImageLogic - Failed to repalce regions", exp)
datamanager.rollback()
raise
@di.dependsOn('data_manager')
def delete_region(image_uuid, region_name, transaction_id, force_delete):
DataManager = di.resolver.unpack(delete_region)
datamanager = DataManager()
try:
image_rec = datamanager.get_record('image')
sql_image = image_rec.get_image_by_id(image_uuid)
if not sql_image:
raise NotFoundError('image with id: {0} not found'.format(
image_uuid))
# do not allow delete_region for protected images
if sql_image.protected:
protect_msg = "Protected image {} cannot be deleted. Please " \
"update image with protected=false and try again"
raise ErrorStatus(protect_msg.format(image_uuid), 400)
existing_region_names = sql_image.get_existing_region_names()
sql_image.remove_region(region_name)
# Get any exception created by previous actions against the database
datamanager.flush()
send_to_rds_if_needed(sql_image, existing_region_names, "put",
transaction_id)
if force_delete:
datamanager.commit()
else:
datamanager.rollback()
except ErrorStatus as exp:
LOG.log_exception("ImageLogic - Failed to update image", exp)
datamanager.rollback()
raise
except Exception as exp:
LOG.log_exception("ImageLogic - Failed to delete region", exp)
datamanager.rollback()
raise
finally:
datamanager.close()
@di.dependsOn('data_manager')
def add_customers(image_uuid, customers, transaction_id):
DataManager = di.resolver.unpack(add_customers)
datamanager = DataManager()
try:
image_rec = datamanager.get_record('image')
sql_image = image_rec.get_image_by_id(image_uuid)
if not sql_image:
raise NotFoundError('image with id: {0} not found'.format(
image_uuid))
if sql_image.visibility != "shared":
raise ErrorStatus('Customer can only be added to shared image.')
existing_region_names = sql_image.get_existing_region_names()
for user in customers.customers:
db_Customer = ImageCustomer(customer_id=user)
sql_image.add_customer(db_Customer)
datamanager.flush() # i want to get any exception created by
# previous actions against the database
send_to_rds_if_needed(sql_image, existing_region_names, "put",
transaction_id)
datamanager.commit()
ret_image = get_image_by_uuid(image_uuid)
return ret_image
except Exception as exp:
if 'conflicts with persistent instance' in str(exp) or \
'Duplicate entry' in str(exp):
raise ErrorStatus("Duplicate Customer for Image")
LOG.log_exception("ImageLogic - Failed to add Customers", exp)
datamanager.rollback()
raise
@di.dependsOn('data_manager')
def replace_customers(image_uuid, customers, transaction_id):
DataManager = di.resolver.unpack(replace_customers)
datamanager = DataManager()
try:
image_rec = datamanager.get_record('image')
sql_image = image_rec.get_image_by_id(image_uuid)
if not sql_image:
raise NotFoundError('image {0} not found'.format(image_uuid))
if sql_image.visibility != "shared":
raise ValueError('Customer can only be replaced with shared Image')
existing_region_names = sql_image.get_existing_region_names()
sql_image.remove_all_customers()
datamanager.flush()
for cust in customers.customers:
db_Customer = ImageCustomer(customer_id=cust)
sql_image.add_customer(db_Customer)
datamanager.flush() # get exception created by previous db actions
send_to_rds_if_needed(sql_image, existing_region_names, "put",
transaction_id)
datamanager.commit()
ret_image = get_image_by_uuid(image_uuid)
return ret_image
except Exception as exp:
if 'conflicts with persistent instance' in str(exp) or \
'Duplicate entry' in str(exp):
raise ErrorStatus("Duplicate Customer for Image", 409)
LOG.log_exception("ImageLogic - Failed to add Customers", exp)
datamanager.rollback()
raise
@di.dependsOn('data_manager')
def delete_customer(image_uuid, customer_id, transaction_id):
DataManager = di.resolver.unpack(delete_customer)
datamanager = DataManager()
try:
image_rec = datamanager.get_record('image')
sql_image = image_rec.get_image_by_id(image_uuid)
if not sql_image:
raise NotFoundError('image {0} not found'.format(image_uuid))
if sql_image.visibility != "shared":
raise ValueError(
"Customer can only be deleted from shared image {}".format(
image_uuid))
existing_region_names = sql_image.get_existing_region_names()
sql_image.remove_customer(customer_id)
datamanager.flush() # i want to get any exception created by
# previous actions against the database
send_to_rds_if_needed(sql_image, existing_region_names, "put",
transaction_id)
datamanager.commit()
except Exception as exp:
LOG.log_exception("ImageLogic - Failed to delete Customer", exp)
datamanager.rollback()
raise
def set_resource_status(sql_image, status_model):
image_wrapper = ImageWrapper.from_db_model(sql_image)
image_wrapper.image.status = 'no regions'
if status_model and status_model.regions:
for region in image_wrapper.image.regions:
for status in status_model.regions:
if status.region == region.name:
region.status = status.status
if status.error_msg:
region.set_error_message(status.error_msg)
image_wrapper.image.status = status_model.status
return image_wrapper
@di.dependsOn('data_manager')
def get_image_by_uuid(image_uuid, query_by_id_or_name=False):
"""This function includes an optional boolean parameter
query_by_id_or_name. If query_by_id_or_name evaluates to true, IMS logic
will fetch the image record whose "image_uuid" parameter value matches
either the image id or name value. Otherwise, it defaults to query by
image ID value only.
"""
DataManager = di.resolver.unpack(get_image_by_uuid)
datamanager = DataManager()
LOG.debug("Get image by uuid : {}".format(image_uuid))
try:
datamanager.begin_transaction()
image_rec = datamanager.get_record('image')
# Only the get_image API will pass the optional parameter and
# set it to true
if query_by_id_or_name:
sql_image = image_rec.get_image(image_uuid)
else:
# all other image APIs will NOT pass the optional parameter
sql_image = image_rec.get_image_by_id(image_uuid)
if not sql_image:
raise NotFoundError(
status_code=404,
message="Image {0} not found ".format(image_uuid))
# Get the status from resource table
uuid = [sql_image.id]
resource_status_dict = utils.get_resource_status_from_db(
datamanager.get_session(), uuid, True)
status_model = resource_status_dict.get(sql_image.id)
image_wrapper = set_resource_status(sql_image, status_model)
# get image own link
image_wrapper.image.links, image_wrapper.image.self_link = \
ImsUtils.get_server_links(image_uuid)
# convert time stamp format to human readable time
image_wrapper.image.created_at = ImsUtils.convert_time_human(
image_wrapper.image.created_at)
image_wrapper.image.updated_at = ImsUtils.convert_time_human(
image_wrapper.image.updated_at)
except NotFoundError as exp:
datamanager.rollback()
LOG.log_exception("ImageLogic - Failed to update image", exp)
raise
except Exception as exp:
datamanager.rollback()
LOG.log_exception("ImageLogic - Failed to delete Customer", exp)
raise
return image_wrapper
@di.dependsOn('data_manager')
def get_image_list_by_params(visibility, region, Customer):
DataManager = di.resolver.unpack(get_image_list_by_params)
datamanager = DataManager()
try:
image_record = datamanager.get_record('image')
sql_images = image_record.get_images_by_criteria(visibility=visibility,
region=region,
Customer=Customer)
response = ImageSummaryResponse()
if sql_images:
uuids = [sql_image.id for sql_image in sql_images]
resource_status_dict = utils.get_resource_status_from_db(
datamanager.get_session(), uuids, True)
for sql_image in sql_images:
status_model = resource_status_dict.get(sql_image.id)
wsme_image = set_resource_status(sql_image, status_model)
image_summary = ImageSummary.from_wsme(wsme_image)
response.images.append(image_summary)
return response
except ErrorStatus as exp:
LOG.log_exception("ImageLogic - Failed to get list", exp)
raise
except Exception as exp:
LOG.log_exception("ImageLogic - Failed to get list", exp)
raise
def update_region_actions(image_dict, existing_region_names, action="put"):
if action == "delete":
set_regions_action(image_dict, "delete")
elif action == "post":
set_regions_action(image_dict, "create")
else: # put
for region in image_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,
image_dict["regions"]):
continue
else:
image_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(image_dict, action):
for region in image_dict["regions"]:
region["action"] = action
@di.dependsOn('data_manager')
def enable_image(image_uuid, int_enabled, transaction_id):
DataManager = di.resolver.unpack(enable_image)
datamanager = DataManager()
try:
image_rec = datamanager.get_record('image')
sql_image = image_rec.get_image_by_id(image_uuid)
if not sql_image:
raise NotFoundError('Image with id: {0} not found'.format(
image_uuid))
sql_image.enabled = int_enabled
existing_region_names = sql_image.get_existing_region_names()
datamanager.flush() # i want to get any exception created by this
# insert method
send_to_rds_if_needed(sql_image, existing_region_names, "put",
transaction_id)
datamanager.commit()
ret_image = get_image_by_uuid(image_uuid)
return ret_image
except ErrorStatus as exp:
LOG.log_exception(
"ImageLogic - Failed to change image activation value", exp)
datamanager.rollback()
raise
except Exception as exp:
LOG.log_exception(
"ImageLogic - Failed to change image activation value", exp)
datamanager.rollback()
raise