karbor/karbor/api/v1/copies.py

127 lines
4.1 KiB
Python

# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
"""The copy api."""
from oslo_config import cfg
from oslo_log import log as logging
from oslo_utils import uuidutils
from webob import exc
from karbor.api import common
from karbor.api.openstack import wsgi
from karbor import exception
from karbor.i18n import _
from karbor import objects
from karbor.policies import copies as copy_policy
from karbor.services.protection import api as protection_api
CONF = cfg.CONF
LOG = logging.getLogger(__name__)
class CopiesViewBuilder(common.ViewBuilder):
"""Model a server API response as a python dictionary."""
def detail(self, request, copy):
"""Detailed view of a single copy."""
copy_ref = {
'copy': {
'project_id': copy.get('project_id'),
'provider_id': copy.get('provider_id'),
'plan_id': copy.get('plan_id'),
'checkpoint_id': copy.get('checkpoint_id'),
'parameters': copy.get('parameters'),
}
}
return copy_ref
class CopiesController(wsgi.Controller):
"""The copy API controller for the OpenStack API."""
_view_builder_class = CopiesViewBuilder
def __init__(self):
self.protection_api = protection_api.API()
super(CopiesController, self).__init__()
def create(self, req, provider_id, body):
"""Creates a new copy."""
if not self.is_valid_body(body, 'copy'):
raise exc.HTTPUnprocessableEntity()
LOG.debug('Create copy request body: %s', body)
context = req.environ['karbor.context']
context.can(copy_policy.CREATE_POLICY)
copy = body['copy']
plan_id = copy.get("plan_id", None)
if not uuidutils.is_uuid_like(plan_id):
msg = _("Invalid plan id provided.")
raise exception.InvalidInput(reason=msg)
if not uuidutils.is_uuid_like(provider_id):
msg = _("Invalid provider id provided.")
raise exception.InvalidInput(reason=msg)
parameters = copy.get("parameters", None)
if parameters:
if not isinstance(parameters, dict):
msg = _("The parameters must be a dict when creating"
" a copy.")
raise exception.InvalidInput(reason=msg)
try:
plan = objects.Plan.get_by_id(context, plan_id)
except exception.PlanNotFound as error:
raise exc.HTTPNotFound(explanation=error.msg)
if provider_id != plan.provider_id:
msg = _("The provider id is not the same as the value "
"in the plan.")
raise exception.InvalidInput(reason=msg)
filters = {'plan_id': plan_id}
checkpoints = self.protection_api.list_checkpoints(
context, provider_id, marker=None, limit=None,
sort_keys=None, sort_dirs=None, filters=filters, offset=None)
if not checkpoints:
msg = _("The plan has not been protected.")
raise exception.InvalidInput(reason=msg)
plan.parameters.update(parameters)
try:
checkpoint_copy = self.protection_api.copy(context, plan)
except Exception:
LOG.exception("Failed to create checkpoint copies.")
raise
copy = {
'project_id': context.project_id,
'provider_id': plan.provider_id,
'plan_id': plan.id,
'checkpoint_id': checkpoint_copy,
'parameters': parameters
}
retval = self._view_builder.detail(req, copy)
return retval
def create_resource():
return wsgi.Resource(CopiesController())