def put(self, _id, **kw): context = t_context.extract_context_from_environ() if not policy.enforce(context, policy.ADMIN_API_ROUTINGS_PUT): return utils.format_api_error( 403, _('Unauthorized to update resource routing')) try: db_api.get_resource_routing(context, _id) except t_exceptions.ResourceNotFound: return utils.format_api_error(404, _('Resource routing not found')) if 'routing' not in kw: return utils.format_api_error(400, _('Request body not found')) update_dict = kw['routing'] # values to be updated should not be empty for field in update_dict: value = update_dict.get(field) if value is None or len(value.strip()) == 0: return utils.format_api_error( 400, _("Field %(field)s can not be empty") % {'field': field}) # the resource type should be properly provisioned. if 'resource_type' in update_dict: if not constants.is_valid_resource_type( update_dict['resource_type']): return utils.format_api_error( 400, _('There is no such resource type')) # the pod with new pod_id should exist in pod table if 'pod_id' in update_dict: new_pod_id = update_dict.get('pod_id') try: # find the pod through the pod_id and verify whether it exists db_api.get_pod(context, new_pod_id) except t_exceptions.ResourceNotFound: return utils.format_api_error( 400, _("The pod %(new_pod_id)s doesn't" " exist") % {'new_pod_id': new_pod_id}) except Exception as e: LOG.exception( 'Failed to update resource routing: ' '%(exception)s ', {'exception': e}) return utils.format_api_error( 500, _('Failed to update resource routing')) try: routing_updated = db_api.update_resource_routing( context, _id, update_dict) return {'routing': routing_updated} except Exception as e: LOG.exception( 'Failed to update resource routing: ' '%(exception)s ', {'exception': e}) return utils.format_api_error( 500, _('Failed to update resource routing'))
def put(self, _id, **kw): context = t_context.extract_context_from_environ() if not policy.enforce(context, policy.ADMIN_API_ROUTINGS_PUT): return utils.format_api_error( 403, _('Unauthorized to update resource routing')) try: db_api.get_resource_routing(context, _id) except t_exceptions.ResourceNotFound: return utils.format_api_error(404, _('Resource routing not found')) if 'routing' not in kw: return utils.format_api_error( 400, _('Request body not found')) update_dict = kw['routing'] # values to be updated should not be empty for field in update_dict: value = update_dict.get(field) if value is None or len(value.strip()) == 0: return utils.format_api_error( 400, _("Field %(field)s can not be empty") % { 'field': field}) # the resource type should be properly provisioned. if 'resource_type' in update_dict: if not constants.is_valid_resource_type( update_dict['resource_type']): return utils.format_api_error( 400, _('There is no such resource type')) # the pod with new pod_id should exist in pod table if 'pod_id' in update_dict: new_pod_id = update_dict.get('pod_id') try: # find the pod through the pod_id and verify whether it exists db_api.get_pod(context, new_pod_id) except t_exceptions.ResourceNotFound: return utils.format_api_error( 400, _("The pod %(new_pod_id)s doesn't" " exist") % {'new_pod_id': new_pod_id}) except Exception as e: LOG.exception('Failed to update resource routing: ' '%(exception)s ', {'exception': e}) return utils.format_api_error( 500, _('Failed to update resource routing')) try: routing_updated = db_api.update_resource_routing( context, _id, update_dict) return {'routing': routing_updated} except Exception as e: LOG.exception('Failed to update resource routing: ' '%(exception)s ', {'exception': e}) return utils.format_api_error( 500, _('Failed to update resource routing'))
def test_get_list_element_create_fail(self): pod = self._prepare_pod() resource_id = 'fake_resource_id' _type = 'fake_resource' ele = {'id': resource_id} body = {'name': resource_id} routing = api.create_resource_mapping(self.t_ctx, resource_id, None, pod['pod_id'], self.project_id, _type) api.update_resource_routing( self.t_ctx, routing['id'], { 'created_at': constants.expire_time, 'updated_at': constants.expire_time }) def fake_list_resource(t_ctx, q_ctx, pod, body, _type): raise q_exceptions.ConnectionFailed() self.assertRaises(q_exceptions.ConnectionFailed, lock_handle.get_or_create_element, self.t_ctx, self.q_ctx, self.project_id, pod, ele, _type, body, fake_list_resource, create_resource) # the original routing is not deleted routing = api.get_resource_routing(self.t_ctx, routing['id']) self.assertIsNone(routing['bottom_id'])
def get_one(self, _id): context = t_context.extract_context_from_environ() if not policy.enforce(context, policy.ADMIN_API_ROUTINGS_SHOW): return utils.format_api_error( 403, _('Unauthorized to show the resource routing')) try: return {'routing': db_api.get_resource_routing(context, _id)} except t_exc.ResourceNotFound: return utils.format_api_error(404, _('Resource routing not found'))
def delete(self, _id): context = t_context.extract_context_from_environ() if not policy.enforce(context, policy.ADMIN_API_ROUTINGS_DELETE): return utils.format_api_error( 403, _('Unauthorized to delete the resource routing')) try: db_api.get_resource_routing(context, _id) except t_exc.ResourceNotFound: return utils.format_api_error(404, _('Resource routing not found')) try: db_api.delete_resource_routing(context, _id) pecan.response.status = 200 return pecan.response except Exception as e: LOG.exception(_LE('Failed to delete the resource routing: ' '%(exception)s '), {'exception': e}) return utils.format_api_error( 500, _('Failed to delete the resource routing'))
def get_one(self, _id): context = t_context.extract_context_from_environ() if not policy.enforce(context, policy.ADMIN_API_ROUTINGS_SHOW): return utils.format_api_error( 403, _('Unauthorized to show the resource routing')) try: return {'routing': db_api.get_resource_routing(context, _id)} except t_exc.ResourceNotFound: return utils.format_api_error( 404, _('Resource routing not found'))
def delete(self, _id): context = t_context.extract_context_from_environ() if not policy.enforce(context, policy.ADMIN_API_ROUTINGS_DELETE): return utils.format_api_error( 403, _('Unauthorized to delete the resource routing')) try: db_api.get_resource_routing(context, _id) except t_exc.ResourceNotFound: return utils.format_api_error(404, _('Resource routing not found')) try: db_api.delete_resource_routing(context, _id) pecan.response.status = 200 return pecan.response except Exception as e: LOG.exception( _LE('Failed to delete the resource routing: ' '%(exception)s '), {'exception': e}) return utils.format_api_error( 500, _('Failed to delete the resource routing'))
def test_get_list_element_create_fail(self): pod = self._prepare_pod() resource_id = 'fake_resource_id' _type = 'fake_resource' ele = {'id': resource_id} body = {'name': resource_id} routing = api.create_resource_mapping(self.t_ctx, resource_id, None, pod['pod_id'], self.project_id, _type) api.update_resource_routing(self.t_ctx, routing['id'], {'created_at': constants.expire_time, 'updated_at': constants.expire_time}) def fake_list_resource(t_ctx, q_ctx, pod, body, _type): raise q_exceptions.ConnectionFailed() self.assertRaises( q_exceptions.ConnectionFailed, lock_handle.get_or_create_element, self.t_ctx, self.q_ctx, self.project_id, pod, ele, _type, body, fake_list_resource, create_resource) # the original routing is not deleted routing = api.get_resource_routing(self.t_ctx, routing['id']) self.assertIsNone(routing['bottom_id'])
def put(self, _id, **kw): context = t_context.extract_context_from_environ() if not policy.enforce(context, policy.ADMIN_API_ROUTINGS_PUT): return utils.format_api_error( 403, _('Unauthorized to update resource routing')) try: routing = db_api.get_resource_routing(context, _id) except t_exc.ResourceNotFound: return utils.format_api_error(404, _('Resource routing not found')) if 'routing' not in kw: return utils.format_api_error( 400, _('Request body not found')) update_dict = kw['routing'] # values to be updated should not be empty for field in update_dict: value = update_dict.get(field) if value is None or len(value.strip()) == 0: return utils.format_api_error( 400, _("Field %(field)s can not be empty") % { 'field': field}) # the resource type should be properly provisioned. if 'resource_type' in update_dict: if not constants.is_valid_resource_type( update_dict['resource_type']): return utils.format_api_error( 400, _('There is no such resource type')) # verify the integrity: the pod_id and project_id should be bound if 'pod_id' in update_dict or 'project_id' in update_dict: if 'pod_id' in update_dict: pod_id = update_dict['pod_id'] else: pod_id = routing['pod_id'] if 'project_id' in update_dict: project_id = update_dict['project_id'] else: project_id = routing['project_id'] bindings = db_api.list_pod_bindings(context, [{'key': 'pod_id', 'comparator': 'eq', 'value': pod_id }, {'key': 'tenant_id', 'comparator': 'eq', 'value': project_id} ], []) if len(bindings) == 0: return utils.format_api_error( 400, _('The pod_id and project_id have not been ' 'bound')) try: routing_updated = db_api.update_resource_routing( context, _id, update_dict) return {'routing': routing_updated} except Exception as e: LOG.exception(_LE('Failed to update resource routing: ' '%(exception)s '), {'exception': e}) return utils.format_api_error( 500, _('Failed to update resource routing'))
def test_post(self, mock_context): mock_context.return_value = self.context kw_routing = self._prepare_routing_element('subnet') id = self.controller.post(**kw_routing)['routing']['id'] routing = db_api.get_resource_routing(self.context, id) self.assertEqual('subnet', routing['resource_type']) routings = db_api.list_resource_routings(self.context, [{'key': 'resource_type', 'comparator': 'eq', 'value': 'subnet' }, ]) self.assertEqual(1, len(routings)) # failure case, only admin can create resource routing self.context.is_admin = False kw_routing = self._prepare_routing_element('subnet') res = self.controller.post(**kw_routing) self._validate_error_code(res, 403) self.context.is_admin = True # failure case, request body not found kw_routing1 = {'route': {'top_id': uuidutils.generate_uuid(), 'bottom_id': uuidutils.generate_uuid(), }} res = self.controller.post(**kw_routing1) self._validate_error_code(res, 400) # failure case, top_id is not given kw_routing2 = self._prepare_routing_element('router') kw_routing2['routing'].pop('top_id') res = self.controller.post(**kw_routing2) self._validate_error_code(res, 400) # failure case, top_id is empty kw_routing3 = self._prepare_routing_element('router') kw_routing3['routing'].update({'top_id': ''}) res = self.controller.post(**kw_routing3) self._validate_error_code(res, 400) # failure case, top_id is given value 'None' kw_routing4 = self._prepare_routing_element('security_group') kw_routing4['routing'].update({'top_id': None}) res = self.controller.post(**kw_routing4) self._validate_error_code(res, 400) # failure case, wrong resource type kw_routing6 = self._prepare_routing_element('server') self.controller.post(**kw_routing6) self._validate_error_code(res, 400) # failure case, the resource routing already exists kw_routing7 = self._prepare_routing_element('router') self.controller.post(**kw_routing7) res = self.controller.post(**kw_routing7) self._validate_error_code(res, 409)
def test_post(self, mock_context): mock_context.return_value = self.context # prepare the foreign key: pod_id kw_pod = {'pod': {'region_name': 'pod1', 'az_name': 'az1'}} pod_id = pod.PodsController().post(**kw_pod)['pod']['pod_id'] # a variable used for later test project_id = uuidutils.generate_uuid() kw_routing = { 'routing': { 'top_id': '09fd7cc9-d169-4b5a-88e8-436ecf4d0bfe', 'bottom_id': 'dc80f9de-abb7-4ec6-ab7a-94f8fd1e20ef', 'pod_id': pod_id, 'project_id': project_id, 'resource_type': 'subnet' } } id = self.controller.post(**kw_routing)['routing']['id'] routing = db_api.get_resource_routing(self.context, id) self.assertEqual('09fd7cc9-d169-4b5a-88e8-436ecf4d0bfe', routing['top_id']) self.assertEqual('dc80f9de-abb7-4ec6-ab7a-94f8fd1e20ef', routing['bottom_id']) self.assertEqual(pod_id, routing['pod_id']) self.assertEqual(project_id, routing['project_id']) self.assertEqual('subnet', routing['resource_type']) routings = db_api.list_resource_routings( self.context, [{ 'key': 'top_id', 'comparator': 'eq', 'value': '09fd7cc9-d169-4b5a-' '88e8-436ecf4d0bfe' }, { 'key': 'pod_id', 'comparator': 'eq', 'value': pod_id }], []) self.assertEqual(1, len(routings)) # failure case, only admin can create resource routing self.context.is_admin = False res = self.controller.post(**kw_routing) self._validate_error_code(res, 403) self.context.is_admin = True # failure case, request body not found kw_routing1 = { 'route': { 'top_id': '109fd7cc9-d169-4b5a-88e8-436ecf4d0bfe', 'bottom_id': '2dc80f9de-abb7-4ec6-ab7a-94f8fd1e20ef', 'pod_id': pod_id, 'project_id': project_id, 'resource_type': 'subnet' } } res = self.controller.post(**kw_routing1) self._validate_error_code(res, 400) # failure case, top_id is not given kw_routing2 = { 'routing': { 'bottom_id': '2dc80f9de-abb7-4ec6-ab7a-94f8fd1e20ef', 'pod_id': pod_id, 'project_id': project_id, 'resource_type': 'subnet' } } res = self.controller.post(**kw_routing2) self._validate_error_code(res, 400) # failure case, top_id is empty kw_routing3 = { 'routing': { 'top_id': '', 'bottom_id': '2dc80f9de-abb7-4ec6-ab7a-94f8fd1e20ef', 'pod_id': pod_id, 'project_id': project_id, 'resource_type': 'subnet' } } res = self.controller.post(**kw_routing3) self._validate_error_code(res, 400) # failure case, top_id is given value 'None' kw_routing4 = { 'routing': { 'top_id': None, 'bottom_id': '2dc80f9de-abb7-4ec6-ab7a-94f8fd1e20ef', 'pod_id': pod_id, 'project_id': project_id, 'resource_type': 'subnet' } } res = self.controller.post(**kw_routing4) self._validate_error_code(res, 400) # failure case, wrong resource type kw_routing6 = { 'routing': { 'top_id': '09fd7cc9-d169-4b5a-88e8-436ecf4d0b09', 'bottom_id': 'dc80f9de-abb7-4ec6-ab7a-94f8fd1e2031f', 'pod_id': pod_id, 'project_id': project_id, 'resource_type': 'server' } } res = self.controller.post(**kw_routing6) self._validate_error_code(res, 400) # failure case, the resource routing already exists res = self.controller.post(**kw_routing) self._validate_error_code(res, 409)
def get_all(self, **kwargs): context = t_context.extract_context_from_environ() if not policy.enforce(context, policy.ADMIN_API_ROUTINGS_LIST): return utils.format_api_error( 403, _('Unauthorized to show all resource routings')) # default value -1 means no pagination, then maximum pagination # limit from configuration will be used. _limit = kwargs.pop('limit', -1) try: limit = int(_limit) limit = utils.get_pagination_limit(limit) except ValueError as e: LOG.exception('Failed to convert pagination limit to an integer: ' '%(exception)s ', {'exception': e}) msg = (_("Limit should be an integer or a valid literal " "for int() rather than '%s'") % _limit) return utils.format_api_error(400, msg) marker = kwargs.pop('marker', None) if marker is not None: try: marker = int(marker) try: # we throw an exception if a marker with # invalid ID is specified. db_api.get_resource_routing(context, marker) except t_exceptions.ResourceNotFound: return utils.format_api_error( 400, _('Marker %s is an invalid ID') % marker) except ValueError as e: LOG.exception('Failed to convert page marker to an integer: ' '%(exception)s ', {'exception': e}) msg = (_("Marker should be an integer or a valid literal " "for int() rather than '%s'") % marker) return utils.format_api_error(400, msg) is_valid_filter, filters = self._get_filters(kwargs) if not is_valid_filter: msg = (_('Unsupported filter type: %(filters)s') % { 'filters': ', '.join( [filter_name for filter_name in filters]) }) return utils.format_api_error(400, msg) if 'id' in filters: try: # resource routing id is an integer. filters['id'] = int(filters['id']) except ValueError as e: LOG.exception('Failed to convert routing id to an integer:' ' %(exception)s ', {'exception': e}) msg = (_("Id should be an integer or a valid literal " "for int() rather than '%s'") % filters['id']) return utils.format_api_error(400, msg) # project ID from client should be equal to the one from # context, since only the project ID in which the user # is authorized will be used as the filter. filters['project_id'] = context.project_id expand_filters = [{'key': filter_name, 'comparator': 'eq', 'value': filters[filter_name]} for filter_name in filters] try: routings = db_api.list_resource_routings(context, expand_filters, limit, marker, sorts=[('id', 'desc')]) links = [] if len(routings) >= limit: marker = routings[-1]['id'] # if we reach the first element, then no elements in next page, # so link to next page won't be provided. if marker != 1: base = constants.ROUTING_PATH link = "%s?limit=%s&marker=%s" % (base, limit, marker) links.append({"rel": "next", "href": link}) result = {} result["routings"] = routings if links: result["routings_links"] = links return result except Exception as e: LOG.exception('Failed to show all resource routings: ' '%(exception)s ', {'exception': e}) return utils.format_api_error( 500, _('Failed to show all resource routings'))
def test_post(self, mock_context): mock_context.return_value = self.context # prepare the foreign key: pod_id, project_id kw_pod = {'pod': {'pod_name': 'pod1', 'az_name': 'az1'}} pod_id = pod.PodsController().post(**kw_pod)['pod']['pod_id'] kw_binding = {'pod_binding': {'tenant_id': '01', 'pod_id': pod_id}} project_id = pod.BindingsController().post(**kw_binding)[ 'pod_binding']['tenant_id'] kw_routing = {'routing': {'top_id': '09fd7cc9-d169-4b5a-88e8-436ecf4d0bfe', 'bottom_id': 'dc80f9de-abb7-4ec6-ab7a-94f8fd1e20ef', 'pod_id': pod_id, 'project_id': project_id, 'resource_type': 'subnet' }} id = self.controller.post(**kw_routing)['routing']['id'] routing = db_api.get_resource_routing(self.context, id) self.assertEqual(routing['top_id'], '09fd7cc9-d169-4b5a-88e8-436ecf4d0bfe') self.assertEqual(routing['bottom_id'], 'dc80f9de-abb7-4ec6-ab7a-94f8fd1e20ef') self.assertEqual(routing['pod_id'], pod_id) self.assertEqual(routing['project_id'], project_id) self.assertEqual(routing['resource_type'], 'subnet') routings = db_api.list_resource_routings(self.context, [{'key': 'top_id', 'comparator': 'eq', 'value': '09fd7cc9-d169-4b5a-' '88e8-436ecf4d0bfe' }, {'key': 'pod_id', 'comparator': 'eq', 'value': pod_id} ], []) self.assertEqual(len(routings), 1) # failure case, only admin can create resource routing self.context.is_admin = False res = self.controller.post(**kw_routing) self._validate_error_code(res, 403) self.context.is_admin = True # failure case, request body not found kw_routing1 = {'route': {'top_id': '109fd7cc9-d169-4b5a-88e8-436ecf4d0bfe', 'bottom_id': '2dc80f9de-abb7-4ec6-ab7a-94f8fd1e20ef', 'pod_id': pod_id, 'project_id': project_id, 'resource_type': 'subnet' }} res = self.controller.post(**kw_routing1) self._validate_error_code(res, 400) # failure case, top_id is not given kw_routing2 = {'routing': {'bottom_id': '2dc80f9de-abb7-4ec6-ab7a-94f8fd1e20ef', 'pod_id': pod_id, 'project_id': project_id, 'resource_type': 'subnet' }} res = self.controller.post(**kw_routing2) self._validate_error_code(res, 400) # failure case, top_id is empty kw_routing3 = {'routing': {'top_id': '', 'bottom_id': '2dc80f9de-abb7-4ec6-ab7a-94f8fd1e20ef', 'pod_id': pod_id, 'project_id': project_id, 'resource_type': 'subnet' }} res = self.controller.post(**kw_routing3) self._validate_error_code(res, 400) # failure case, top_id is given value 'None' kw_routing4 = {'routing': {'top_id': None, 'bottom_id': '2dc80f9de-abb7-4ec6-ab7a-94f8fd1e20ef', 'pod_id': pod_id, 'project_id': project_id, 'resource_type': 'subnet' }} res = self.controller.post(**kw_routing4) self._validate_error_code(res, 400) # failure case, the pod_id and the project_id should be bound kw_pod2 = {'pod': {'pod_name': 'pod2', 'az_name': 'az1'}} pod_id2 = pod.PodsController().post(**kw_pod2)['pod']['pod_id'] # the tenant_id binds with pod_id rather than pod_id2 kw_binding2 = {'pod_binding': {'tenant_id': '02', 'pod_id': pod_id}} project_id2 = pod.BindingsController().post(**kw_binding2)[ 'pod_binding']['tenant_id'] kw_routing5 = {'routing': {'top_id': '09fd7cc9-d169-4b5a-88e8-436ecf4d0bfe', 'bottom_id': 'dc80f9de-abb7-4ec6-ab7a-94f8fd1e20ef', 'pod_id': pod_id2, 'project_id': project_id2, 'resource_type': 'subnet' }} res = self.controller.post(**kw_routing5) self._validate_error_code(res, 400) # failure case, wrong resource type kw_routing6 = {'routing': {'top_id': '09fd7cc9-d169-4b5a-88e8-436ecf4d0b09', 'bottom_id': 'dc80f9de-abb7-4ec6-ab7a-94f8fd1e2031f', 'pod_id': pod_id, 'project_id': project_id, 'resource_type': 'server' }} res = self.controller.post(**kw_routing6) self._validate_error_code(res, 400) # failure case, the resource routing already exists res = self.controller.post(**kw_routing) self._validate_error_code(res, 409)
def get_all(self, **kwargs): context = t_context.extract_context_from_environ() if not policy.enforce(context, policy.ADMIN_API_ROUTINGS_LIST): return utils.format_api_error( 403, _('Unauthorized to show all resource routings')) # default value -1 means no pagination, then maximum pagination # limit from configuration will be used. _limit = kwargs.pop('limit', -1) try: limit = int(_limit) limit = utils.get_pagination_limit(limit) except ValueError as e: LOG.exception( 'Failed to convert pagination limit to an integer: ' '%(exception)s ', {'exception': e}) msg = (_("Limit should be an integer or a valid literal " "for int() rather than '%s'") % _limit) return utils.format_api_error(400, msg) marker = kwargs.pop('marker', None) if marker is not None: try: marker = int(marker) try: # we throw an exception if a marker with # invalid ID is specified. db_api.get_resource_routing(context, marker) except t_exceptions.ResourceNotFound: return utils.format_api_error( 400, _('Marker %s is an invalid ID') % marker) except ValueError as e: LOG.exception( 'Failed to convert page marker to an integer: ' '%(exception)s ', {'exception': e}) msg = (_("Marker should be an integer or a valid literal " "for int() rather than '%s'") % marker) return utils.format_api_error(400, msg) is_valid_filter, filters = self._get_filters(kwargs) if not is_valid_filter: msg = (_('Unsupported filter type: %(filters)s') % { 'filters': ', '.join([filter_name for filter_name in filters]) }) return utils.format_api_error(400, msg) if 'id' in filters: try: # resource routing id is an integer. filters['id'] = int(filters['id']) except ValueError as e: LOG.exception( 'Failed to convert routing id to an integer:' ' %(exception)s ', {'exception': e}) msg = (_("Id should be an integer or a valid literal " "for int() rather than '%s'") % filters['id']) return utils.format_api_error(400, msg) # project ID from client should be equal to the one from # context, since only the project ID in which the user # is authorized will be used as the filter. filters['project_id'] = context.project_id expand_filters = [{ 'key': filter_name, 'comparator': 'eq', 'value': filters[filter_name] } for filter_name in filters] try: routings = db_api.list_resource_routings(context, expand_filters, limit, marker, sorts=[('id', 'desc')]) links = [] if len(routings) >= limit: marker = routings[-1]['id'] # if we reach the first element, then no elements in next page, # so link to next page won't be provided. if marker != 1: base = constants.ROUTING_PATH link = "%s?limit=%s&marker=%s" % (base, limit, marker) links.append({"rel": "next", "href": link}) result = {} result["routings"] = routings if links: result["routings_links"] = links return result except Exception as e: LOG.exception( 'Failed to show all resource routings: ' '%(exception)s ', {'exception': e}) return utils.format_api_error( 500, _('Failed to show all resource routings'))