def init(api, cors, impl): """Configures REST handlers for app_group resource.""" namespace = webutils.namespace(api, __name__, 'AppGroup REST operations') app_group_model = { '_id': fields.String(description='Name'), 'cells': fields.List(fields.String(description='Cells')), 'group-type': fields.String(description='Group Type'), 'pattern': fields.String(description='Pattern'), 'data': fields.String(description='Data'), } request_model = api.model('ReqAppGroup', app_group_model) response_model = api.model('RespAppGroup', app_group_model) @namespace.route( '/', ) class _AppGroupList(restplus.Resource): """Treadmill App resource""" @webutils.get_api(api, cors, marshal=api.marshal_list_with, resp_model=response_model) def get(self): """Returns list of configured applications.""" return impl.list() @namespace.route('/<app_group>') @api.doc(params={'app_group': 'App Group ID/name'}) class _AppGroupResource(restplus.Resource): """Treadmill AppGroup resource.""" @webutils.get_api(api, cors, marshal=api.marshal_with, resp_model=response_model) def get(self, app_group): """Return Treadmill app-group configuration.""" return impl.get(app_group) @webutils.post_api(api, cors, req_model=request_model, resp_model=response_model) def post(self, app_group): """Creates Treadmill app-group.""" return impl.create(app_group, flask.request.json) @webutils.put_api(api, cors, req_model=request_model, resp_model=response_model) def put(self, app_group): """Updates Treadmill app-group configuration.""" return impl.update(app_group, flask.request.json) @webutils.delete_api(api, cors) def delete(self, app_group): """Deletes Treadmill app-group.""" return impl.delete(app_group)
def init(api, cors, impl): """Configures REST handlers for app-dns resource.""" namespace = webutils.namespace(api, __name__, 'App DNS REST operations') model = { '_id': fields.String(description='Name'), 'cells': fields.List(fields.String(description='Cells')), 'pattern': fields.String(description='App pattern'), 'endpoints': fields.List(fields.String(description='Endpoints')), 'alias': fields.String(description='Alias'), 'scope': fields.String(description='Scope', required=True), } app_dns_model = api.model('AppDNS', model) @namespace.route( '/', ) class _AppDNSList(restplus.Resource): """Treadmill app-dns resource""" @webutils.get_api(api, cors, marshal=api.marshal_list_with, resp_model=app_dns_model) def get(self): """Returns list of configured app-dns.""" return impl.list() @namespace.route('/<app_dns>') @api.doc(params={'app_dns': 'Application DNS ID/name'}) class _AppDNSResource(restplus.Resource): """Treadmill App DNS resource.""" @webutils.get_api(api, cors, marshal=api.marshal_with, resp_model=app_dns_model) def get(self, app_dns): """Return Treadmill app-dns configuration.""" return impl.get(app_dns) @webutils.post_api(api, cors, req_model=app_dns_model, resp_model=app_dns_model) def post(self, app_dns): """Creates Treadmill app-dns.""" return impl.create(app_dns, flask.request.json) @webutils.put_api(api, cors, req_model=app_dns_model, resp_model=app_dns_model) def put(self, app_dns): """Updates Treadmill app-dns configuration.""" return impl.update(app_dns, flask.request.json) @webutils.delete_api(api, cors) def delete(self, app_dns): """Deletes Treadmill app-dns.""" return impl.delete(app_dns)
def init(api, cors, impl): """Configures REST handlers for cell resource.""" namespace = webutils.namespace(api, __name__, 'Cell REST operations') @namespace.route('/') class _CellList(restplus.Resource): """Treadmill Cell resource""" @webutils.get_api(api, cors) def get(self): """Returns list of configured cells.""" return impl.list() @namespace.route('/<cell_id>') class _CellResource(restplus.Resource): """Treadmill Cell resource.""" @webutils.get_api(api, cors) def get(self, cell_id): """Return Treadmill cell configuration.""" return impl.get(cell_id) @webutils.delete_api(api, cors) def delete(self, cell_id): """Deletes Treadmill cell.""" return impl.delete(cell_id) @webutils.put_api(api, cors) def put(self, cell_id): """Updates Treadmill cell configuration.""" return impl.update(cell_id, flask.request.json) @webutils.post_api(api, cors) def post(self, cell_id): """Creates Treadmill cell.""" return impl.create(cell_id, flask.request.json)
def init(api, cors, impl): """Configures REST handlers for state resource.""" # Disable too many branches warning. # # pylint: disable=R0912 namespace = webutils.namespace(api, __name__, 'Trace REST operations') model = { 'name': fields.String(description='Application name'), 'instances': fields.List(fields.String(description='Instance IDs')), } trace_model = api.model('Trace', model) @namespace.route('/<app_name>') @api.doc(params={'app_name': 'Application name'}) class _TraceAppResource(restplus.Resource): """Treadmill application trace information resource. """ @webutils.get_api(api, cors, marshal=api.marshal_with, resp_model=trace_model) def get(self, app_name): """Return trace information of a Treadmill application. """ trace_info = impl.get(app_name) if trace_info is None: api.abort(http.client.NOT_FOUND, 'No trace information available for %s' % app_name) return trace_info
def init(api, cors, impl): """Configures REST handlers for state resource.""" # Disable too many branches warning. # # pylint: disable=R0912 namespace = webutils.namespace(api, __name__, 'State REST operations') @namespace.route( '/', ) class _StateList(restplus.Resource): """Treadmill State resource""" @webutils.get_api(api, cors) def get(self): """Return all state.""" return impl.list(flask.request.args.get('match')) @webutils.put_api(api, cors) def post(self): """Returns state of the instance list.""" instances = flask.request.json.get('instances') states = [impl.get(instance_id) for instance_id in instances] return [state for state in states if state is not None] @namespace.route('/<instance_id>') class _StateResource(restplus.Resource): """Treadmill State resource.""" @webutils.get_api(api, cors) def get(self, instance_id): """Return Treadmill instance state.""" state = impl.get(instance_id) if state is None: api.abort(httplib.NOT_FOUND, 'Instance does not exist: %s' % instance_id) return state
def init(api, cors, impl): """Configures REST handlers for state resource.""" namespace = webutils.namespace(api, __name__, 'Trace REST operations') model = { 'name': fields.String(description='Application name'), 'instances': fields.List(fields.String(description='Instance IDs')), } trace_model = api.model('Trace', model) @namespace.route('/<app_name>') @api.doc(params={'app_name': 'Application name'}) class _TraceAppResource(restplus.Resource): """Treadmill application trace information resource. """ @webutils.get_api(api, cors, marshal=api.marshal_with, resp_model=trace_model) def get(self, app_name): """Return trace information of a Treadmill application. """ trace_info = impl.get(app_name) if trace_info is None: raise exc.NotFoundError( 'No trace information available for {}'.format(app_name)) return trace_info
def test_namespace(self): """Tests namespace().""" m_api = mock.Mock() # W0613: Unused argument 'kwargs' # pylint: disable=W0613 def noop(*args, **kwargs): """Simply return the positional arguments""" return args m_api.namespace = noop (ns, ) = webutils.namespace(m_api, 'treadmill.rest.api.state', 'foo') self.assertEqual(ns, 'state') (ns, ) = webutils.namespace(m_api, 'treadmill_foo.rest.api.allocation_group', 'foo') self.assertEqual(ns, 'allocation-group')
def register_authz_resource(resource, api, description): """Register a resource for authz namespace. :param resource: sub-class inherited from AuthzAPIBase. :param api: reserved parameter for `restplus.Resource`. :param description: reserved parameter for `restplus.Resource`. """ namespace = webutils.namespace(api, '', description) namespace.add_resource(resource, _ROUTE)
def init(api, cors, impl): """Configures REST handlers for endpoint resource.""" # Disable too many branches warning. # # pylint: disable=R0912 namespace = webutils.namespace( api, __name__, 'Endpoint state REST operations' ) endpoint_model = { 'endpoint': fields.String(description='Endpoint name'), 'name': fields.String(description='Application name'), 'port': fields.Integer(description='Endpoint port'), 'proto': fields.String(description='Application endpoint protocol'), 'host': fields.String(description='Endpoint host'), } response_model = api.model( 'Endpoint', endpoint_model ) @namespace.route( '/<pattern>', ) @api.doc(params={'pattern': 'Application pattern'}) class _EndpointList(restplus.Resource): """Treadmill Endpoint resource""" @webutils.get_api(api, cors, marshal=api.marshal_list_with, resp_model=response_model) def get(self, pattern): """Return all endpoints""" ret = impl.list(pattern, None, None) print ret return ret @namespace.route('/<pattern>/<proto>/<endpoint>') @api.doc(params={ 'pattern': 'Application pattern', 'proto': 'Application endpoint protocol', 'endpoint': 'Application endpoint name', }) class _EndpointResource(restplus.Resource): """Treadmill Endpoint resource""" @webutils.get_api(api, cors, marshal=api.marshal_list_with, resp_model=response_model) def get(self, pattern, proto, endpoint): """Return Treadmill app endpoint state""" ret = impl.list(pattern, proto, endpoint) print ret return ret
def init(api, _cors, impl): """Configures REST handlers for keytab resource.""" namespace = webutils.namespace(api, __name__, 'Keytab Locker REST operations') @namespace.route('/') class _KeytabList(restplus.Resource): """Treadmill Keytab list resource""" def get(self): """Returns list of available keytabs.""" return impl.list()
def init(api, cors, impl): """Configures REST handlers for DNS resource.""" namespace = webutils.namespace( api, __name__, 'DNS REST operations' ) server_model = fields.String(description='Server') model = { '_id': fields.String( description='Name', max_length=32), 'location': fields.String(description='Location'), 'nameservers': fields.List(server_model), 'rest-server': fields.List(server_model), 'zkurl': fields.String(description='Zookeeper URL'), 'fqdn': fields.String(description='FQDN'), 'ttl': fields.String(description='Time To Live'), } dns_model = api.model( 'DNS', model ) @namespace.route('/') class _DNSList(restplus.Resource): """Treadmill DNS resource""" @webutils.get_api(api, cors, marshal=api.marshal_list_with, resp_model=dns_model) def get(self): """Returns list of configured DNS servers.""" return impl.list() @namespace.route('/<dns>') @api.doc(params={'dns': 'DNS ID/name or FQDN'}) class _DNSResource(restplus.Resource): """Treadmill DNS resource.""" @webutils.get_api(api, cors, marshal=api.marshal_with, resp_model=dns_model) def get(self, dns): """Return Treadmill cell configuration.""" return impl.get(dns)
def init(api, cors, impl): """Configures REST handlers for server resource.""" namespace = webutils.namespace(api, __name__, 'Server REST operations') req_parser = api.parser() req_parser.add_argument('cell', help='Cell', location='args', required=False) req_parser.add_argument('partition', help='Partition', location='args', required=False) @namespace.route( '/', ) class _ServerList(restplus.Resource): """Treadmill Server resource""" @webutils.get_api(api, cors, parser=req_parser) def get(self): """Returns list of configured servers.""" args = req_parser.parse_args() return impl.list(args.get('cell'), args.get('partition')) @namespace.route('/<server_id>') class _ServerResource(restplus.Resource): """Treadmill Server resource.""" @webutils.get_api(api, cors) def get(self, server_id): """Return Treadmill server configuration.""" return impl.get(server_id) @webutils.delete_api(api, cors) def delete(self, server_id): """Deletes Treadmill server.""" return impl.delete(server_id) @webutils.put_api(api, cors) def put(self, server_id): """Updates Treadmill server configuration.""" return impl.update(server_id, flask.request.json) @webutils.post_api(api, cors) def post(self, server_id): """Creates Treadmill server.""" return impl.create(server_id, flask.request.json)
def init(api, cors, impl): """Configures REST handlers for cell resource.""" namespace = webutils.namespace( api, __name__, 'Ticket Locker REST operations' ) model = { 'expires_at': fields.Integer(description='Ticket expiration time.'), } resp_model = api.model( 'Ticket', model ) @namespace.route('/') class _TicketsList(restplus.Resource): """Treadmill Ticket list resource""" def get(self): """Returns list of available tickets.""" return impl.list() @namespace.route('/@') class _TickeUserResource(restplus.Resource): """Treadmill Ticket resource.""" @webutils.get_api(api, cors, marshal=api.marshal_with, resp_model=resp_model) def get(self): """Return Treadmill Ticket details for the authenticated user.""" return impl.get(flask.g.get('user')) @namespace.route('/<principal>') @api.doc(params={'principal': 'Principal name'}) class _TicketResource(restplus.Resource): """Treadmill Ticket resource.""" @webutils.get_api(api, cors, marshal=api.marshal_with, resp_model=resp_model) def get(self, principal): """Return Treadmill Ticket details.""" return impl.get(principal)
def init(api, _cors, impl): """Configures REST handlers for allocation resource.""" namespace = webutils.namespace(api, __name__, 'Local nodeinfo redirect API.') @namespace.route('/<hostname>/<path:path>') class _NodeRedirect(restplus.Resource): """Redirects to local nodeinfo endpoint.""" def get(self, hostname, path): """Returns list of local instances.""" hostport = impl.get(hostname) if not hostport: return 'Host not found.', http_client.NOT_FOUND url = utils.encode_uri_parts(path) return flask.redirect('http://%s/%s' % (hostport, url), code=http_client.FOUND)
def init(api, cors, impl): """Configures REST handlers for cron resource.""" del cors namespace = webutils.namespace(api, '', 'Group based authorizer') @namespace.route('/<user>/<action>/<resource>') class _AuthZ(restplus.Resource): """Treadmill Group authorizer.""" def post(self, user, action, resource): """Authorize user access to resource based on group membership.""" payload = flask.request.get_json(force=True) _LOGGER.info( 'authorize user: %s, action: %s, resource, %s, payload: %r', user, action, resource, payload) status = http.client.OK resource_id = payload.get('pk') try: authorized, why = impl.authorize( user=user, action=action, resource=resource, resource_id=resource_id, payload=payload.get('payload')) except Exception as err: # pylint: disable=broad-except _LOGGER.exception('Unhandled exception') authorized, why = False, [str(err)] status = http.client.INTERNAL_SERVER_ERROR _LOGGER.info('Authorize %s %s %s %s: %s', user, action, resource, resource_id, authorized) # TODO: API returns 200 always, for authorization it will be more # intuitive to return FORBIDDEN return flask.Response(json.dumps({ 'auth': authorized, 'annotations': why }), status=status, mimetype='application/json')
def init(api, cors, impl): """Configures REST handlers for app monitor resource.""" namespace = webutils.namespace( api, __name__, 'Identity Group REST operations' ) @namespace.route( '/', ) class _IdentityGroupList(restplus.Resource): """Treadmill identity group resource""" @webutils.get_api(api, cors) def get(self): """Returns list of configured identity groups.""" return impl.list() @namespace.route('/<app_id>') class _IdentityGroupResource(restplus.Resource): """Treadmill identity group resource.""" @webutils.get_api(api, cors) def get(self, app_id): """Return identity group configuration.""" return impl.get(app_id) @webutils.delete_api(api, cors) def delete(self, app_id): """Deletes identity group.""" return impl.delete(app_id) @webutils.put_api(api, cors) def put(self, app_id): """Updates identity group configuration.""" return impl.update(app_id, flask.request.json) @webutils.post_api(api, cors) def post(self, app_id): """Creates identity group.""" return impl.create(app_id, flask.request.json)
def init(api, cors, impl): """Configures REST handlers for cloud host resource.""" namespace = webutils.namespace( api, __name__, 'Cloud Host REST operations' ) @namespace.route('/<hostname>') @api.doc(params={'hostname': 'hostname'}) class _CloudHostResource(restplus.Resource): """Treadmill Cloud Host resource""" @webutils.post_api(api, cors, marshal=api.marshal_list_with) def post(self, hostname): """Adds host to IPA.""" return impl.create(hostname) @webutils.delete_api(api, cors, marshal=api.marshal_list_with) def delete(self, hostname): """Deletes host from IPA.""" return impl.delete(hostname)
def init(api, cors, impl): """Configures REST handlers for endpoint resource.""" # Disable too many branches warning. # # pylint: disable=R0912 namespace = webutils.namespace(api, __name__, 'State REST operations') @namespace.route( '/<pattern>', ) class _EndpointList(restplus.Resource): """Treadmill State resource""" @webutils.get_api(api, cors) def get(self, pattern): """Return all state.""" return impl.list(pattern, None) @namespace.route('/<pattern>/<endpoint>') class _EndpointResource(restplus.Resource): """Treadmill State resource.""" @webutils.get_api(api, cors) def get(self, pattern, endpoint): """Return Treadmill instance state.""" return impl.list(pattern, endpoint)
def init(api, cors, impl): """Configures REST handlers for server resource.""" namespace = webutils.namespace(api, __name__, 'Server REST operations') @namespace.route( '/', ) class _ServerList(restplus.Resource): """Treadmill Server resource""" @webutils.get_api(api, cors) def get(self): """Returns list of configured servers.""" return impl.list(flask.request.args.get('cell'), flask.request.args.getlist('features')) @namespace.route('/<server_id>') class _ServerResource(restplus.Resource): """Treadmill Server resource.""" @webutils.get_api(api, cors) def get(self, server_id): """Return Treadmill server configuration.""" return impl.get(server_id) @webutils.delete_api(api, cors) def delete(self, server_id): """Deletes Treadmill server.""" return impl.delete(server_id) @webutils.put_api(api, cors) def put(self, server_id): """Updates Treadmill server configuration.""" return impl.update(server_id, flask.request.json) @webutils.post_api(api, cors) def post(self, server_id): """Creates Treadmill server.""" return impl.create(server_id, flask.request.json)
def init(api, cors, impl): """Configures REST handlers for app monitor resource.""" namespace = webutils.namespace(api, __name__, 'Application monitor REST operations') @namespace.route( '/', ) class _AppMonitorList(restplus.Resource): """Treadmill App monitor resource""" @webutils.get_api(api, cors) def get(self): """Returns list of configured app monitors.""" return impl.list() @namespace.route('/<app_id>') class _AppMonitorResource(restplus.Resource): """Treadmill App monitor resource.""" @webutils.get_api(api, cors) def get(self, app_id): """Return Treadmill application monitor configuration.""" return impl.get(app_id) @webutils.delete_api(api, cors) def delete(self, app_id): """Deletes Treadmill application monitor.""" return impl.delete(app_id) @webutils.put_api(api, cors) def put(self, app_id): """Updates Treadmill application configuration.""" return impl.update(app_id, flask.request.json) @webutils.post_api(api, cors) def post(self, app_id): """Creates Treadmill application.""" return impl.create(app_id, flask.request.json)
def init(api, cors, impl): """Configures REST handlers for tenant resource.""" namespace = webutils.namespace(api, __name__, 'Tenant REST operations') @namespace.route( '/', ) class _TenantList(restplus.Resource): """Treadmill Tenant resource""" @webutils.get_api(api, cors) def get(self): """Returns list of configured tenants.""" return impl.list() @namespace.route('/<tenant_id>') class _TenantResource(restplus.Resource): """Treadmill Tenant resource.""" @webutils.get_api(api, cors) def get(self, tenant_id): """Return Treadmill tenant configuration.""" return impl.get(tenant_id) @webutils.delete_api(api, cors) def delete(self, tenant_id): """Deletes Treadmill tenant.""" return impl.delete(tenant_id) @webutils.put_api(api, cors) def put(self, tenant_id): """Updates Treadmill tenant configuration.""" return impl.update(tenant_id, flask.request.json) @webutils.post_api(api, cors) def post(self, tenant_id): """Creates Treadmill tenant.""" return impl.create(tenant_id, flask.request.json)
def init(api, cors, impl): """Configures REST handlers for cell resource.""" namespace = webutils.namespace(api, __name__, 'Cell REST operations') master = api.model( 'Master', { 'hostname': fields.String(description='Hostname'), 'idx': fields.Integer(description='Index of master'), 'zk-followers-port': fields.Integer(description='ZK follower port'), 'zk-election-port': fields.Integer(description='ZK election port'), 'zk-jmx-port': fields.Integer(description='ZK JMX port'), 'zk-client-port': fields.Integer(description='ZK client port'), }) model = { '_id': fields.String(description='Name'), 'username': fields.String(description='Treadmill User ID'), 'root': fields.String(description='Treadmill Root'), 'archive-server': fields.String(description='Archive Server'), 'archive-username': fields.String(description='Archive Username'), 'ssq-namespace': fields.String(description='SSQ Namespace'), 'location': fields.String(description='Location'), 'version': fields.String(description='Version'), 'masters': fields.List(fields.Nested(master)), } cell_model = api.model('Cell', model) @namespace.route('/') class _CellList(restplus.Resource): """Treadmill Cell resource""" @webutils.get_api(api, cors, marshal=api.marshal_list_with, resp_model=cell_model) def get(self): """Returns list of configured cells.""" return impl.list() @namespace.route('/<cell>') @api.doc(params={'cell': 'Cell ID/name'}) class _CellResource(restplus.Resource): """Treadmill Cell resource.""" @webutils.get_api(api, cors, marshal=api.marshal_with, resp_model=cell_model) def get(self, cell): """Return Treadmill cell configuration.""" return impl.get(cell) @webutils.post_api(api, cors, req_model=cell_model, resp_model=cell_model) def post(self, cell): """Creates Treadmill cell.""" return impl.create(cell, flask.request.json) @webutils.put_api(api, cors, req_model=cell_model, resp_model=cell_model) def put(self, cell): """Updates Treadmill cell configuration.""" return impl.update(cell, flask.request.json) @webutils.delete_api(api, cors) def delete(self, cell): """Deletes Treadmill cell.""" return impl.delete(cell)
def init(api, cors, impl): """Configures REST handlers for app monitor resource.""" namespace = webutils.namespace(api, __name__, 'Identity Group REST operations') model = { '_id': fields.String(description='Name'), 'count': fields.Integer(description='Identiy Group Count', required=True), } identity_group_model = api.model('IdentityGroup', model) match_parser = api.parser() match_parser.add_argument( 'match', help='A glob match on an app monitor', location='args', required=False, ) @namespace.route( '/', ) class _IdentityGroupList(restplus.Resource): """Treadmill identity group resource""" @webutils.get_api(api, cors, marshal=api.marshal_list_with, resp_model=identity_group_model, parser=match_parser) def get(self): """Returns list of configured identity groups.""" args = match_parser.parse_args() return impl.list(args.get('match')) @namespace.route('/<app_id>') @api.doc(params={'app_ip': 'App ID/name'}) class _IdentityGroupResource(restplus.Resource): """Treadmill identity group resource.""" @webutils.get_api(api, cors, marshal=api.marshal_with, resp_model=identity_group_model) def get(self, app_id): """Return identity group configuration.""" return impl.get(app_id) @webutils.post_api(api, cors, req_model=identity_group_model, resp_model=identity_group_model) def post(self, app_id): """Creates identity group.""" return impl.create(app_id, flask.request.json) @webutils.put_api(api, cors, req_model=identity_group_model, resp_model=identity_group_model) def put(self, app_id): """Updates identity group configuration.""" return impl.update(app_id, flask.request.json) @webutils.delete_api(api, cors) def delete(self, app_id): """Deletes identity group.""" return impl.delete(app_id)
def init(api, cors, impl): """Configures REST handlers for app monitor resource.""" namespace = webutils.namespace( api, __name__, 'Identity Group REST operations' ) identity_group_model = { '_id': fields.String(description='Name'), 'count': fields.Integer( description='Identiy Group Count', required=True), } request_model = api.model( 'ReqIdentityGroup', identity_group_model ) response_model = api.model( 'RespIdentityGroup', identity_group_model ) @namespace.route( '/', ) class _IdentityGroupList(restplus.Resource): """Treadmill identity group resource""" @webutils.get_api(api, cors, marshal=api.marshal_list_with, resp_model=response_model) def get(self): """Returns list of configured identity groups.""" return impl.list() @namespace.route('/<app_id>') @api.doc(params={'app_ip': 'App ID/name'}) class _IdentityGroupResource(restplus.Resource): """Treadmill identity group resource.""" @webutils.get_api(api, cors, marshal=api.marshal_with, resp_model=response_model) def get(self, app_id): """Return identity group configuration.""" return impl.get(app_id) @webutils.post_api(api, cors, req_model=request_model, resp_model=response_model) def post(self, app_id): """Creates identity group.""" return impl.create(app_id, flask.request.json) @webutils.put_api(api, cors, req_model=request_model, resp_model=response_model) def put(self, app_id): """Updates identity group configuration.""" return impl.update(app_id, flask.request.json) @webutils.delete_api(api, cors) def delete(self, app_id): """Deletes identity group.""" return impl.delete(app_id)
def init(api, cors, impl): """Configures REST handlers for cell resource.""" namespace = webutils.namespace( api, __name__, 'Cell REST operations' ) master = api.model('Master', { 'hostname': fields.String(description='Hostname'), 'idx': fields.Integer(description='Index of master'), 'zk-followers-port': fields.Integer(description='ZK follower port'), 'zk-election-port': fields.Integer(description='ZK election port'), 'zk-jmx-port': fields.Integer(description='ZK JMX port'), 'zk-client-port': fields.Integer(description='ZK client port'), }) partition = api.model('Partition', { 'partition': fields.String(description='Name'), 'cpu': fields.String(description='Total cpu capacity'), 'disk': fields.String(description='Total disk capacity'), 'memory': fields.String(description='Total memory capacity'), 'systems': fields.List(fields.Integer(description='System')), 'down-threshold': fields.String(description='Server down threshold'), 'reboot-schedule': fields.String(description='Reboot schedule'), }) model = { '_id': fields.String(description='Name'), 'username': fields.String(description='Treadmill User ID'), 'zk-auth-scheme': fields.String(description='Zookeeper auth scheme'), 'root': fields.String(description='Treadmill Root'), 'location': fields.String(description='Location'), 'version': fields.String(description='Version'), 'status': fields.String(description='Status'), 'masters': fields.List(fields.Nested(master)), 'partitions': fields.List(fields.Nested(partition)), 'traits': fields.List(fields.String(description='Traits')), 'data': fields.Raw(), } cell_model = api.model( 'Cell', model ) @namespace.route('/') class _CellList(restplus.Resource): """Treadmill Cell resource""" @webutils.get_api(api, cors, marshal=api.marshal_list_with, resp_model=cell_model) def get(self): """Returns list of configured cells.""" return impl.list() @namespace.route('/<cell>') @api.doc(params={'cell': 'Cell ID/name'}) class _CellResource(restplus.Resource): """Treadmill Cell resource.""" @webutils.get_api(api, cors, marshal=api.marshal_with, resp_model=cell_model) def get(self, cell): """Return Treadmill cell configuration.""" return impl.get(cell) @webutils.post_api(api, cors, req_model=cell_model, resp_model=cell_model) def post(self, cell): """Creates Treadmill cell.""" return impl.create(cell, flask.request.json) @webutils.put_api(api, cors, req_model=cell_model, resp_model=cell_model) def put(self, cell): """Updates Treadmill cell configuration.""" return impl.update(cell, flask.request.json) @webutils.delete_api(api, cors) def delete(self, cell): """Deletes Treadmill cell.""" return impl.delete(cell)
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.""" # 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 cron resource.""" namespace = webutils.namespace(api, __name__, 'Cron REST operations') cron_model = { '_id': fields.String(description='Name'), 'event': fields.String(description='Event type', enum=['app:start', 'app:stop', 'monitor:set_count']), 'resource': fields.String(description='Resource'), 'expression': fields.String(description='Cron Expression'), 'count': fields.Integer(description='Resource count', required=False), } req_model = api.model( 'Cron', cron_model, ) cron_resp_model = cron_model cron_resp_model.update( action=fields.String(description='Action'), next_run_time=fields.DateTime(description='Next run time'), timezone=fields.String(description='Timezone'), event=fields.String(description='Event type', enum=['app', 'monitor']), ) resp_model = api.model( 'CronResponse', cron_resp_model, ) match_resource_parser = api.parser() match_resource_parser.add_argument('match', help='A glob match on a job ID', location='args', required=False, default=None) match_resource_parser.add_argument( 'resource', help='A glob match on a cron resource name', location='args', required=False, default=None) resume_pause_parser = api.parser() resume_pause_parser.add_argument( 'resume', help='Resume a job ID', location='args', required=False, type=bool, default=False, ) resume_pause_parser.add_argument( 'pause', help='Pause a job ID', location='args', required=False, type=bool, default=False, ) @namespace.route( '/', ) class _CronList(restplus.Resource): """Treadmill Cron resource""" @webutils.get_api(api, cors, marshal=api.marshal_list_with, resp_model=resp_model, parser=match_resource_parser) def get(self): """Returns list of configured cron.""" args = match_resource_parser.parse_args() return impl.list(**args) @namespace.route('/<job_id>') @api.doc(params={'job_id': 'Cron ID/Name'}) class _CronResource(restplus.Resource): """Treadmill Cron resource.""" @webutils.get_api(api, cors, marshal=api.marshal_with, resp_model=resp_model) def get(self, job_id): """Return Treadmill cron configuration.""" job = impl.get(job_id) if not job: raise exc.NotFoundError( 'job does not exist: {}'.format(job_id)) return job @webutils.post_api(api, cors, req_model=req_model, resp_model=resp_model) def post(self, job_id): """Creates Treadmill cron.""" return impl.create(job_id, flask.request.json) @webutils.put_api(api, cors, req_model=req_model, resp_model=resp_model, parser=resume_pause_parser) def put(self, job_id): """Updates Treadmill cron configuration.""" args = resume_pause_parser.parse_args() return impl.update(job_id, flask.request.json, **args) @webutils.delete_api(api, cors) def delete(self, job_id): """Deletes Treadmill cron.""" return impl.delete(job_id)
def init(api, cors, impl): """Configures REST handlers for AWS image resource.""" namespace = webutils.namespace(api, __name__, 'AWS Image REST operations') # TODO: will it make sense to maintain models in separate module? model = { 'ImageId': fields.String(description='Image id.'), 'Name': fields.String(description='Image name.'), 'OwnerId': fields.String(description='Image account.'), 'CreationDate': fields.String(description='Date created.'), 'State': fields.String(description='State.'), } aws_image_model = api.model('AWSImage', model) resource_fields = { 'tags': fields.Raw(description='Tags k/v dictionary'), 'name': fields.String(description='Resource name'), 'ids': fields.List(fields.String, description='List of resource ids') } aws_image_req_model = api.model( 'AWSImageRequest', { 'base_image': fields.Nested(resource_fields, description='Base image'), 'base_image_account': fields.String(description='Base image account.'), 'userdata': fields.List(fields.String, description='User data.'), 'profile': fields.String(description='Instance profile.'), 'secgroup': fields.Nested(resource_fields, description='AWS secgroup'), 'subnet': fields.Nested(resource_fields, description='AWS subnet'), 'key': fields.String(description='Instance ssh key.'), }) match_parser = api.parser() match_parser.add_argument( 'account', help='Image account', location='args', required=False, ) @namespace.route( '/', ) class _ImageResourceList(restplus.Resource): """Treadmill App monitor resource""" @webutils.get_api(api, cors, marshal=api.marshal_list_with, resp_model=aws_image_model, parser=match_parser) def get(self): """Returns list of configured app monitors.""" return impl.list() @namespace.route('/<image>') @api.doc(params={'image': 'Image name'}) class _ImageResource(restplus.Resource): """Treadmill AWS Image resource.""" @webutils.get_api(api, cors, marshal=api.marshal_with, resp_model=aws_image_model) def get(self, image): """Return Treadmill application monitor configuration.""" return impl.get(image) @webutils.post_api(api, cors, req_model=aws_image_req_model, resp_model=aws_image_model) def post(self, image): """Creates AWS image.""" return impl.create(image, flask.request.json) @webutils.delete_api(api, cors) def delete(self, image): """Deletes AWS image.""" return impl.delete(image)
def init(api, cors, impl): """Configures REST handlers for state resource.""" # Disable too many branches warning. # # pylint: disable=R0912 namespace = webutils.namespace( api, __name__, 'State REST operations' ) model = { 'name': fields.String(description='Application name'), 'host': fields.String(description='Application host'), 'state': fields.String(description='Application state'), 'expires': fields.Float(description='Host expiration'), 'when': fields.Float(description='Timestamp of event'), 'signal': fields.Integer(description='Kill signal'), 'exitcode': fields.Integer(description='Service exitcode'), 'oom': fields.Boolean(description='Out of memory'), } state_model = api.model( 'State', model ) match_parser = api.parser() match_parser.add_argument('match', help='A glob match on an app name', location='args', required=False,) match_parser.add_argument('finished', help='Flag to include finished apps', location='args', required=False, type=inputs.boolean, default=False) inst_parser = api.parser() inst_parser.add_argument('instances', type=list, location='json', required=True, help='List of instances, e.g.: ' '{ "instances": ["proid.app#0000000000"]}') @namespace.route( '/', ) class _StateList(restplus.Resource): """Treadmill State resource""" @webutils.get_api(api, cors, marshal=api.marshal_list_with, resp_model=state_model, parser=match_parser) def get(self): """Return all state.""" args = match_parser.parse_args() return impl.list(args.get('match'), args.get('finished')) @webutils.post_api(api, cors, marshal=api.marshal_list_with, resp_model=state_model, parser=inst_parser) def post(self): """Returns state of the instance list.""" args = inst_parser.parse_args() instances = args.get('instances') states = [impl.get(instance_id) for instance_id in instances] return [state for state in states if state is not None] @namespace.route('/<instance_id>') @api.doc(params={'instance_id': 'Application instance ID'}) class _StateResource(restplus.Resource): """Treadmill State resource.""" @webutils.get_api(api, cors, marshal=api.marshal_with, resp_model=state_model) def get(self, instance_id): """Return Treadmill instance state.""" state = impl.get(instance_id) if state is None: raise exc.NotFoundError( 'Instance does not exist: {}'.format(instance_id) ) return state