<reponame>gaocegege/treadmill
"""Local node REST api.
"""

import logging
import os

# pylint: disable=E0611,F0401
import flask
import flask_restplus as restplus

from treadmill import webutils

_LOGGER = logging.getLogger(__name__)


# pylint: disable=W0232,R0912
def init(api, cors, impl):
    """Configures REST handlers for allocation resource."""

    app_ns = api.namespace('app', description='Local app REST operations')

    req_parser = api.parser()
    req_parser.add_argument('start',
                            default=0, help='The index (inclusive) of'
                            ' the first line from the log file to return.'
                            ' Index is zero based.',
                            location='args', required=False, type=int)
    req_parser.add_argument('limit',
                            help='The number of lines to return. '
                            '-1 (the default) means no limit ie. return all'
                            ' the lines in the file from "start".',
                            location='args', required=False, type=int)
    req_parser.add_argument('order',
                            choices=('asc', 'desc'), default='asc',
                            help="The order of the log lines to return. 'asc':"
                            " chronological, 'desc': reverse chronological",
                            location='args', required=False, type=str)

    @app_ns.route('/',)
    class _AppList(restplus.Resource):
        """Local app list resource."""

        @webutils.get_api(api, cors)
        def get(self):
            """Returns list of local instances."""
            return impl.list(flask.request.args.get('state'))

    @app_ns.route('/<app>/<uniq>',)
    class _AppDetails(restplus.Resource):
        """Local app details resource."""

        @webutils.get_api(api, cors)
        def get(self, app, uniq):
            """Returns list of local instances."""
            return impl.get('/'.join([app, uniq]))

    @app_ns.route('/<app>/<uniq>/sys/<component>',)
    class _AppSystemLog(restplus.Resource):
        """Local app details resource."""

        @webutils.raw_get_api(api, cors, parser=req_parser)
        def get(self, app, uniq, component):
            """Return content of system component log.."""
            args = req_parser.parse_args()
            return flask.Response(
                impl.log.get('/'.join([app, uniq, 'sys', component]),
                             start=args.get('start'),
                             limit=args.get('limit'),
                             order=args.get('order')),
                mimetype='text/plain')

    @app_ns.route('/<app>/<uniq>/service/<service>',)
    class _AppServiceLog(restplus.Resource):
        """Local app details resource."""

        @webutils.raw_get_api(api, cors, parser=req_parser)
        def get(self, app, uniq, service):
            """Return content of system component log.."""
            args = req_parser.parse_args()
            return flask.Response(
                impl.log.get('/'.join([app, uniq, 'app', service]),
                             start=args.get('start'),
                             limit=args.get('limit'),
                             order=args.get('order')),
                mimetype='text/plain')

    archive_ns = api.namespace('archive',
                               description='Local archive REST operations')

    @archive_ns.route('/<app>/<uniq>/sys')
    class _SysArchiveAsAttachment(restplus.Resource):
        """Download sys archive as attachment."""

        @webutils.raw_get_api(api, cors)
        def get(self, app, uniq):
            """Return content of sys archived file.."""
            fname = impl.archive.get('/'.join([app, uniq, 'sys']))

            return flask.send_file(
                fname,
                as_attachment=True,
                attachment_filename=os.path.basename(fname)
            )

    @archive_ns.route('/<app>/<uniq>/app')
    class _AppArchiveAsAttachment(restplus.Resource):
        """Download app archive as attachment."""

        @webutils.raw_get_api(api, cors)
        def get(self, app, uniq):
            """Return content of app archived file.."""
            fname = impl.archive.get('/'.join([app, uniq, 'app']))

            return flask.send_file(
                fname,
                as_attachment=True,
                attachment_filename=os.path.basename(fname)
            )

    metrics_ns = api.namespace('metrics', description='Local metrics '
                               'REST operations')

    metrics_req_parser = api.parser()
    metrics_req_parser.add_argument(
        'timeframe',
        choices=('short', 'long'),
        default='short',
        help="Whether to query the metrics for shorter or longer timeframe.",
        location='args',
        required=False,
        type=str)

    @metrics_ns.route('/',)
    class _MetricsList(restplus.Resource):
        """Local metrics list resource."""

        @webutils.get_api(api, cors)
        def get(self):
            """Returns list of locally available metrics."""
            return impl.list(flask.request.args.get('state'), inc_svc=True)

    @metrics_ns.route('/<app>/<uniq>')
    @metrics_ns.route('/<service>')
    class _Metrics(restplus.Resource):
        """Download metrics."""

        @webutils.raw_get_api(api, cors, parser=metrics_req_parser)
        def get(self, **id_parts):
            """
            Return metrics either as an attachment or as json.
            """
            args = metrics_req_parser.parse_args()
            if webutils.wants_json_resp(flask.request):
                return self._get(self._to_rsrc_id(**id_parts),
                                 args.get('timeframe'))
            else:
                return self._get_as_attach(self._to_rsrc_id(**id_parts),
                                           args.get('timeframe'))

        def _to_rsrc_id(self, **id_parts):
            """
            Return the metrics resource id based on the keyword args.
            """
            try:
                rsrc_id = '/'.join([id_parts['app'], id_parts['uniq']])
            except KeyError:
                rsrc_id = id_parts['service']

            return rsrc_id

        def _get(self, rsrc_id, timeframe):
            """Return the metrics file as json."""
            return flask.Response(impl.metrics.get(rsrc_id, timeframe,
                                                   as_json=True),
                                  mimetype='application/json')

        def _get_as_attach(self, rsrc_id, timeframe):
            """Return the metrics file as attachment."""
            return flask.send_file(
                impl.metrics.get(rsrc_id, timeframe),
                as_attachment=True,
                mimetype='application/octet-stream',
                attachment_filename=os.path.basename(
                    impl.metrics.file_path(rsrc_id)
                )
            )

