ranger/orm/services/resource_distributor/rds/controllers/v1/resources/root.py

286 lines
10 KiB
Python
Executable File

"""handle rest api input module."""
import ast
import logging.handlers
import time
from orm.services.resource_distributor.rds.controllers.v1.base import (ClientSideError, LockedEntity,
NotAllowedError)
from orm.services.resource_distributor.rds.services.base import ConflictValue
from orm.services.resource_distributor.rds.services import resource as ResourceService
import pecan
from pecan import rest
import wsme
from wsme import types as wtypes
from wsmeext.pecan import wsexpose
my_logger = logging.getLogger(__name__)
resources_operation_list = {
"flavor": ['delete', 'create', 'modify'],
"image": ['delete', 'create', 'modify']
}
class Links(wtypes.DynamicBase):
"""class method."""
self = wsme.wsattr(wtypes.text, mandatory=True)
def __init__(own, self=""):
"""init function.
:param self: self link
"""
own.self = self
class CreatedResource(wtypes.DynamicBase):
"""class method for returned json."""
id = wsme.wsattr(wtypes.text, mandatory=True)
created = wsme.wsattr(wtypes.text, mandatory=False)
links = wsme.wsattr(Links, mandatory=True)
updated = wsme.wsattr(wtypes.text, mandatory=False)
err = wsme.wsattr(wtypes.text, mandatory=False)
message = wsme.wsattr(wtypes.text, mandatory=False)
def __init__(self, id="", err=None, message=None,
created=None, updated=None, links=Links()):
"""init function.
:param id: resource id
:param err: error if any
:param message: error message
:param created: timestamp
:param updated: timestamp when put request
:param links:
"""
self.id = id
self.links = links
if created is not None:
self.created = created
if updated is not None:
self.updated = updated
if err is not None:
self.err = err # pragma: no cover
if message is not None:
self.message = message # pragma: no cover
class Result(wtypes.DynamicBase):
"""class method, json header."""
customer = wsme.wsattr(CreatedResource, mandatory=False)
group = wsme.wsattr(CreatedResource, mandatory=False)
flavor = wsme.wsattr(CreatedResource, mandatory=False)
image = wsme.wsattr(CreatedResource, mandatory=False)
def __init__(self, customer=None, group=None,
flavor=None, image=None):
"""init function.
:param customer: json header
:param flavor: json header
"""
if customer is not None:
self.customer = customer
if group is not None:
self.group = group
if flavor is not None:
self.flavor = flavor
if image is not None:
self.image = image
class TrackingData(wtypes.DynamicBase):
"""class method to handle json input."""
external_id = wsme.wsattr(wtypes.text, mandatory=True)
tracking_id = wsme.wsattr(wtypes.text, mandatory=True)
def __init__(self, external_id="", tracking_id=""):
"""init function.
:param external_id: full flow traking id
:param tracking_id: enternal traking id
"""
self.external_id = external_id
self.tracking_id = tracking_id
class ResourceTypeData(wtypes.DynamicBase):
"""class method, handle json input."""
resource_type = wsme.wsattr(wtypes.text, mandatory=True)
resource_id = wsme.wsattr(wtypes.text, mandatory=False)
def __init__(self, resource_type="", resource_id=None):
"""init function.
:param resource_type: type of the resource eg.customer, flavor..
:param resource_id: id of the resource
"""
self.resource_type = resource_type
if resource_id is not None:
self.resource_id = resource_id # pragma: no cover
class ResourceData(wtypes.DynamicBase):
"""class method to handle resource data json."""
resource = wsme.wsattr(ResourceTypeData, mandatory=True)
model = wsme.wsattr(wtypes.text, mandatory=True)
# model = wsme.wsattr(FullJson, mandatory=True)
tracking = wsme.wsattr(TrackingData, mandatory=True)
def __init__(self, model="", resource=ResourceTypeData(),
tracking=TrackingData(),):
"""init function.
:param model: input json (resource data)
:param resource: resource type, resource id
:param tracking: transaction id
"""
self.resource = resource
self.tracking = tracking
self.model = model
class Resource(wtypes.DynamicBase):
"""main class first key json."""
service_template = wsme.wsattr(ResourceData, mandatory=True)
def __init__(self, service_template=ResourceData()):
"""init function.
:param service_template:
"""
self.service_template = service_template
class CreateNewResource(rest.RestController):
"""creatin new resource controller."""
@wsexpose(Result, body=Resource, status_code=201,
rest_content_types='json')
def post(self, resource):
"""Handle HTTP POST request.
:param Customer (json in request body):
:return: result (json format ... {'Cusetomer':{'id':'',
'links':{'own':'how host url'},'created':'1234567890'}}
the response will be 201 created if success
:return 409 for conflict
:return 400 bad request
handle json input
"""
my_logger.info("create resource")
jsondata = resource.service_template.model
my_logger.debug("parse json & get yaml file!!! {}".format(jsondata))
uuid = resource.service_template.tracking.tracking_id
resource_type = resource.service_template.resource.resource_type
base_url = pecan.request.application_url
jsondata = ast.literal_eval(jsondata)
try:
resource_id = ResourceService.main(jsondata,
uuid,
resource_type,
'create')
site_link = "%s/v1/rds/%s/%s" % (base_url,
resource_type,
resource_id)
res = Result(**{resource_type: CreatedResource(id=resource_id,
created='%d' % (time.time() * 1000),
links=Links(site_link))})
return res
except ConflictValue as e:
my_logger.error("the request blocked need to wait "
"for previous operation to be done ")
raise LockedEntity(e.message)
except Exception as e:
my_logger.error("error :- %s " % str(e.message))
raise ClientSideError(e.message)
@wsexpose(Result, body=Resource, status_code=201,
rest_content_types='json')
def put(self, resource):
"""Handle HTTP POST request.
:param Customer (json in request body):
:return: result (json format ... {'Cusetomer':{'id':'',
'links':{'own':'how host url'},'created':'1234567890'}}
the response will be 201 created if success
:return 409 for conflict
:return 400 bad request
handle json input
"""
my_logger.info("modify resource")
jsondata = resource.service_template.model
my_logger.debug("parse json & get yaml file!!! {}".format(jsondata))
uuid = resource.service_template.tracking.tracking_id
resource_type = resource.service_template.resource.resource_type
base_url = pecan.request.application_url
jsondata = ast.literal_eval(jsondata)
try:
resource_id = ResourceService.main(jsondata,
uuid,
resource_type,
'modify')
my_logger.debug("data sent!.")
site_link = "%s/v1/rds/%s/%s" % (base_url,
resource_type,
resource_id)
res = Result(**{
resource_type: CreatedResource(
id=resource_id,
updated='%d' % (time.time() * 1000),
links=Links(site_link))})
return res
except ConflictValue as e:
my_logger.error("the request blocked need to wait "
"for previous operation to be done ")
raise LockedEntity(e.message)
except Exception as e:
my_logger.error("error :- %s " % str(e.message))
raise ClientSideError(e.message)
@wsexpose(str, body=Resource, status_code=200,
rest_content_types='json')
def delete(self, resource):
"""handle json input.
:param resource: input json
:return: 200 if valid json
:return: 405 not allowed for not valid resource to delete
:return: 400 for bad request
"""
operation = 'delete'
my_logger.info("delete resource ")
jsondata = resource.service_template.model
my_logger.debug("parse json & get yaml file!!! {}".format(jsondata))
jsondata = ast.literal_eval(jsondata)
resource_uuid = resource.service_template.tracking.tracking_id
resource_type = resource.service_template.resource.resource_type
if resource_type not in resources_operation_list or operation not in \
resources_operation_list[resource_type]:
raise NotAllowedError("delete Not allowed for this"
" resource %s" % resource_type)
try:
resource_id = ResourceService.main(jsondata,
resource_uuid,
resource_type,
operation)
return resource_id
except ConflictValue as e:
my_logger.error("the request blocked need to wait"
" for previous operation to be done ")
raise LockedEntity(e.message)
except Exception as e:
my_logger.error("error :- %s " % str(e.message))
raise ClientSideError(e.message)