def init(api, cors, impl): """Configures REST handlers for instance resource.""" # Disable too many branches warning. # # pylint: disable=R0912 namespace = webutils.namespace(api, __name__, 'Instance REST operations') count_parser = api.parser() count_parser.add_argument('count', type=int, default=1, location='args') instances_resp_model = api.model( 'Instances', { 'instances': fields.List(fields.String(description='Instances')), }) inst_prio = api.model( 'InstancePriority', { '_id': fields.String(description='Application ID'), 'priority': fields.Integer(description='Priority'), }) bulk_update_inst_req = api.model( 'ReqBulkUpdateInstance', { 'instances': fields.List(fields.Nested(inst_prio)), }) bulk_del_inst_req = api.model('ReqBulkDeleteInstance', { 'instances': fields.List(fields.String(description='Application ID')), }) # Responses app_request_model, app_response_model = app_model.models(api) _erorr_id_why, error_model_resp = error_model.models(api) bulk_update_resp = api.clone('ApplicationWithError', app_response_model, error_model_resp) app_prio = api.clone('AppInstance', app_response_model, { 'priority': fields.Integer(description='Priority'), }) update_resp = api.model( 'UpdateInstance', { 'instances': fields.List(fields.Nested(bulk_update_resp)), }) prio_request_model = api.model( 'ReqInstancePriority', { 'priority': fields.List(fields.Integer(description='Priority')), }) match_parser = api.parser() match_parser.add_argument( 'match', help='A glob match on an app name', location='args', required=False, ) @namespace.route( '/', ) class _InstanceList(restplus.Resource): """Treadmill Instance resource""" @webutils.get_api(api, cors, marshal=api.marshal_with, resp_model=instances_resp_model, parser=match_parser) def get(self): """Returns list of configured applications.""" args = match_parser.parse_args() return dict(instances=impl.list(args.get('match'))) @namespace.route( '/_bulk/delete', ) class _InstanceBulkDelete(restplus.Resource): """Treadmill Instance resource""" @webutils.post_api( api, cors, req_model=bulk_del_inst_req, ) def post(self): """Bulk deletes list of instances.""" instance_ids = flask.request.json['instances'] for instance_id in instance_ids: impl.delete(instance_id) @namespace.route( '/_bulk/update', ) class _InstanceBulkUpdate(restplus.Resource): """Treadmill Instance resource""" @webutils.post_api(api, cors, req_model=bulk_update_inst_req, resp_model=update_resp) def post(self): """Bulk updates list of instances.""" deltas = flask.request.json['instances'] if not isinstance(deltas, list): raise exc.InvalidInputError( __name__, 'deltas is not a list: {}'.format(deltas)) result = [] for delta in deltas: if not isinstance(delta, dict): raise exc.InvalidInputError( __name__, 'delta is not a dict: {}'.format(deltas)) if '_id' not in delta: raise exc.InvalidInputError( __name__, 'delta is missing _id attribute: {}'.format(deltas)) # rest of validation is done in API. rsrc_id = delta.get('_id') del delta['_id'] try: result.append(impl.update(rsrc_id, delta)) except Exception as err: # pylint: disable=W0703 result.append( {'_error': { '_id': rsrc_id, 'why': str(err) }}) return {'instances': result} @namespace.route('/<instance_id>') @api.doc(params={'instance_id': 'Instance ID/name'}) class _InstanceResource(restplus.Resource): """Treadmill Instance resource.""" @webutils.get_api(api, cors, marshal=api.marshal_with, resp_model=app_prio) def get(self, instance_id): """Return Treadmill instance configuration.""" instance = impl.get(instance_id) if not instance: raise exc.NotFoundError( 'Instance does not exist: {}'.format(instance_id)) return instance @webutils.post_api(api, cors, req_model=app_request_model, resp_model=instances_resp_model, parser=count_parser) def post(self, instance_id): """Creates Treadmill instance.""" args = count_parser.parse_args() count = args.get('count', 1) instances = impl.create(instance_id, flask.request.json, count) return {'instances': instances} @webutils.put_api( api, cors, req_model=prio_request_model, ) def put(self, instance_id): """Updates Treadmill instance configuration.""" return impl.update(instance_id, flask.request.json) @webutils.delete_api(api, cors) def delete(self, instance_id): """Deletes Treadmill application.""" return impl.delete(instance_id)
def init(api, cors, impl): """Configures REST handlers for app resource.""" namespace = webutils.namespace(api, __name__, 'Application REST operations') request_model, response_model = app_model.models(api) match_parser = api.parser() match_parser.add_argument( 'match', help='A glob match on an app name', location='args', required=False, ) @namespace.route( '/', ) class _AppList(restplus.Resource): """Treadmill App resource""" @webutils.get_api(api, cors, marshal=api.marshal_list_with, resp_model=response_model, parser=match_parser) def get(self): """Returns list of configured applications.""" args = match_parser.parse_args() return impl.list(args.get('match')) @namespace.route('/<app>') @api.doc(params={'app': 'Application ID/Name'}) class _AppResource(restplus.Resource): """Treadmill App resource.""" @webutils.get_api(api, cors, marshal=api.marshal_with, resp_model=response_model) def get(self, app): """Return Treadmill application configuration.""" return impl.get(app) @webutils.post_api(api, cors, req_model=request_model, resp_model=response_model) def post(self, app): """Creates Treadmill application.""" return impl.create(app, flask.request.json) @webutils.put_api(api, cors, req_model=request_model, resp_model=response_model) def put(self, app): """Updates Treadmill application configuration.""" return impl.update(app, flask.request.json) @webutils.delete_api(api, cors) def delete(self, app): """Deletes Treadmill application.""" return impl.delete(app)
def init(api, cors, impl): """Configures REST handlers for instance resource.""" namespace = webutils.namespace(api, __name__, 'Instance REST operations') create_args_parser = api.parser() create_args_parser.add_argument('count', type=int, default=1, location='args') create_args_parser.add_argument('debug', type=bool, default=False, location='args') create_args_parser.add_argument('debug_services', type=str, action='split', location='args') instances_resp_model = api.model( 'Instances', { 'instances': fields.List(fields.String(description='Instances')), }) inst_prio = api.model( 'InstancePriority', { '_id': fields.String(description='Application ID'), 'priority': fields.Integer(description='Priority'), }) bulk_update_inst_req = api.model( 'ReqBulkUpdateInstance', { 'instances': fields.List(fields.Nested(inst_prio)), }) bulk_del_inst_req = api.model('ReqBulkDeleteInstance', { 'instances': fields.List(fields.String(description='Application ID')), }) # Responses app_request_model, app_response_model = app_model.models(api) _erorr_id_why, error_model_resp = error_model.models(api) bulk_update_resp = api.clone('ApplicationWithError', app_response_model, error_model_resp) app_prio = api.clone('AppInstance', app_response_model, { 'priority': fields.Integer(description='Priority'), }) update_resp = api.model( 'UpdateInstance', { 'instances': fields.List(fields.Nested(bulk_update_resp)), }) prio_request_model = api.model( 'ReqInstancePriority', { 'priority': fields.List(fields.Integer(description='Priority')), }) match_parser = api.parser() match_parser.add_argument( 'match', help='A glob match on an app name', location='args', required=False, ) @namespace.route( '/', ) class _InstanceList(restplus.Resource): """Treadmill Instance resource""" @webutils.get_api(api, cors, marshal=api.marshal_with, resp_model=instances_resp_model, parser=match_parser) def get(self): """Returns list of configured applications.""" args = match_parser.parse_args() return dict(instances=impl.list(args.get('match'))) @namespace.route( '/_bulk/delete', ) class _InstanceBulkDelete(restplus.Resource): """Treadmill Instance resource""" @webutils.post_api( api, cors, req_model=bulk_del_inst_req, ) def post(self): """Bulk deletes list of instances.""" user = flask.g.get('user') instance_ids = flask.request.json['instances'] # Bulk operations are allowed on on same proid. proid = None for instance_id in instance_ids: if proid is None: proid = instance_id.partition('.')[0] else: if proid != instance_id.partition('.')[0]: raise exc.InvalidInputError( __name__, 'Mulitple proids in bulk delete request.') impl.bulk_delete(proid, instance_ids, user) @namespace.route( '/_bulk/update', ) class _InstanceBulkUpdate(restplus.Resource): """Treadmill Instance resource""" @webutils.post_api(api, cors, req_model=bulk_update_inst_req, resp_model=update_resp) def post(self): """Bulk updates list of instances.""" deltas = flask.request.json['instances'] proid = None def _proid(delta): """Return proid from delta resource id.""" return delta.get('_id', '').partition('.')[0] for delta in deltas: if proid is None: proid = _proid(delta) else: if proid != _proid(delta): raise exc.InvalidInputError( __name__, 'Mulitple proids in bulk update request.') result = impl.bulk_update(proid, deltas) return {'instances': result} @namespace.route('/<instance_id>') @api.doc(params={'instance_id': 'Instance ID/name'}) class _InstanceResource(restplus.Resource): """Treadmill Instance resource.""" @webutils.get_api(api, cors, marshal=api.marshal_with, resp_model=app_prio) def get(self, instance_id): """Return Treadmill instance configuration.""" instance = impl.get(instance_id) if not instance: raise exc.NotFoundError( 'Instance does not exist: {}'.format(instance_id)) return instance @webutils.post_api(api, cors, req_model=app_request_model, resp_model=instances_resp_model, parser=create_args_parser) def post(self, instance_id): """Creates Treadmill instance.""" args = create_args_parser.parse_args() count = args.get('count', 1) debug = args.get('debug', False) debug_services = args.get('debug_services') # FIXME: figure why action='split' doesn't split it. if debug_services: debug_services = debug_services.split(',') user = flask.g.get('user') instances = impl.create(instance_id, flask.request.json, count, user, debug, debug_services) return {'instances': instances} @webutils.put_api( api, cors, req_model=prio_request_model, ) def put(self, instance_id): """Updates Treadmill instance configuration.""" return impl.update(instance_id, flask.request.json) @webutils.delete_api(api, cors) def delete(self, instance_id): """Deletes Treadmill application.""" user = flask.g.get('user') return impl.delete(instance_id, user)