"""Local node REST api.
"""

import logging
import os

# pylint: disable=E0611,F0401
import flask
import flask_restplus as restplus

from treadmill import webutils

_LOGGER = logging.getLogger(__name__)


# pylint: disable=W0232,R0912
def init(api, cors, impl):
    """Configures REST handlers for allocation resource."""

    app_ns = api.namespace('app', description='Local app REST operations')

    req_parser = api.parser()
    req_parser.add_argument('start',
                            default=0, help='The index (inclusive) of'
                            ' the first line from the log file to return.'
                            ' Index is zero based.',
                            location='args', required=False, type=int)
    req_parser.add_argument('limit',
                            help='The number of lines to return. '
                            '-1 (the default) means no limit ie. return all'
                            ' the lines in the file from "start".',
                            location='args', required=False, type=int)
    req_parser.add_argument('order',
                            choices=('asc', 'desc'), default='asc',
                            help="The order of the log lines to return. 'asc':"
                            " chronological, 'desc': reverse chronological",
                            location='args', required=False, type=str)

    @app_ns.route('/',)
    class _AppList(restplus.Resource):
        """Local app list resource."""

        @webutils.get_api(api, cors)
        def get(self):
            """Returns list of local instances."""
            return impl.list(flask.request.args.get('state'))

    @app_ns.route('/<app>/<uniq>',)
    class _AppDetails(restplus.Resource):
        """Local app details resource."""

        @webutils.get_api(api, cors)
        def get(self, app, uniq):
            """Returns list of local instances."""
            return impl.get('/'.join([app, uniq]))

    @app_ns.route('/<app>/<uniq>/sys/<component>',)
    class _AppSystemLog(restplus.Resource):
        """Local app details resource."""

        @webutils.raw_get_api(api, cors, parser=req_parser)
        def get(self, app, uniq, component):
            """Return content of system component log.."""
            args = req_parser.parse_args()
            return flask.Response(
                impl.log.get('/'.join([app, uniq, 'sys', component]),
                             start=args.get('start'),
                             limit=args.get('limit'),
                             order=args.get('order')),
                mimetype='text/plain')

    @app_ns.route('/<app>/<uniq>/service/<service>',)
    class _AppServiceLog(restplus.Resource):
        """Local app details resource."""

        @webutils.raw_get_api(api, cors, parser=req_parser)
        def get(self, app, uniq, service):
            """Return content of system component log.."""
            args = req_parser.parse_args()
            return flask.Response(
                impl.log.get('/'.join([app, uniq, 'app', service]),
                             start=args.get('start'),
                             limit=args.get('limit'),
                             order=args.get('order')),
                mimetype='text/plain')

    archive_ns = api.namespace('archive',
                               description='Local archive REST operations')

    @archive_ns.route('/<app>/<uniq>/sys')
    class _SysArchiveAsAttachment(restplus.Resource):
        """Download sys archive as attachment."""

        @webutils.raw_get_api(api, cors)
        def get(self, app, uniq):
            """Return content of sys archived file.."""
            fname = impl.archive.get('/'.join([app, uniq, 'sys']))

            return flask.send_file(
                fname,
                as_attachment=True,
                attachment_filename=os.path.basename(fname)
            )

    @archive_ns.route('/<app>/<uniq>/app')
    class _AppArchiveAsAttachment(restplus.Resource):
        """Download app archive as attachment."""

        @webutils.raw_get_api(api, cors)
        def get(self, app, uniq):
            """Return content of app archived file.."""
            fname = impl.archive.get('/'.join([app, uniq, 'app']))

            return flask.send_file(
                fname,
                as_attachment=True,
                attachment_filename=os.path.basename(fname)
            )

    metrics_ns = api.namespace('metrics', description='Local metrics '
                               'REST operations')

    metrics_req_parser = api.parser()
    metrics_req_parser.add_argument(
        'timeframe',
        choices=('short', 'long'),
        default='short',
        help="Whether to query the metrics for shorter or longer timeframe.",
        location='args',
        required=False,
        type=str)

    @metrics_ns.route('/',)
    class _MetricsList(restplus.Resource):
        """Local metrics list resource."""

        @webutils.get_api(api, cors)
        def get(self):
            """Returns list of locally available metrics."""
            return impl.list(flask.request.args.get('state'), inc_svc=True)

    @metrics_ns.route('/<app>/<uniq>')
    @metrics_ns.route('/<service>')
    class _Metrics(restplus.Resource):
        """Download metrics."""

        @webutils.raw_get_api(api, cors, parser=metrics_req_parser)
        def get(self, **id_parts):
            """
            Return metrics either as an attachment or as json.
            """
            args = metrics_req_parser.parse_args()
            if webutils.wants_json_resp(flask.request):
                return self._get(self._to_rsrc_id(**id_parts),
                                 args.get('timeframe'))
            else:
                return self._get_as_attach(self._to_rsrc_id(**id_parts),
                                           args.get('timeframe'))

        def _to_rsrc_id(self, **id_parts):
            """
            Return the metrics resource id based on the keyword args.
            """
            try:
                rsrc_id = '/'.join([id_parts['app'], id_parts['uniq']])
            except KeyError:
                rsrc_id = id_parts['service']

            return rsrc_id

        def _get(self, rsrc_id, timeframe):
            """Return the metrics file as json."""
            return flask.Response(impl.metrics.get(rsrc_id, timeframe,
                                                   as_json=True),
                                  mimetype='application/json')

        def _get_as_attach(self, rsrc_id, timeframe):
            """Return the metrics file as attachment."""
            return flask.send_file(
                impl.metrics.get(rsrc_id, timeframe),
                as_attachment=True,
                mimetype='application/octet-stream',
                attachment_filename=os.path.basename(
                    impl.metrics.file_path(rsrc_id)
                )
            )
Local node REST api. # pylint: disable=E0611,F0401 # pylint: disable=W0232,R0912 Configures REST handlers for allocation resource. Local app list resource. Returns list of local instances. Local app details resource. Returns list of local instances. Local app details resource. Return content of system component log.. Local app details resource. Return content of system component log.. Download sys archive as attachment. Return content of sys archived file.. Download app archive as attachment. Return content of app archived file.. Local metrics list resource. Returns list of locally available metrics. Download metrics. Return metrics either as an attachment or as json. Return the metrics resource id based on the keyword args. Return the metrics file as json. Return the metrics file as attachment.