def test_templatized_enforcement(self): target_mine = {'project_id': 'fake'} target_not_mine = {'project_id': 'another'} action = "example:my_file" result = policy.enforce(self.context, action, target_mine) self.assertTrue(result) result = policy.enforce(self.context, action, target_not_mine) self.assertFalse(result)
def test_templatized_enforcement(self): target_mine = {'project_id': 'fake'} target_not_mine = {'project_id': 'another'} action = "example:my_file" result = policy.enforce(self.context, action, target_mine) self.assertEqual(result, True) result = policy.enforce(self.context, action, target_not_mine) self.assertEqual(result, False)
def test_ignore_case_role_check(self): lowercase_action = "example:lowercase_admin" uppercase_action = "example:uppercase_admin" admin_context = context.Context(user_id='fake', tenant_id='fake', roles=['AdMiN']) result = policy.enforce(admin_context, lowercase_action, self.target) self.assertTrue(result) result = policy.enforce(admin_context, uppercase_action, self.target) self.assertTrue(result)
def test_ignore_case_role_check(self): lowercase_action = "example:lowercase_admin" uppercase_action = "example:uppercase_admin" admin_context = context.Context(user_id='fake', tenant_id='fake', roles=['AdMiN']) result = policy.enforce(admin_context, lowercase_action, self.target) self.assertEqual(result, True) result = policy.enforce(admin_context, uppercase_action, self.target) self.assertEqual(result, True)
def get_one(self, _id): context = t_context.extract_context_from_environ() if not policy.enforce(context, policy.ADMIN_API_PODS_SHOW): pecan.abort(401, _('Unauthorized to show dci')) return try: dci = db_api.get_dci(context, _id) return_object = m.SuccessMessage(result={'dci': dci}) return return_object.to_dict() except t_exceptions.ResourceNotFound as e: LOG.exception( 'Failed to get dci: ' 'dci_id %(dci_id)s ,' '%(exception)s ', { 'dci_id': _id, 'exception': e }) return m.DCINotFound(dci_id=_id).to_dict() except Exception as e: LOG.exception('Failed to get dci: %(dci_id)s,' '%(exception)s', { 'dci_id': _id, 'exception': e }) return_object = m.FailureMessage() return return_object.to_dict()
def post(self, **kw): context = t_context.extract_context_from_environ() if not policy.enforce(context, policy.ADMIN_API_PODS_CREATE): pecan.abort(401, _('Unauthorized to create firewall_gateway')) return firewall_gateway = request.context['request_data']['firewall_gateway'] fabric = firewall_gateway.get('fabric', '').strip() firewall_id = firewall_gateway.get('firewall_id', '').strip() router_id = firewall_gateway.get('router_id', '').strip() project_id = firewall_gateway.get('project_id', '').strip() admin_state_up = firewall_gateway.get('admin_state_up', True) status = firewall_gateway.get('status', "DOWN") description = firewall_gateway.get('description', '').strip() _uuid = uuidutils.generate_uuid() try: with context.session.begin(): new_firewall_gateway = core.create_resource( context, models.FirewallGateway, { 'id': _uuid, 'fabric': fabric, 'firewall_id': firewall_id, 'router_id': router_id, 'project_id': project_id, 'admin_state_up': admin_state_up, 'status': status, 'description': description }) return_object = m.SuccessMessage( result={'firewall_gateway': new_firewall_gateway}) return return_object.to_dict() except db_exc.DBDuplicateEntry as e1: LOG.exception( 'Record firewall_gateway already exists for ' 'router_id %(router_id)s: ' 'firewall_id%(firewall_id)s: ' '%(exception)s', { 'router_id': router_id, 'firewall_id': firewall_id, 'exception': e1 }) return_object = m.FirewallGatewayExists(router_id=router_id, firewall_id=firewall_id) return return_object.to_dict() except Exception as e2: LOG.exception( 'Failed to create firewall_gateway: ' 'router_id: %(router_id)s,' 'firewall_id %(firewall_id)s: ' '%(exception)s ', { 'router_id': router_id, 'firewall_id': firewall_id, 'exception': e2 }) return_object = m.FailureMessage() return return_object.to_dict()
def get_all(self, **kwargs): """Get all the jobs. Using filters, only get a subset of jobs. :param kwargs: job filters :return: a list of jobs """ context = t_context.extract_context_from_environ() if not policy.enforce(context, policy.ADMIN_API_JOB_LIST): return utils.format_api_error( 403, _('Unauthorized to show all jobs')) 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) filters = [{'key': key, 'comparator': 'eq', 'value': value} for key, value in six.iteritems(filters)] try: jobs_in_job_table = db_api.list_jobs(context, filters) jobs_in_job_log_table = db_api.list_jobs_from_log(context, filters) jobs = jobs_in_job_table + jobs_in_job_log_table return {'jobs': [self._get_more_readable_job(job) for job in jobs]} except Exception as e: LOG.exception('Failed to show all asynchronous jobs: ' '%(exception)s ', {'exception': e}) return utils.format_api_error( 500, _('Failed to show all asynchronous jobs'))
def delete(self, _id): context = t_context.extract_context_from_environ() if not policy.enforce(context, policy.ADMIN_API_PODS_DELETE): pecan.abort(401, _('Unauthorized to delete regions')) return try: with context.session.begin(): print "MaXiao 111 delete region has dcs " region_object = core.get_resource_object(context, models.Region, _id) print "MaXiao delete region has dcs :"+str(region_result) if len(region_object.dcs)>0: raise t_exceptions.InUse("Specified region has dc(s)") core.delete_resource(context, models.Region, _id) pecan.response.status = 200 return {} except t_exceptions.InUse: return Response(_('Specified region has dcs'), 400) except t_exceptions.ResourceNotFound: return Response(_('Region not found'), 404) except Exception as e: LOG.exception('Failed to delete region: %(region_id)s,' '%(exception)s', {'region_id': _id, 'exception': e}) return Response(_('Failed to delete region'), 500)
def get_one(self, _id): context = t_context.extract_context_from_environ() if not policy.enforce(context, policy.ADMIN_API_PODS_SHOW): pecan.abort(401, _('Unauthorized to show firewall_bypass')) return try: return_object = m.SuccessMessage(result={ 'firewall_bypass': db_api.get_firewall_bypass(context, _id) }) return return_object.to_dict() except t_exceptions.ResourceNotFound as e1: LOG.exception( 'Failed to show firewall_bypass : '******'id%(id)s ,' '%(exception)s ', { 'id': _id, 'exception': e1 }) return m.FirewallBypassNotFound(id=_id).to_dict() except Exception as e2: LOG.exception( 'Failed to show firewall_bypass: '******'id: %(id)s,' '%(exception)s ', { 'id': _id, 'exception': e2 }) return_object = m.FailureMessage() return return_object.to_dict()
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 delete(self, _id): context = t_context.extract_context_from_environ() if not policy.enforce(context, policy.ADMIN_API_PODS_DELETE): pecan.abort(401, _('Unauthorized to delete firewall_bypass')) return try: with context.session.begin(): core.delete_resource(context, models.FirewallBypass, _id) return_object = m.SuccessMessage(result={}) return return_object.to_dict() except t_exceptions.ResourceNotFound as e1: LOG.exception( 'Failed to delete firewall_bypass : '******'id%(id)s ,' '%(exception)s ', { 'id': _id, 'exception': e1 }) return m.FirewallBypassNotFound(id=_id).to_dict() except Exception as e2: LOG.exception( 'Failed to delete firewall_bypass: '******'id: %(id)s,' '%(exception)s ', { 'id': _id, 'exception': e2 }) return_object = m.FailureMessage() return return_object.to_dict()
def put(self, _id, **kw): context = t_context.extract_context_from_environ() if not policy.enforce(context, policy.ADMIN_API_PODS_CREATE): pecan.abort(401, _('Unauthorized to put core_router')) return core_router = request.context['request_data']['core_router'] try: with context.session.begin(): core.get_resource(context, models.CoreRouter, _id) if 'routes' in core_router: self._update_core_router_routes(context, _id, core_router) router_updated = core.update_resource(context, models.CoreRouter, _id, core_router) return_object = m.SuccessMessage( result={'core_router': router_updated}) return return_object.to_dict() except t_exceptions.ResourceNotFound as e: LOG.exception( 'Failed to update core_router : ' 'core_router_id %(core_router_id)s ,' '%(exception)s ', { 'core_router_id': _id, 'exception': e }) return m.CoreRouterNotFound(core_router_id=_id).to_dict() except Exception as e: LOG.exception('Failed to update core_router : ' '%(exception)s ', {'exception': e}) return_object = m.FailureMessage() return return_object.to_dict()
def delete(self, _id): context = t_context.extract_context_from_environ() if not policy.enforce(context, policy.ADMIN_API_PODS_DELETE): pecan.abort(401, _('Unauthorized to delete dcs')) return try: with context.session.begin(): region_object = core.get_resource_object(context, models.DC, _id) if len(region_object.fabrics) >0: raise t_exceptions.InUse("Specified dc has fabric(s)") if len(region_object.core_routers) >0: raise t_exceptions.InUse("Specified dc has core_router(s)") core.delete_resource(context, models.DC, _id) pecan.response.status = 200 return {} except t_exceptions.InUse: return Response(_('Specified region has dcs/core_routers'), 400) except t_exceptions.ResourceNotFound: return Response(_('DC not found'), 404) except Exception as e: LOG.exception('Failed to delete dc: %(dc_id)s,' '%(exception)s', {'dc_id': _id, 'exception': e}) return Response(_('Failed to delete dc'), 500)
def delete(self, _id): context = t_context.extract_context_from_environ() if not policy.enforce(context, policy.ADMIN_API_PODS_DELETE): pecan.abort(401, _('Unauthorized to delete pods')) return try: with context.session.begin(): pod = core.get_resource(context, models.Pod, _id) if pod is not None: ag_name = utils.get_ag_name(pod['pod_name']) ag = az_ag.get_ag_by_name(context, ag_name) if ag is not None: az_ag.delete_ag(context, ag['id']) core.delete_resource(context, models.Pod, _id) pecan.response.status = 200 return {} except t_exc.ResourceNotFound: return Response(_('Pod not found'), 404) except Exception as e: LOG.exception(_LE('Failed to delete pod: %(pod_id)s,' '%(exception)s'), {'pod_id': _id, 'exception': e}) return Response(_('Failed to delete pod'), 500)
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 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 post(self, **kw): context = t_context.extract_context_from_environ() if not policy.enforce(context, policy.ADMIN_API_BINDINGS_CREATE): pecan.abort(401, _('Unauthorized to create bindings')) return if 'pod_binding' not in kw: pecan.abort(400, _('Request body not found')) return pod_b = kw['pod_binding'] tenant_id = pod_b.get('tenant_id', '').strip() pod_id = pod_b.get('pod_id', '').strip() if tenant_id == '' or pod_id == '': return Response( _('Tenant_id and pod_id can not be empty'), 422) # the az_pod_map_id should be exist for in the pod map table try: with context.session.begin(): pod = core.get_resource(context, models.Pod, pod_id) if pod.get('az_name') == '': return Response(_('Top region can not be bound'), 422) except t_exc.ResourceNotFound: return Response(_('pod_id not found in pod'), 422) except Exception as e: LOG.exception(_LE('Failed to get_resource for pod_id: ' '%(pod_id)s ,' '%(exception)s '), {'pod_id': pod_id, 'exception': e}) pecan.abort(500, _('Failed to create pod binding')) return try: pod_binding = db_api.create_pod_binding( context, tenant_id, pod_id) except db_exc.DBDuplicateEntry: return Response(_('Pod binding already exists'), 409) except db_exc.DBConstraintError: return Response(_('pod_id not exists in pod'), 422) except db_exc.DBReferenceError: return Response(_('DB reference not exists in pod'), 422) except Exception as e: LOG.exception(_LE('Failed to create pod binding: %(exception)s '), {'exception': e}) pecan.abort(500, _('Failed to create pod binding')) return return {'pod_binding': pod_binding}
def get_one(self, _id): context = t_context.extract_context_from_environ() if not policy.enforce(context, policy.ADMIN_API_PODS_SHOW): pecan.abort(401, _('Unauthorized to show pods')) return try: return {'pod': db_api.get_pod(context, _id)} except t_exc.ResourceNotFound: pecan.abort(404, _('Pod not found')) return
def get_one(self, _id): context = t_context.extract_context_from_environ() if not policy.enforce(context, policy.ADMIN_API_PODS_SHOW): pecan.abort(401, _('Unauthorized to show tricircle resource')) return try: return {'tricircle_resource': db_api.get_tricircle_resource(context, _id)} except t_exceptions.ResourceNotFound: pecan.abort(404, _('Tricircle resource not found')) return
def get_one(self, _id): context = t_context.extract_context_from_environ() if not policy.enforce(context, policy.ADMIN_API_PODS_SHOW): pecan.abort(401, _('Unauthorized to show core routers')) return try: return {'dynamic_peering_connection': db_api.get_dynamic_peering_connection(context, _id)} except t_exceptions.ResourceNotFound: pecan.abort(404, _('Dynamic Peering Connection not found')) return
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_PODS_DELETE): pecan.abort(401, _('Unauthorized to delete core_router')) return try: with context.session.begin(): core_router_object = core.get_resource_object( context, models.CoreRouter, _id) if len(core_router_object.interfaces) > 0: raise t_exceptions.CoreRouterInUseInterfacesException( core_router_id=_id, count=len(core_router_object.interfaces)) if len(core_router_object.firewall_bypasss) > 0: raise t_exceptions.CoreRouterInUseFirewallBypasssException( core_router_id=_id, count=len(core_router_object.firewall_bypasss)) core.delete_resource(context, models.CoreRouter, _id) return_object = m.SuccessMessage(result={}) return return_object.to_dict() except t_exceptions.ResourceNotFound as e: LOG.exception( 'Failed to delete core_router : ' 'core_router_id %(core_router_id)s ,' '%(exception)s ', { 'core_router_id': _id, 'exception': e }) return m.CoreRouterNotFound(core_router_id=_id).to_dict() except t_exceptions.CoreRouterInUse as e: LOG.exception( 'Failed to delete core_router: ' '%(core_router_id)s,' '%(exception)s', { 'core_router_id': _id, 'exception': e }) return_object = m.CoreRouterInUse(str(e)) return return_object.to_dict() except Exception as e: LOG.exception( 'Failed to delete core_router: ' '%(core_router_id)s,' '%(exception)s', { 'core_router_id': _id, 'exception': e }) return_object = m.FailureMessage() return return_object.to_dict()
def post(self, **kw): context = t_context.extract_context_from_environ() if not policy.enforce(context, policy.ADMIN_API_PODS_CREATE): pecan.abort(401, _('Unauthorized to create tricircle resource')) return if 'tricircle_resource' not in kw: pecan.abort(400, _('Request body tricircle_resource not found')) return tricircle_resource = request.context['request_data']['tricircle_resource'] tricircle_resource_id= tricircle_resource.get('id', '').strip() tricircle_resource_name = tricircle_resource.get('name', '').strip() region_name= tricircle_resource.get('region_name', '').strip() project_id= tricircle_resource.get('project_id', '').strip() resource_type= tricircle_resource.get('resource_type', '').strip() admin_state_up = tricircle_resource.get('admin_state_up',True) status = tricircle_resource.get('status',"DOWN") try: with context.session.begin(): new_tricircle_resource= core.create_resource( context, models.TricircleResource, {'id': tricircle_resource_id, 'name':tricircle_resource_name, 'region_name':region_name, 'resource_type':resource_type, 'project_id': project_id, 'admin_state_up':admin_state_up, 'status':status}) except db_exc.DBDuplicateEntry as e1: LOG.exception('Record already exists on' 'tricircle_resource_id%(tricircle_resource_id)s: ' '%(exception)s', {'tricircle_resource_id':tricircle_resource_id, 'exception': e1}) return Response(_('Record already exists'), 409) except Exception as e2: LOG.exception('Failed to create tricircle_resource :' 'tricircle_resource_id: %(tricircle_resource_id)s,' '%(exception)s ', {'tricircle_resource_id': tricircle_resource_id, 'exception': e2}) return Response(_('Failed to create tricircle_resource'), 500) return {'tricircle_resource': new_tricircle_resource}
def get_all(self): context = t_context.extract_context_from_environ() if not policy.enforce(context, policy.ADMIN_API_PODS_LIST): pecan.abort(401, _('Unauthorized to list pods')) return try: return {'pods': db_api.list_pods(context)} except Exception as e: LOG.exception(_LE('Failed to list all pods: %(exception)s '), {'exception': e}) pecan.abort(500, _('Failed to list pods')) return
def get_all(self): context = t_context.extract_context_from_environ() if not policy.enforce(context, policy.ADMIN_API_PODS_LIST): pecan.abort(401, _('Unauthorized to list tricircle_resources')) return try: return {'tricircle_resources': db_api.list_tricircle_resources(context)} except Exception as e: LOG.exception('Failed to list all tricircle_resources: %(exception)s ', {'exception': e}) pecan.abort(500, _('Failed to list tricircle_resources')) return
def delete(self, _id): context = t_context.extract_context_from_environ() if not policy.enforce(context, policy.ADMIN_API_BINDINGS_DELETE): pecan.abort(401, _('Unauthorized to delete bindings')) return try: with context.session.begin(): core.delete_resource(context, models.PodBinding, _id) pecan.response.status = 200 return {} except t_exc.ResourceNotFound: pecan.abort(404, _('Pod binding not found')) return
def get_all(self): context = t_context.extract_context_from_environ() if not policy.enforce(context, policy.ADMIN_API_PODS_LIST): pecan.abort(401, _('Unauthorized to list dynamic peering connection')) return try: return {'dynamic_peering_connections': db_api.list_dynamic_peering_connections(context)} except Exception as e: LOG.exception('Failed to list all dynamic_peering_connections: %(exception)s ', {'exception': e}) pecan.abort(500, _('Failed to list dynamic_peering_connections')) return
def get_all(self): context = t_context.extract_context_from_environ() if not policy.enforce(context, policy.ADMIN_API_PODS_LIST): pecan.abort(401, _('Unauthorized to list route_entry')) return try: return_object = m.SuccessMessage( result={'route_entrys': db_api.list_route_entrys(context)}) return return_object.to_dict() except Exception as e: LOG.exception('Failed to list route_entrys: ' '%(exception)s ', {'exception': e}) return_object = m.FailureMessage() return return_object.to_dict()
def get_one(self, _id): context = t_context.extract_context_from_environ() if not policy.enforce(context, policy.ADMIN_API_BINDINGS_SHOW): pecan.abort(401, _('Unauthorized to show bindings')) return try: with context.session.begin(): pod_binding = core.get_resource(context, models.PodBinding, _id) return {'pod_binding': pod_binding} except t_exc.ResourceNotFound: pecan.abort(404, _('Tenant pod binding not found')) return
def post(self, **kw): context = t_context.extract_context_from_environ() if not policy.enforce(context, policy.ADMIN_API_ROUTINGS_CREATE): return utils.format_api_error( 403, _("Unauthorized to create resource routing")) if 'routing' not in kw: return utils.format_api_error( 400, _("Request body not found")) routing = kw['routing'] for field in ('top_id', 'bottom_id', 'pod_id', 'project_id', 'resource_type'): value = routing.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. resource_type = routing.get('resource_type').strip() if not constants.is_valid_resource_type(resource_type): return utils.format_api_error( 400, _('There is no such resource type')) try: top_id = routing.get('top_id').strip() bottom_id = routing.get('bottom_id').strip() pod_id = routing.get('pod_id').strip() project_id = routing.get('project_id').strip() routing = db_api.create_resource_mapping(context, top_id, bottom_id, pod_id, project_id, resource_type) if not routing: return utils.format_api_error( 409, _('Resource routing already exists')) except Exception as e: LOG.exception('Failed to create resource routing: ' '%(exception)s ', {'exception': e}) return utils.format_api_error( 500, _('Failed to create resource routing')) return {'routing': routing}
def put(self, job_id): # we use HTTP/HTTPS PUT method to redo a job. Regularly PUT method # requires a request body, but considering the job redo operation # doesn't need more information other than job id, we will issue # this request without a request body. context = t_context.extract_context_from_environ() if not policy.enforce(context, policy.ADMIN_API_JOB_REDO): return utils.format_api_error(403, _('Unauthorized to redo a job')) try: db_api.get_job_from_log(context, job_id) return utils.format_api_error( 400, _('Job %(job_id)s is from job log') % {'job_id': job_id}) except Exception: try: job = db_api.get_job(context, job_id) except t_exc.ResourceNotFound: return utils.format_api_error( 404, _('Job %(job_id)s not found') % {'job_id': job_id}) try: # if status = RUNNING, notify user this new one and then exit if job['status'] == constants.JS_Running: return utils.format_api_error( 400, (_("Can't redo job %(job_id)s which is running") % { 'job_id': job['id'] })) # if status = SUCCESS, notify user this new one and then exit elif job['status'] == constants.JS_Success: msg = ( _("Can't redo job %(job_id)s which had run successfully") % { 'job_id': job['id'] }) return utils.format_api_error(400, msg) # if job status = FAIL or job status = NEW, redo it immediately self.xjob_handler.invoke_method(context, job['project_id'], constants.job_handles[job['type']], job['type'], job['resource_id']) except Exception as e: LOG.exception('Failed to redo the job: ' '%(exception)s ', {'exception': e}) return utils.format_api_error(500, _('Failed to redo the job'))
def get_all(self): context = t_context.extract_context_from_environ() if not policy.enforce(context, policy.ADMIN_API_BINDINGS_LIST): pecan.abort(401, _('Unauthorized to list bindings')) return try: with context.session.begin(): pod_bindings = core.query_resource(context, models.PodBinding, [], []) except Exception: pecan.abort(500, _('Fail to list tenant pod bindings')) return return {'pod_bindings': pod_bindings}
def post(self, **kw): context = t_context.extract_context_from_environ() if not policy.enforce(context, policy.ADMIN_API_ROUTINGS_CREATE): return utils.format_api_error( 403, _("Unauthorized to create resource routing")) if 'routing' not in kw: return utils.format_api_error(400, _("Request body not found")) routing = kw['routing'] for field in ('top_id', 'bottom_id', 'pod_id', 'project_id', 'resource_type'): value = routing.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. resource_type = routing.get('resource_type').strip() if not constants.is_valid_resource_type(resource_type): return utils.format_api_error(400, _('There is no such resource type')) try: top_id = routing.get('top_id').strip() bottom_id = routing.get('bottom_id').strip() pod_id = routing.get('pod_id').strip() project_id = routing.get('project_id').strip() routing = db_api.create_resource_mapping(context, top_id, bottom_id, pod_id, project_id, resource_type) if not routing: return utils.format_api_error( 409, _('Resource routing already exists')) except Exception as e: LOG.exception( _LE('Failed to create resource routing: ' '%(exception)s '), {'exception': e}) return utils.format_api_error( 500, _('Failed to create resource routing')) return {'routing': routing}
def delete(self, job_id): # delete a job from the database. If the job is running, the delete # operation will fail. In other cases, job will be deleted directly. context = t_context.extract_context_from_environ() if not policy.enforce(context, policy.ADMIN_API_JOB_DELETE): return utils.format_api_error(403, _('Unauthorized to delete a job')) try: db_api.get_job_from_log(context, job_id) return utils.format_api_error( 400, _('Job %(job_id)s is from job log') % {'job_id': job_id}) except Exception: try: job = db_api.get_job(context, job_id) except t_exc.ResourceNotFound: return utils.format_api_error( 404, _('Job %(job_id)s not found') % {'job_id': job_id}) try: # if job status = RUNNING, notify user this new one, delete # operation fails. if job['status'] == constants.JS_Running: return utils.format_api_error( 400, (_('Failed to delete the running job %(job_id)s') % { "job_id": job_id })) # if job status = SUCCESS, move the job entry to job log table, # then delete it from job table. elif job['status'] == constants.JS_Success: db_api.finish_job(context, job_id, True, timeutils.utcnow()) pecan.response.status = 200 return {} db_api.delete_job(context, job_id) pecan.response.status = 200 return {} except Exception as e: LOG.exception('Failed to delete the job: ' '%(exception)s ', {'exception': e}) return utils.format_api_error(500, _('Failed to delete the job'))
def put(self, job_id): # we use HTTP/HTTPS PUT method to redo a job. Regularly PUT method # requires a request body, but considering the job redo operation # doesn't need more information other than job id, we will issue # this request without a request body. context = t_context.extract_context_from_environ() if not policy.enforce(context, policy.ADMIN_API_JOB_REDO): return utils.format_api_error( 403, _('Unauthorized to redo a job')) try: db_api.get_job_from_log(context, job_id) return utils.format_api_error( 400, _('Job %(job_id)s is from job log') % {'job_id': job_id}) except Exception: try: job = db_api.get_job(context, job_id) except t_exc.ResourceNotFound: return utils.format_api_error( 404, _('Job %(job_id)s not found') % {'job_id': job_id}) try: # if status = RUNNING, notify user this new one and then exit if job['status'] == constants.JS_Running: return utils.format_api_error( 400, (_("Can't redo job %(job_id)s which is running") % {'job_id': job['id']})) # if status = SUCCESS, notify user this new one and then exit elif job['status'] == constants.JS_Success: msg = (_("Can't redo job %(job_id)s which had run successfully" ) % {'job_id': job['id']}) return utils.format_api_error(400, msg) # if job status = FAIL or job status = NEW, redo it immediately self.xjob_handler.invoke_method(context, job['project_id'], constants.job_handles[job['type']], job['type'], job['resource_id']) except Exception as e: LOG.exception('Failed to redo the job: ' '%(exception)s ', {'exception': e}) return utils.format_api_error( 500, _('Failed to redo the job'))
def get_one(self, id, **kwargs): """the return value may vary according to the value of id :param id: 1) if id = 'schemas', return job schemas 2) if id = 'detail', return all jobs 3) if id = $job_id, return detailed single job info :return: return value is decided by id parameter """ context = t_context.extract_context_from_environ() job_resource_map = constants.job_resource_map if not policy.enforce(context, policy.ADMIN_API_JOB_SCHEMA_LIST): return utils.format_api_error( 403, _('Unauthorized to show job information')) if id == 'schemas': job_schemas = [] for job_type in job_resource_map.keys(): job = {} resource = [] for resource_type, resource_id in job_resource_map[job_type]: resource.append(resource_id) job['resource'] = resource job['type'] = job_type job_schemas.append(job) return {'schemas': job_schemas} if id == 'detail': return self.get_all(**kwargs) try: job = db_api.get_job(context, id) return {'job': self._get_more_readable_job(job)} except Exception: try: job = db_api.get_job_from_log(context, id) return {'job': self._get_more_readable_job(job)} except t_exc.ResourceNotFound: return utils.format_api_error( 404, _('Resource not found'))
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 to show all resource routings')) filters = self._get_filters(kwargs) filters = [{'key': key, 'comparator': 'eq', 'value': value} for key, value in filters.iteritems()] try: return {'routings': db_api.list_resource_routings(context, filters)} except Exception as e: LOG.exception(_LE('Failed to show all resource routings: ' '%(exception)s '), {'exception': e}) return utils.format_api_error( 500, _('Failed to show all resource routings'))
def delete(self, job_id): # delete a job from the database. If the job is running, the delete # operation will fail. In other cases, job will be deleted directly. context = t_context.extract_context_from_environ() if not policy.enforce(context, policy.ADMIN_API_JOB_DELETE): return utils.format_api_error( 403, _('Unauthorized to delete a job')) try: db_api.get_job_from_log(context, job_id) return utils.format_api_error( 400, _('Job %(job_id)s is from job log') % {'job_id': job_id}) except Exception: try: job = db_api.get_job(context, job_id) except t_exc.ResourceNotFound: return utils.format_api_error( 404, _('Job %(job_id)s not found') % {'job_id': job_id}) try: # if job status = RUNNING, notify user this new one, delete # operation fails. if job['status'] == constants.JS_Running: return utils.format_api_error( 400, (_('Failed to delete the running job %(job_id)s') % {"job_id": job_id})) # if job status = SUCCESS, move the job entry to job log table, # then delete it from job table. elif job['status'] == constants.JS_Success: db_api.finish_job(context, job_id, True, timeutils.utcnow()) pecan.response.status = 200 return {} db_api.delete_job(context, job_id) pecan.response.status = 200 return {} except Exception as e: LOG.exception('Failed to delete the job: ' '%(exception)s ', {'exception': e}) return utils.format_api_error( 500, _('Failed to delete the job'))
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 delete(self, _id): context = t_context.extract_context_from_environ() if not policy.enforce(context, policy.ADMIN_API_PODS_DELETE): pecan.abort(401, _('Unauthorized to delete dynamic_peering_connections')) return try: with context.session.begin(): core.delete_resource(context, models.DynamicPeeringConnection, _id) pecan.response.status = 200 return {} except t_exceptions.ResourceNotFound: return Response(_('Dynamic Peering Connection not found'), 404) except Exception as e: LOG.exception('Failed to delete dynamic_peering_connection: %(dynamic_peering_connection_id)s,' '%(exception)s', {'dynamic_peering_connection_id': _id, 'exception': e}) return Response(_('Failed to delete dynamic_peering_connection'), 500)
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 delete(self, _id): context = t_context.extract_context_from_environ() if not policy.enforce(context, policy.ADMIN_API_PODS_DELETE): pecan.abort(401, _('Unauthorized to delete pods')) return try: with context.session.begin(): core.delete_resource(context, models.Pod, _id) pecan.response.status = 200 return {} except t_exceptions.ResourceNotFound: return Response(_('Pod not found'), 404) except Exception as e: LOG.exception('Failed to delete pod: %(pod_id)s,' '%(exception)s', {'pod_id': _id, 'exception': e}) return Response(_('Failed to delete pod'), 500)
def get_one(self, _id): context = t_context.extract_context_from_environ() if not policy.enforce(context, policy.ADMIN_API_PODS_SHOW): pecan.abort(401, _('Unauthorized to show core_router')) return try: core_router = db_api.get_core_router(context, _id) return_object = m.SuccessMessage( result={'core_router': core_router}) return return_object.to_dict() except t_exceptions.ResourceNotFound as e: LOG.exception( 'Failed to get core_router : ' 'core_router_id %(core_router_id)s ,' '%(exception)s ', { 'core_router_id': _id, 'exception': e }) return m.CoreRouterNotFound(core_router_id=_id).to_dict()
def delete(self, _id): context = t_context.extract_context_from_environ() if not policy.enforce(context, policy.ADMIN_API_PODS_DELETE): pecan.abort(401, _('Unauthorized to delete tricircle_resources')) return try: with context.session.begin(): core.delete_resource(context, models.TricircleResource, _id) pecan.response.status = 200 return {} except t_exceptions.ResourceNotFound: return Response(_('Firewall gateway not found'), 404) except Exception as e: LOG.exception('Failed to delete tricircle_resource: %(tricircle_resource_id)s,' '%(exception)s', {'tricircle_resource_id': _id, 'exception': e}) return Response(_('Failed to delete tricircle_resource'), 500)
def delete(self, _id): context = t_context.extract_context_from_environ() if not policy.enforce(context, policy.ADMIN_API_PODS_DELETE): pecan.abort(401, _('Unauthorized to delete pods')) return try: with context.session.begin(): core.delete_resource(context, models.Pod, _id) pecan.response.status = 200 return {} except t_exc.ResourceNotFound: return Response(_('Pod not found'), 404) except Exception as e: LOG.exception( _LE('Failed to delete pod: %(pod_id)s,' '%(exception)s'), { 'pod_id': _id, 'exception': e }) return Response(_('Failed to delete pod'), 500)
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')) filters = self._get_filters(kwargs) filters = [{ 'key': key, 'comparator': 'eq', 'value': value } for key, value in six.iteritems(filters)] try: return { 'routings': db_api.list_resource_routings(context, filters) } except Exception as e: LOG.exception( _LE('Failed to show all resource routings: ' '%(exception)s '), {'exception': e}) return utils.format_api_error( 500, _('Failed to show all resource routings'))
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_early_OR_enforcement(self): action = "example:early_or_success" result = policy.enforce(self.context, action, self.target) self.assertEqual(result, True)
def test_early_AND_enforcement(self): action = "example:early_and_fail" result = policy.enforce(self.context, action, self.target) self.assertEqual(result, False)
def test_enforce_good_action(self): action = "example:allowed" result = policy.enforce(self.context, action, self.target) self.assertEqual(result, True)
def test_enforce_bad_action_throws(self): action = "example:denied" result = policy.enforce(self.context, action, self.target) self.assertEqual(result, False)
def test_enforce_nonexistent_action_throws(self): action = "example:non_exist" result = policy.enforce(self.context, action, self.target) self.assertEqual(result, False)
def test_default_not_found(self): self._set_rules("default_noexist") result = policy.enforce(self.context, "example:noexist", {}) self.assertEqual(result, False)
def test_not_found_policy_calls_default(self): result = policy.enforce(self.context, "example:noexist", {}) self.assertEqual(result, True)
def test_policy_called(self): result = policy.enforce(self.context, "example:exist", {}) self.assertEqual(result, False)
def post(self, **kw): context = t_context.extract_context_from_environ() job_resource_map = constants.job_resource_map if not policy.enforce(context, policy.ADMIN_API_JOB_CREATE): return utils.format_api_error( 403, _("Unauthorized to create a job")) if 'job' not in kw: return utils.format_api_error( 400, _("Request body not found")) job = kw['job'] for field in ('type', 'project_id'): value = job.get(field) if value is None: return utils.format_api_error( 400, _("%(field)s isn't provided in request body") % { 'field': field}) elif len(value.strip()) == 0: return utils.format_api_error( 400, _("%(field)s can't be empty") % {'field': field}) if job['type'] not in job_resource_map.keys(): return utils.format_api_error( 400, _('There is no such job type: %(job_type)s') % { 'job_type': job['type']}) job_type = job['type'] project_id = job['project_id'] if 'resource' not in job: return utils.format_api_error( 400, _('Failed to create job, because the resource is not' ' specified')) # verify that all given resources are exactly needed request_fields = set(job['resource'].keys()) require_fields = set([resource_id for resource_type, resource_id in job_resource_map[job_type]]) missing_fields = require_fields - request_fields redundant_fields = request_fields - require_fields if missing_fields: return utils.format_api_error( 400, _('Some required fields are not specified:' ' %(field)s') % {'field': missing_fields}) if redundant_fields: return utils.format_api_error( 400, _('Some fields are redundant: %(field)s') % { 'field': redundant_fields}) # validate whether the project id is legal resource_type_1, resource_id_1 = ( constants.job_primary_resource_map[job_type]) if resource_type_1 is not None: filter = [{'key': 'project_id', 'comparator': 'eq', 'value': project_id}, {'key': 'resource_type', 'comparator': 'eq', 'value': resource_type_1}, {'key': 'top_id', 'comparator': 'eq', 'value': job['resource'][resource_id_1]}] routings = db_api.list_resource_routings(context, filter) if not routings: msg = (_("%(resource)s %(resource_id)s doesn't belong to the" " project %(project_id)s") % {'resource': resource_type_1, 'resource_id': job['resource'][resource_id_1], 'project_id': project_id}) return utils.format_api_error(400, msg) # if job_type = seg_rule_setup, we should ensure the project id # is equal to the one from resource. if job_type in (constants.JT_SEG_RULE_SETUP, constants.JT_RESOURCE_RECYCLE): if job['project_id'] != job['resource']['project_id']: msg = (_("Specified project_id %(project_id_1)s and resource's" " project_id %(project_id_2)s are different") % {'project_id_1': job['project_id'], 'project_id_2': job['resource']['project_id']}) return utils.format_api_error(400, msg) # combine uuid into target resource id resource_id = '#'.join([job['resource'][resource_id] for resource_type, resource_id in job_resource_map[job_type]]) try: # create a job and put it into execution immediately self.xjob_handler.invoke_method(context, project_id, constants.job_handles[job_type], job_type, resource_id) except Exception as e: LOG.exception('Failed to create job: ' '%(exception)s ', {'exception': e}) return utils.format_api_error( 500, _('Failed to create a job')) new_job = db_api.get_latest_job(context, constants.JS_New, job_type, resource_id) return {'job': self._get_more_readable_job(new_job)}
def get_all(self, **kwargs): """Get all the jobs. Using filters, only get a subset of jobs. :param kwargs: job filters :return: a list of jobs """ context = t_context.extract_context_from_environ() if not policy.enforce(context, policy.ADMIN_API_JOB_LIST): return utils.format_api_error( 403, _('Unauthorized to show all jobs')) # check limit and marker, default value -1 means no pagination _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) sorts = [('timestamp', 'desc'), ('id', 'desc')] 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) # 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 filters = [{'key': key, 'comparator': 'eq', 'value': value} for key, value in six.iteritems(filters)] try: if marker is not None: try: # verify whether the marker is effective db_api.get_job(context, marker) jobs = db_api.list_jobs(context, filters, sorts, limit, marker) jobs_from_log = [] if len(jobs) < limit: jobs_from_log = db_api.list_jobs_from_log( context, filters, sorts, limit - len(jobs), None) job_collection = jobs + jobs_from_log except t_exc.ResourceNotFound: try: db_api.get_job_from_log(context, marker) jobs_from_log = db_api.list_jobs_from_log( context, filters, sorts, limit, marker) job_collection = jobs_from_log except t_exc.ResourceNotFound: msg = (_('Invalid marker: %(marker)s') % {'marker': marker}) return utils.format_api_error(400, msg) else: jobs = db_api.list_jobs(context, filters, sorts, limit, marker) jobs_from_log = [] if len(jobs) < limit: jobs_from_log = db_api.list_jobs_from_log( context, filters, sorts, limit - len(jobs), None) job_collection = jobs + jobs_from_log # add link links = [] if len(job_collection) >= limit: marker = job_collection[-1]['id'] base = constants.JOB_PATH link = "%s?limit=%s&marker=%s" % (base, limit, marker) links.append({"rel": "next", "href": link}) result = {'jobs': [self._get_more_readable_job(job) for job in job_collection]} if links: result['jobs_links'] = links return result except Exception as e: LOG.exception('Failed to show all asynchronous jobs: ' '%(exception)s ', {'exception': e}) return utils.format_api_error( 500, _('Failed to show all asynchronous jobs'))
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'))