def delete(self, container_ident, force=False, **kwargs): """Delete a container. :param container_ident: UUID or Name of a container. :param force: If True, allow to force delete the container. """ context = pecan.request.context if utils.is_all_tenants(kwargs): policy.enforce(context, "container:delete_all_tenants", action="container:delete_all_tenants") context.all_tenants = True container = utils.get_container(container_ident) check_policy_on_container(container.as_dict(), "container:delete") try: force = strutils.bool_from_string(force, strict=True) except ValueError: msg = _('Valid force values are true, false, 0, 1, yes and no') raise exception.InvalidValue(msg) stop = kwargs.pop('stop', False) try: stop = strutils.bool_from_string(stop, strict=True) except ValueError: msg = _('Valid stop values are true, false, 0, 1, yes and no') raise exception.InvalidValue(msg) compute_api = pecan.request.compute_api if not force and not stop: utils.validate_container_state(container, 'delete') elif force and not stop: req_version = pecan.request.version min_version = versions.Version('', '', '', '1.7') if req_version >= min_version: policy.enforce(context, "container:delete_force", action="container:delete_force") utils.validate_container_state(container, 'delete_force') else: raise exception.InvalidParamInVersion(param='force', req_version=req_version, min_version=min_version) elif stop: req_version = pecan.request.version min_version = versions.Version('', '', '', '1.12') if req_version >= min_version: check_policy_on_container(container.as_dict(), "container:stop") utils.validate_container_state(container, 'delete_after_stop') if container.status == consts.RUNNING: LOG.debug( 'Calling compute.container_stop with %s ' 'before delete', container.uuid) compute_api.container_stop(context, container, 10) else: raise exception.InvalidParamInVersion(param='stop', req_version=req_version, min_version=min_version) container.status = consts.DELETING compute_api.container_delete(context, container, force) pecan.response.status = 204
def setUp(self): super(TestVersion, self).setUp() self.a = versions.Version({versions.Version.string: "container 2.0"}, "container 2.0", "container 2.1") self.b = versions.Version({versions.Version.string: "container 2.0"}, "container 2.0", "container 2.1") self.c = versions.Version({versions.Version.string: "container 2.2"}, "container 2.0", "container 2.2")
def test_init(self, mock_parse): a = mock.Mock() b = mock.Mock() mock_parse.return_value = (a, b) v = versions.Version('test', 'foo', 'bar') mock_parse.assert_called_with('test', 'foo', 'bar') self.assertEqual(a, v.major) self.assertEqual(b, v.minor)
def test_check_for_versions_intersection_negative(self): func_list = \ [versioned_method.VersionedMethod('foo', versions.Version('', '', '', '2.1'), versions.Version('', '', '', '2.4'), None), versioned_method.VersionedMethod('foo', versions.Version('', '', '', '2.11'), versions.Version('', '', '', '3.1'), None), versioned_method.VersionedMethod('foo', versions.Version('', '', '', '2.8'), versions.Version('', '', '', '2.9'), None), ] result = base.Controller.check_for_versions_intersection( func_list=func_list) self.assertFalse(result) func_list = \ [versioned_method.VersionedMethod('foo', versions.Version('', '', '', '2.12'), versions.Version('', '', '', '2.14'), None), versioned_method.VersionedMethod('foo', versions.Version('', '', '', '3.0'), versions.Version('', '', '', '3.4'), None) ] result = base.Controller.check_for_versions_intersection( func_list=func_list) self.assertFalse(result)
def test_check_for_versions_intersection_shared_start_end(self): func_list = \ [versioned_method.VersionedMethod('foo', versions.Version('', '', '', '1.1'), versions.Version('', '', '', '1.1'), None), versioned_method.VersionedMethod('foo', versions.Version('', '', '', '1.1'), versions.Version('', '', '', '1.2'), None) ] result = base.Controller.check_for_versions_intersection( func_list=func_list) self.assertTrue(result)
def test_check_for_versions_intersection_positive(self): func_list = \ [versioned_method.VersionedMethod('foo', versions.Version('', '', '', '2.1'), versions.Version('', '', '', '2.4'), None), versioned_method.VersionedMethod('foo', versions.Version('', '', '', '2.3'), versions.Version('', '', '', '3.1'), None), versioned_method.VersionedMethod('foo', versions.Version('', '', '', '2.9'), versions.Version('', '', '', '3.4'), None) ] result = base.Controller.check_for_versions_intersection( func_list=func_list) self.assertTrue(result)
def version_check(action, version): """Check whether the current version supports the operation. :param action: Operations to be executed. :param version: The minimum version required to perform the operation. """ req_version = pecan.request.version min_version = versions.Version('', '', '', version) if req_version < min_version: raise exception.InvalidParamInVersion(param=action, req_version=req_version, min_version=min_version)
def decorator(f): obj_min_ver = versions.Version('', '', '', min_ver) if max_ver: obj_max_ver = versions.Version('', '', '', max_ver) else: obj_max_ver = versions.Version('', '', '', versions.CURRENT_MAX_VER) # Add to list of versioned methods registered func_name = f.__name__ new_func = versioned_method.VersionedMethod( func_name, obj_min_ver, obj_max_ver, f) func_dict = getattr(cls, VER_METHOD_ATTR, {}) if not func_dict: setattr(cls, VER_METHOD_ATTR, func_dict) func_list = func_dict.get(func_name, []) if not func_list: func_dict[func_name] = func_list func_list.append(new_func) is_intersect = Controller.check_for_versions_intersection( func_list) if is_intersect: raise exception.ApiVersionsIntersect( name=new_func.name, min_ver=new_func.start_version, max_ver=new_func.end_version ) # Ensure the list is sorted by minimum version (reversed) # so later when we work through the list in order we find # the method which has the latest version which supports # the version requested. func_list.sort(key=lambda f: f.start_version, reverse=True) return f
def test_controller_get_attr_version_not_found(self, mock_pecan_request): class MyController(base.Controller): @base.Controller.api_version('1.0', '1.1') def testapi1(self): return 'API1_1.0_1.1' @base.Controller.api_version('1.3', '1.4') # noqa def testapi1(self): return 'API1_1.3_1.4' controller = MyController() mock_pecan_request.version = versions.Version("", "", "", "1.2") controller.request = mock_pecan_request method = controller.__getattribute__('testapi1') self.assertRaises(exc.HTTPNotAcceptable, method)
def test_controller_get_attribute(self, mock_pecan_request): class MyController(base.Controller): @base.Controller.api_version('1.0', '1.1') def testapi1(self): return 'API1_1.0_1.1' @base.Controller.api_version('1.2', '1.3') # noqa def testapi1(self): return 'API1_1.2_1.3' controller = MyController() mock_pecan_request.version = versions.Version("", "", "", "1.2") controller.request = mock_pecan_request method = controller.__getattribute__('testapi1') result = method() self.assertEqual('API1_1.2_1.3', result)
def _route(self, args): version = ver.Version( pecan.request.headers, MIN_VER_STR, MAX_VER_STR) # Always set the basic version headers pecan.response.headers[ver.Version.min_string] = MIN_VER_STR pecan.response.headers[ver.Version.max_string] = MAX_VER_STR pecan.response.headers[ver.Version.string] = " ".join( [ver.Version.service_string, str(version)]) pecan.response.headers["vary"] = ver.Version.string # assert that requested version is supported self._check_version(version, pecan.response.headers) pecan.request.version = version if pecan.request.body: msg = ("Processing request: url: %(url)s, %(method)s, " "body: %(body)s" % {'url': pecan.request.url, 'method': pecan.request.method, 'body': pecan.request.body}) LOG.debug(msg) return super(Controller, self)._route(args)
def post(self, run=False, **container_dict): """Create or run a new container. :param run: if true, starts the container :param container_dict: a container within the request body. """ context = pecan.request.context compute_api = pecan.request.compute_api policy.enforce(context, "container:create", action="container:create") if container_dict.get('security_groups'): # remove duplicate security_groups from list container_dict['security_groups'] = list( set(container_dict.get('security_groups'))) for index, sg in enumerate(container_dict['security_groups']): security_group_id = self._check_security_group( context, {'name': sg}) container_dict['security_groups'][index] = security_group_id try: run = strutils.bool_from_string(run, strict=True) container_dict['interactive'] = strutils.bool_from_string( container_dict.get('interactive', False), strict=True) except ValueError: raise exception.InvalidValue( _('Valid run or interactive values ' 'are: true, false, True, False')) auto_remove = container_dict.pop('auto_remove', None) if auto_remove is not None: req_version = pecan.request.version min_version = versions.Version('', '', '', '1.3') if req_version >= min_version: try: container_dict['auto_remove'] = strutils.bool_from_string( auto_remove, strict=True) except ValueError: raise exception.InvalidValue( _('Auto_remove values are: ' 'true, false, True, False')) else: raise exception.InvalidParamInVersion(param='auto_remove', req_version=req_version, min_version=min_version) runtime = container_dict.pop('runtime', None) if runtime is not None: req_version = pecan.request.version min_version = versions.Version('', '', '', '1.5') if req_version >= min_version: container_dict['runtime'] = runtime else: raise exception.InvalidParamInVersion(param='runtime', req_version=req_version, min_version=min_version) hostname = container_dict.pop('hostname', None) if hostname is not None: req_version = pecan.request.version min_version = versions.Version('', '', '', '1.9') if req_version >= min_version: container_dict['hostname'] = hostname else: raise exception.InvalidParamInVersion(param='hostname', req_version=req_version, min_version=min_version) nets = container_dict.get('nets', []) requested_networks = utils.build_requested_networks(context, nets) pci_req = self._create_pci_requests_for_sriov_ports( context, requested_networks) mounts = container_dict.pop('mounts', []) if mounts: req_version = pecan.request.version min_version = versions.Version('', '', '', '1.11') if req_version < min_version: raise exception.InvalidParamInVersion(param='mounts', req_version=req_version, min_version=min_version) requested_volumes = self._build_requested_volumes(context, mounts) # Valiadtion accepts 'None' so need to convert it to None if container_dict.get('image_driver'): container_dict['image_driver'] = api_utils.string_or_none( container_dict.get('image_driver')) container_dict['project_id'] = context.project_id container_dict['user_id'] = context.user_id name = container_dict.get('name') or \ self._generate_name_for_container() container_dict['name'] = name if container_dict.get('memory'): container_dict['memory'] = \ str(container_dict['memory']) + 'M' if container_dict.get('restart_policy'): utils.check_for_restart_policy(container_dict) container_dict['status'] = consts.CREATING extra_spec = {} extra_spec['hints'] = container_dict.get('hints', None) extra_spec['pci_requests'] = pci_req new_container = objects.Container(context, **container_dict) new_container.create(context) kwargs = {} kwargs['extra_spec'] = extra_spec kwargs['requested_networks'] = requested_networks kwargs['requested_volumes'] = requested_volumes if pci_req.requests: kwargs['pci_requests'] = pci_req kwargs['run'] = run compute_api.container_create(context, new_container, **kwargs) # Set the HTTP Location Header pecan.response.location = link.build_url('containers', new_container.uuid) pecan.response.status = 202 return view.format_container(pecan.request.host_url, new_container)
def post(self, run=False, **container_dict): """Create a new container. :param run: if true, starts the container :param container_dict: a container within the request body. """ context = pecan.request.context compute_api = pecan.request.compute_api policy.enforce(context, "container:create", action="container:create") # remove duplicate security_groups from list if container_dict.get('security_groups'): container_dict['security_groups'] = list( set(container_dict.get('security_groups'))) try: run = strutils.bool_from_string(run, strict=True) container_dict['interactive'] = strutils.bool_from_string( container_dict.get('interactive', False), strict=True) except ValueError: msg = _('Valid run or interactive value is ''true'', ' '"false", True, False, "True" and "False"') raise exception.InvalidValue(msg) requested_networks = container_dict.get('nets', []) # Valiadtion accepts 'None' so need to convert it to None if container_dict.get('image_driver'): container_dict['image_driver'] = api_utils.string_or_none( container_dict.get('image_driver')) # NOTE(mkrai): Intent here is to check the existence of image # before proceeding to create container. If image is not found, # container create will fail with 400 status. images = compute_api.image_search(context, container_dict['image'], container_dict.get('image_driver'), True) if not images: raise exception.ImageNotFound(image=container_dict['image']) container_dict['project_id'] = context.project_id container_dict['user_id'] = context.user_id name = container_dict.get('name') or \ self._generate_name_for_container() container_dict['name'] = name if container_dict.get('memory'): container_dict['memory'] = \ str(container_dict['memory']) + 'M' if container_dict.get('restart_policy'): self._check_for_restart_policy(container_dict) auto_remove = container_dict.pop('auto_remove', None) if auto_remove is not None: req_version = pecan.request.version min_version = versions.Version('', '', '', '1.3') if req_version >= min_version: try: container_dict['auto_remove'] = strutils.bool_from_string( auto_remove, strict=True) except ValueError: msg = _('Auto_remove value are true or false') raise exception.InvalidValue(msg) else: msg = _('Invalid param auto_remove because current request ' 'version is %(req_version)s. Auto_remove is only ' 'supported from version %(min_version)s') % \ {'req_version': req_version, 'min_version': min_version} raise exception.InvalidParam(msg) container_dict['status'] = consts.CREATING extra_spec = container_dict.get('hints', None) new_container = objects.Container(context, **container_dict) new_container.create(context) if run: compute_api.container_run(context, new_container, extra_spec, requested_networks) else: compute_api.container_create(context, new_container, extra_spec, requested_networks) # Set the HTTP Location Header pecan.response.location = link.build_url('containers', new_container.uuid) pecan.response.status = 202 return view.format_container(pecan.request.host_url, new_container)
from zun.api.controllers.v1 import providervms as providervm_controller from zun.api.controllers.v1 import providerregions as providerregion_controller from zun.api.controllers.v1 import storagerates as storagerate_controller from zun.api.controllers.v1 import usages as usage_controller from zun.api.controllers.v1 import users as user_controller from zun.api.controllers.v1 import statements as statement_controller LOG = logging.getLogger(__name__) BASE_VERSION = 1 MIN_VER_STR = '%s %s' % (ver.Version.service_string, ver.BASE_VER) MAX_VER_STR = '%s %s' % (ver.Version.service_string, ver.CURRENT_MAX_VER) MIN_VER = ver.Version({ver.Version.string: MIN_VER_STR}, MIN_VER_STR, MAX_VER_STR) MAX_VER = ver.Version({ver.Version.string: MAX_VER_STR}, MIN_VER_STR, MAX_VER_STR) class MediaType(controllers_base.APIBase): """A media type representation.""" fields = ( 'base', 'type', ) class V1(controllers_base.APIBase): """The representation of the version 1 of the API."""
def test_repr_with_strings(self, mock_parse): mock_parse.return_value = ('abc', 'def') v = versions.Version('test', mock.ANY, mock.ANY) result = "%s" % v self.assertEqual('abc.def', result)
def test_repr(self, mock_parse): mock_parse.return_value = (123, 456) v = versions.Version('test', mock.ANY, mock.ANY) result = "%s" % v self.assertEqual('123.456', result)