def media_type_accept(request, content_types): """Validate media types against request.method. When request.method is GET or HEAD compare with the Accept header. When request.method is POST, PUT or PATCH compare with the Content-Type header. When request.method is DELETE media type is irrelevant, so return True. """ if request.method in ['GET', 'HEAD']: if request.accept: if request.accept.best_match(content_types): return True error_message = ('Unacceptable Accept type: %s not in %s' % (request.accept, content_types)) raise ClientSideError(error_message, status_code=406) elif request.method in ['PUT', 'POST', 'PATCH']: content_type = request.headers.get('Content-Type') if content_type: for ct in content_types: if request.headers.get('Content-Type', '').startswith(ct): return True error_message = ('Unacceptable Content-Type: %s not in %s' % (content_type, content_types)) raise ClientSideError(error_message, status_code=415) else: raise ClientSideError('missing Content-Type header') elif request.method in ['DELETE']: return True return False
def put(self, body=None): """ Updates a device entry in devices table with new status. Also, updates status of loadbalancers using this device with ERROR or ACTIVE and the errmsg field :param - NOTE the _lookup() hack used to get the device id Url: PUT /devices/<device ID> JSON Request Body { "status": <ERROR | ONLINE> "statusDescription": "Error Description" } Returns: None """ if not self.devid: raise ClientSideError('Device ID is required') with db_session() as session: device = session.query(Device).\ filter(Device.id == self.devid).first() if not device: session.rollback() raise ClientSideError('Device ID is not valid') device.status = body.status session.flush() lb_status = 'ACTIVE' if body.status == 'ONLINE' else body.status lb_descr = body.statusDescription # Now find LB's associated with this Device and update their status lbs = session.query( loadbalancers_devices.c.loadbalancer).\ filter(loadbalancers_devices.c.device == self.devid).\ all() for lb in lbs: session.query(LoadBalancer).\ filter(LoadBalancer.id == lb[0]).\ update({"status": lb_status, "errmsg": lb_descr}, synchronize_session='fetch') session.flush() session.commit() return
def args_from_body(funcdef, body, mimetype): from wsme.rest import json as restjson from wsme.rest import xml as restxml if funcdef.body_type is not None: datatypes = {funcdef.arguments[-1].name: funcdef.body_type} else: datatypes = dict(((a.name, a.datatype) for a in funcdef.arguments)) if not body: return (), {} if mimetype == "application/x-www-form-urlencoded": # the parameters should have been parsed in params return (), {} elif mimetype in restjson.accept_content_types: dataformat = restjson elif mimetype in restxml.accept_content_types: dataformat = restxml elif mimetype == 'multipart/form-data': return parse_multipart_data_from_body(datatypes, params) else: raise ClientSideError("Unknown mimetype: %s" % mimetype, status_code=415) try: kw = dataformat.parse(body, datatypes, bodyarg=funcdef.body_type is not None) except UnknownArgument: if not funcdef.ignore_extra_args: raise kw = {} return (), kw
def combine_args(funcdef, akw, allow_override=False): newargs, newkwargs = [], {} for args, kwargs in akw: for i, arg in enumerate(args): n = funcdef.arguments[i].name if not allow_override and n in newkwargs: raise ClientSideError("Parameter %s was given several times" % n) newkwargs[n] = arg for name, value in kwargs.items(): n = str(name) if not allow_override and n in newkwargs: raise ClientSideError("Parameter %s was given several times" % n) newkwargs[n] = value return newargs, newkwargs
def team_delete_user(team_id, user_id): session = api_base.get_session() with session.begin(subtransactions=True): team = _entity_get(team_id, session) if team is None: raise exc.NotFound(_("Team %s not found") % team_id) user = users.user_get(user_id) if user is None: raise exc.NotFound(_("User %s not found") % user_id) if user_id not in [u.id for u in team.users]: raise ClientSideError( _("The User %(user_id)d is not in " "Team %(team_id)d") % { 'user_id': user_id, 'team_id': team_id }) user_entry = [u for u in team.users if u.id == user_id][0] team.users.remove(user_entry) session.add(team) return team
def _select_protocol(self, request): log.debug( "Selecting a protocol for the following request :\n" "headers: %s\nbody: %s", request.headers.items(), request.content_length and (request.content_length > 512 and request.body[:512] or request.body) or '') protocol = None error = ClientSideError(status_code=406) path = str(request.path) assert path.startswith(self._webpath) path = path[len(self._webpath) + 1:] if 'wsmeproto' in request.params: return self._get_protocol(request.params['wsmeproto']) else: for p in self.protocols: try: if p.accept(request): protocol = p break except ClientSideError as e: error = e # If we could not select a protocol, we raise the last exception # that we got, or the default one. if not protocol: raise error return protocol
def project_group_add_project(project_group_id, project_id): session = api_base.get_session() with session.begin(subtransactions=True): project_group = _entity_get(project_group_id, session) if project_group is None: raise exc.NotFound( _("%(name)s %(id)s not found") % { 'name': "Project Group", 'id': project_group_id }) project = projects.project_get(project_id) if project is None: raise exc.NotFound( _("%(name)s %(id)s not found") % { 'name': "Project", 'id': project_id }) if project_id in [p.id for p in project_group.projects]: raise ClientSideError( _("The Project %(id)d is already in " "Project Group %(group_id)d") % { 'id': project_id, 'group_id': project_group_id }) project_group.projects.append(project) session.add(project_group) return project_group
def project_group_delete_project(project_group_id, project_id): session = api_base.get_session() with session.begin(subtransactions=True): project_group = _entity_get(project_group_id, session) if project_group is None: raise exc.NotFound( _("%(name)s %(id)s not found") % { 'name': "Project Group", 'id': project_group_id }) project = projects.project_get(project_id) if project is None: raise exc.NotFound( _("%(name)s %(id)s not found") % { 'name': "Project", 'id': project_id }) if project_id not in [p.id for p in project_group.projects]: raise ClientSideError( _("The Project %(id)d is not in " "Project Group %(group_id)d") % { 'id': project_id, 'group_id': project_group_id }) project_entry = [ p for p in project_group.projects if p.id == project_id ][0] project_group.projects.remove(project_entry) session.add(project_group) return project_group
def update_lane(board, lane, new_lane): # Make sure we aren't messing up the board ID new_lane['board_id'] = board.id if new_lane.get('list_id') is None: raise ClientSideError(_("A lane must have a worklist_id.")) api_base.entity_update(models.BoardWorklist, lane.id, new_lane)
def add_item(worklist_id, item_id, item_type, list_position, current_user=None): worklist = _worklist_get(worklist_id) if worklist is None: raise exc.NotFound(_("Worklist %s not found") % worklist_id) # Check if this item has an archived card in this worklist to restore archived = get_item_by_item_id( worklist, item_type, item_id, archived=True) if archived: update = { 'archived': False, 'list_position': list_position } api_base.entity_update(models.WorklistItem, archived.id, update) return worklist # If this worklist is a lane, check if the item has an archived card # somewhere in the board to restore if is_lane(worklist): board = boards.get_from_lane(worklist) archived = boards.get_card(board, item_type, item_id, archived=True) if archived: update = { 'archived': False, 'list_id': worklist_id, 'list_position': list_position } api_base.entity_update(models.WorklistItem, archived.id, update) return worklist # Create a new card if item_type == 'story': item = stories_api.story_get(item_id, current_user=current_user) elif item_type == 'task': item = tasks_api.task_get(item_id, current_user=current_user) else: raise ClientSideError(_("An item in a worklist must be either a " "story or a task")) if item is None: raise exc.NotFound(_("%(type)s %(id)s not found") % {'type': item_type, 'id': item_id}) item_dict = { 'list_id': worklist_id, 'item_id': item_id, 'item_type': item_type, 'list_position': list_position } worklist_item = api_base.entity_create(models.WorklistItem, item_dict) if worklist.items is None: worklist.items = [worklist_item] else: worklist.items.append(worklist_item) return worklist
def post(self, body=None): if self.lbid is None: raise ClientSideError('Load Balancer ID has not been supplied') tenant_id = get_limited_to_project(request.headers) with db_session() as session: load_balancer = session.query(LoadBalancer).\ filter(LoadBalancer.tenantid == tenant_id).\ filter(LoadBalancer.id == self.lbid).\ filter(LoadBalancer.status != 'DELETED').\ first() if load_balancer is None: session.rollback() raise NotFound('Load Balancer not found') if load_balancer.status in ImmutableStates: session.rollback() raise ImmutableEntity( 'Cannot get logs from a Load Balancer in a non-ACTIVE ' 'state, current state: {0}'.format(load_balancer.status) ) load_balancer.status = 'PENDING_UPDATE' device = session.query( Device.id, Device.name, Device.status ).join(LoadBalancer.devices).\ filter(LoadBalancer.id == self.lbid).\ first() session.commit() data = { 'deviceid': device.id } if body.objectStoreType != Unset: data['objectStoreType'] = body.objectStoreType.lower() else: data['objectStoreType'] = 'swift' if body.objectStoreBasePath != Unset: data['objectStoreBasePath'] = body.objectStoreBasePath else: data['objectStoreBasePath'] = conf.swift.swift_basepath if body.objectStoreEndpoint != Unset: data['objectStoreEndpoint'] = body.objectStoreEndpoint else: data['objectStoreEndpoint'] = '{0}/{1}'.\ format(conf.swift.swift_endpoint.rstrip('/'), tenant_id) if body.authToken != Unset: data['authToken'] = body.authToken else: data['authToken'] = request.headers.get('X-Auth-Token') submit_job( 'ARCHIVE', device.name, data, self.lbid ) return
def test_replace_regions_specific_region(self): regions.err_utils.get_error = mock.MagicMock( return_value=ClientSideError("blabla", 405)) response = self.app.put_json( '/v1/orm/customers/{customer id}/regions/test', REGION_JSON, expect_errors=True) self.assertEqual(response.status_int, 405)
def put(self, body=None): if not self.lbid: raise ClientSideError('Load Balancer ID is required') tenant_id = get_limited_to_project(request.headers) with db_session() as session: # grab the lb lb = session.query(LoadBalancer).\ filter(LoadBalancer.id == self.lbid).\ filter(LoadBalancer.tenantid == tenant_id).\ filter(LoadBalancer.status != 'DELETED').first() if lb is None: session.rollback() raise NotFound('Load Balancer ID is not valid') if lb.status in ImmutableStates: session.rollback() raise ImmutableEntity( 'Cannot modify a Load Balancer in a non-ACTIVE state' ', current state: {0}'.format(lb.status)) if body.name != Unset: namelimit = session.query(Limits.value).\ filter(Limits.name == 'maxLoadBalancerNameLength').scalar() if len(body.name) > namelimit: session.rollback() raise ClientSideError( 'Length of Load Balancer name too long') lb.name = body.name if body.algorithm != Unset: lb.algorithm = body.algorithm lb.status = 'PENDING_UPDATE' device = session.query( Device.id, Device.name, Device.status ).join(LoadBalancer.devices).\ filter(LoadBalancer.id == self.lbid).\ first() session.commit() submit_job('UPDATE', device.name, device.id, lb.id) return ''
def get_error(transaction_id, status_code, error_details=None, message=None): return ClientSideError(json.dumps({ 'code': status_code, 'type': 'test', 'created': '0.0', 'transaction_id': transaction_id, 'message': message if message else error_details, 'details': 'test' }), status_code=status_code)
class TestCreateGroup(FunctionalTest): """Main create_group test case.""" # @patch.object(groups, 'request') # @patch.object(groups.GroupService, 'create_group_in_db') # @patch.object(groups, 'authentication') # def test_post_success(self, mock_authentication, mock_create_group, # mock_request): # """Test successful group creation.""" # mock_request.application_url = 'http://localhost' # response = self.app.post_json('/v2/orm/groups', # {'id': 'd', 'name': 'a', # 'description': 'b', # 'regions': ['c']}) # # Make sure all keys are in place # self.assertTrue(all([c in response.json['group'] for c in ( # 'created', 'id', 'links')])) # self.assertEqual(response.json['group']['id'], 'd') # self.assertEqual(response.json['group']['name'], 'a') # self.assertEqual(response.json['group']['links']['self'], # 'http://localhost/v2/orm/groups/d') @patch.object(groups.GroupService, 'create_group_in_db', side_effect=groups.error_base.ConflictError) @patch.object(groups.err_utils, 'get_error', return_value=ClientSideError(json.dumps({ 'code': 409, 'type': 'test', 'created': '0.0', 'transaction_id': '333', 'message': 'test', 'details': 'test' }), status_code=409)) @patch.object(groups, 'authentication') def test_post_group_already_exists(self, mock_auth, get_err, mock_create_group): """Make sure the function returns status code 409 if group exists.""" temp_request = groups.request groups.request = MagicMock() response = self.app.post_json('/v2/orm/groups', { 'id': 'noq', 'name': 'poq', 'description': 'b', 'regions': ['c'] }, expect_errors=True) groups.request = temp_request self.assertEqual(response.status_code, 409)
def test_get_list_customer_bad_request(self): # given requests.get = mock.MagicMock() root.CustomerLogic.return_error = 2 root.err_utils.get_error = mock.MagicMock(return_value=ClientSideError("blabla", 500)) # when response = self.app.get('/v1/orm/customers?region=region', expect_errors=True) # assert self.assertEqual(response.status_int, 500)
def add_lane(board, lane_dict): # Make sure we're adding the lane to the right board lane_dict['board_id'] = board.id if lane_dict.get('list_id') is None: raise ClientSideError(_("A lane must have a worklist_id.")) if lane_dict.get('position') is None: lane_dict['position'] = len(board.lanes) api_base.entity_create(models.BoardWorklist, lane_dict) return board
def test_update_customer_fail_bad_request(self): # given requests.put = mock.MagicMock() root.CustomerLogic.return_error = 2 root.err_utils.get_error = mock.MagicMock(return_value=ClientSideError("blabla", 404)) # when response = self.app.put_json('/v1/orm/customers/some_id', CUSTOMER_JSON, expect_errors=True) # assert self.assertEqual(response.status_int, 404)
def test_create_customer_fail(self): # given requests.post = mock.MagicMock() root.CustomerLogic.return_error = 1 root.err_utils.get_error = mock.MagicMock(return_value=ClientSideError("blabla", 500)) # when response = self.app.post_json('/v1/orm/customers', CUSTOMER_JSON, expect_errors=True) # assert self.assertEqual(response.status_int, 500)
def test_get_customer_fail(self): # given requests.put = mock.MagicMock() root.CustomerLogic.return_error = 2 root.err_utils.get_error = mock.MagicMock(return_value=ClientSideError("blabla", 404)) # when response = self.app.get('/v1/orm/customers/some_id', expect_errors=True) # assert self.assertEqual(response.status_int, 404) assert customer_logic_mock.get_customer.called
def test_create_flavor_duplicate_uuid(self): CUSTOMER_JSON['custId'] = 'test' create_existing_uuid = root.utils.create_existing_uuid root.utils.create_existing_uuid = mock.MagicMock(side_effect=TypeError('test')) root.err_utils.get_error = mock.MagicMock(return_value=ClientSideError("blabla", 409)) response = self.app.post_json('/v1/orm/customers', CUSTOMER_JSON, expect_errors=True) root.utils.create_existing_uuid = create_existing_uuid del CUSTOMER_JSON['custId'] self.assertEqual(response.status_int, 409)
def test_create_flavor_other_error(self, mock_customerlogic): my_mock = mock.MagicMock() my_mock.create_customer = mock.MagicMock( side_effect=sqlalchemy.exc.IntegrityError( 'a', 'b', 'test \'customer\' for key \'name_idx\'')) mock_customerlogic.return_value = my_mock root.err_utils.get_error = mock.MagicMock(return_value=ClientSideError("blabla", 500)) response = self.app.post_json('/v1/orm/customers', CUSTOMER_JSON, expect_errors=True) self.assertEqual(response.status_int, 500)
def delete(self): """Remove the health monitor. :param load_balancer_id: id of lb Url: DELETE /loadbalancers/{load_balancer_id}/healthmonitor Returns: void """ if not self.lbid: raise ClientSideError('Load Balancer ID has not been supplied') tenant_id = get_limited_to_project(request.headers) with db_session() as session: query = session.query( LoadBalancer, HealthMonitor ).outerjoin(LoadBalancer.monitors).\ filter(LoadBalancer.tenantid == tenant_id).\ filter(LoadBalancer.id == self.lbid).\ filter(LoadBalancer.status != 'DELETED').\ first() if query is None: session.rollback() raise NotFound("Load Balancer not found") lb, monitor = query if lb is None: session.rollback() raise NotFound("Load Balancer not found") if monitor is not None: session.delete(monitor) session.flush() device = session.query( Device.id, Device.name ).join(LoadBalancer.devices).\ filter(LoadBalancer.id == self.lbid).\ first() counter = session.query(Counters).\ filter(Counters.name == 'api_healthmonitor.delete').first() counter.value += 1 session.commit() submit_job('UPDATE', device.name, device.id, self.lbid) return None
def test_replace_default_users_fail(self): # given requests.put = mock.MagicMock() users.CustomerLogic.return_error = 1 users.err_utils.get_error = mock.MagicMock( return_value=ClientSideError("blabla", 500)) # when response = self.app.put_json('/v1/orm/customers/{customer id}/users/', USER_JSON, expect_errors=True) # assert self.assertEqual(response.status_int, 500)
def update_permission(due_date_id, permission_dict): due_date = _due_date_get(due_date_id) id = None for permission in due_date.permissions: if permission.codename == permission_dict['codename']: id = permission.id users = permission_dict.pop('users') permission_dict['users'] = [] for user_id in users: user = users_api.user_get(user_id) permission_dict['users'].append(user) if id is None: raise ClientSideError(_("Permission %s does not exist") % permission_dict['codename']) return api_base.entity_update(models.Permission, id, permission_dict)
def test_delete_regions_fail(self): # given requests.delete = mock.MagicMock() regions.CustomerLogic.return_error = 2 regions.err_utils.get_error = mock.MagicMock( return_value=ClientSideError("blabla", 404)) # when response = self.app.delete( '/v1/orm/customers/{customer id}/regions/{region_id}', expect_errors=True) # assert self.assertEqual(response.status_int, 404)
def test_delete_default_user_fail(self): # given requests.delete = mock.MagicMock() users.CustomerLogic.return_error = 1 users.err_utils.get_error = mock.MagicMock( return_value=ClientSideError("blabla", 500)) # when response = self.app.delete( '/v1/orm/customers/{customer id}/users/{user_id}', expect_errors=True) # assert self.assertEqual(response.status_int, 500)
def test_add_regions_fail_bad(self): # given requests.post = mock.MagicMock() regions.CustomerLogic.return_error = 2 regions.err_utils.get_error = mock.MagicMock( return_value=ClientSideError("blabla", 404)) # when response = self.app.post_json( '/v1/orm/customers/{customer id}/regions/', REGION_JSON, expect_errors=True) # assert self.assertEqual(response.status_int, 404)
def get(self): """Retrieve the health monitor configuration, if one exists. Url: GET /loadbalancers/{load_balancer_id}/healthmonitor Returns: dict """ if not self.lbid: raise ClientSideError('Load Balancer ID has not been supplied') tenant_id = get_limited_to_project(request.headers) with db_session() as session: # grab the lb monitor = session.query( HealthMonitor.type, HealthMonitor.delay, HealthMonitor.timeout, HealthMonitor.attempts, HealthMonitor.path ).join(LoadBalancer.monitors).\ filter(LoadBalancer.id == self.lbid).\ filter(LoadBalancer.tenantid == tenant_id).\ filter(LoadBalancer.status != 'DELETED').\ first() response.status = 200 if monitor is None: session.rollback() return {} monitor_data = { 'type': monitor.type, 'delay': monitor.delay, 'timeout': monitor.timeout, 'attemptsBeforeDeactivation': monitor.attempts } if monitor.path: monitor_data['path'] = monitor.path counter = session.query(Counters).\ filter(Counters.name == 'api_healthmonitor_get').first() counter.value += 1 session.commit() return monitor_data
def read_std_arguments(self, context): funcdef = context.funcdef notation = funcdef.extra_options.get('extdirect_params_notation', self.default_params_notation) args = context.params if notation == 'positional': kw = dict((argdef.name, fromjson(argdef.datatype, arg)) for argdef, arg in zip(funcdef.arguments, args)) elif notation == 'named': if len(args) == 0: args = [{}] elif len(args) > 1: raise ClientSideError( "Named arguments: takes a single object argument") args = args[0] kw = dict( (argdef.name, fromjson(argdef.datatype, args[argdef.name])) for argdef in funcdef.arguments if argdef.name in args) else: raise ValueError("Invalid notation: %s" % notation) return kw