Esempio n. 1
0
    def invoke_grp(authz):
        """Directly invoke Treadmill API without REST."""
        if authz is not None:
            ctx.authorizer = authz_mod.ClientAuthorizer(
                utils.get_current_username, authz)
        else:
            ctx.authorizer = authz_mod.NullAuthorizer()

        if cli.OUTPUT_FORMAT is None:
            raise click.BadParameter('must use --outfmt [json|yaml]')
Esempio n. 2
0
    def invoke(authz):
        """Directly invoke Treadmill API without REST."""
        if authz is not None:
            ctx.authorizer = authz_mod.ClientAuthorizer(
                lambda: pwd.getpwuid(os.getuid()).pw_name, authz)
        else:
            ctx.authorizer = authz_mod.NullAuthorizer()

        if cli.OUTPUT_FORMAT == 'pretty':
            raise click.BadParameter('must use --outfmt [json|yaml]')
Esempio n. 3
0
def get_authorizer(authz_arg=None):
    """Get authozrizer by argujents"""
    def user_clbk():
        """Get current user from the request."""
        return flask.g.get('user')

    if authz_arg is None:
        authorizer = authz.NullAuthorizer()
    else:
        authorizer = authz.ClientAuthorizer(user_clbk, authz_arg)
    return authorizer
Esempio n. 4
0
def _run_sync():
    """Sync app monitor count with instance count."""

    instance_api = instance.init(authz.NullAuthorizer())
    zkclient = context.GLOBAL.zk.conn

    while True:
        scheduled = sorted(master.list_scheduled_apps(zkclient))
        appname_f = lambda n: n[:n.find('#')]
        grouped = collections.defaultdict(
            list,
            {k: list(v)
             for k, v in itertools.groupby(scheduled, appname_f)})

        appmonitors = master.appmonitors(zkclient)
        for appname in appmonitors:
            data = master.get_appmonitor(zkclient, appname)
            if not data:
                _LOGGER.info('App monitor does not exist: %s', appname)
                continue

            count = data['count']
            current_count = len(grouped[appname])
            _LOGGER.debug('App: %s current: %s, target %s', appname,
                          current_count, count)
            if count == current_count:
                continue

            if count > current_count:
                # need to start more.
                needed = count - current_count
                scheduled = instance_api.create(appname, {}, count=needed)

            if count < current_count:
                for extra in grouped[appname][:current_count - count]:
                    instance_api.delete(extra)

        time.sleep(60)
Esempio n. 5
0
def _run_sync():
    """Sync app monitor count with instance count."""

    instance_api = instance.init(authz.NullAuthorizer())
    zkclient = context.GLOBAL.zk.conn

    state = {'scheduled': {}, 'monitors': {}}

    @zkclient.ChildrenWatch(z.path.scheduled())
    @exc.exit_on_unhandled
    def _scheduled_watch(children):
        """Watch scheduled instances."""
        scheduled = sorted(children)
        grouped = collections.defaultdict(
            list, {
                k: list(v)
                for k, v in itertools.groupby(scheduled,
                                              lambda n: n.rpartition('#')[0])
            })
        state['scheduled'] = grouped
        return True

    def _watch_monitor(name):
        """Watch monitor."""

        # Establish data watch on each monitor.
        @zkclient.DataWatch(z.path.appmonitor(name))
        @exc.exit_on_unhandled
        def _monitor_data_watch(data, _stat, event):
            """Monitor individual monitor."""
            if (event and event.type == 'DELETED') or (data is None):
                _LOGGER.info('Removing watch on deleted monitor: %r', name)
                return False

            try:
                count = yaml.load(data)['count']
            except Exception:  # pylint: disable=W0703
                _LOGGER.exception('Invalid monitor: %r', name)
                return False

            _LOGGER.info('Reconfigure monitor: %s, count: %s', name, count)
            state['monitors'][name] = {
                'count': count,
                'available': 2.0 * count,
                'last_update': time.time(),
                'rate': (2.0 * count / _INTERVAL)
            }
            return True

    @zkclient.ChildrenWatch(z.path.appmonitor())
    @exc.exit_on_unhandled
    def _appmonitors_watch(children):
        """Watch app monitors."""

        monitors = set(children)
        extra = state['monitors'].keys() - monitors
        for name in extra:
            _LOGGER.info('Removing extra monitor: %r', name)
            if state['monitors'].pop(name, None) is None:
                _LOGGER.warn('Failed to remove non-existent monitor: %r', name)

        missing = monitors - state['monitors'].keys()

        for name in missing:
            _LOGGER.info('Adding missing monitor: %s', name)
            _watch_monitor(name)

    _LOGGER.info('Ready')

    while True:
        time.sleep(1)
        if not reevaluate(instance_api, state):
            _LOGGER.error('Unhandled exception while evaluating state.')
            break
Esempio n. 6
0
 def __init__(self, authorizer=None, journaler=None):
     self.authorizer = (authz_mod.NullAuthorizer()
                        if authorizer is None else authorizer)
     self.journaler = (jplugin.NullJournaler()
                       if journaler is None else journaler)
Esempio n. 7
0
 def __init__(self):
     self.authorizer = authz.NullAuthorizer()
Esempio n. 8
0
def init(apis, title=None, cors_origin=None, authz_arg=None):
    """Module initialization."""

    blueprint = flask.Blueprint('v1', __name__)

    api = restplus.Api(blueprint,
                       version='1.0',
                       title=title,
                       description="Treadmill REST API Documentation")

    error_handlers.register(api)

    # load up any external error_handlers
    try:
        err_handlers_plugin = importlib.import_module(
            'treadmill.plugins.rest.error_handlers')
        err_handlers_plugin.init(api)
    except ImportError as err:
        _LOGGER.warn('Unable to load error_handlers plugin: %s', err)

    @blueprint.route('/docs/', endpoint='docs')
    def _swagger_ui():
        """Swagger documentation route"""
        return restplus.apidoc.ui_for(api)

    rest.FLASK_APP.register_blueprint(blueprint)
    rest.FLASK_APP.register_blueprint(restplus.apidoc.apidoc)

    cors = webutils.cors(origin=cors_origin,
                         content_type='application/json',
                         credentials=True)

    @rest.FLASK_APP.after_request
    def _after_request_cors_handler(response):
        """Process all OPTIONS request, thus don't need to add to each app"""
        if flask.request.method != 'OPTIONS':
            return response

        _LOGGER.debug('This is an OPTIONS call')

        def _noop_options():
            """No noop response handler for all OPTIONS"""
            pass

        headers = flask.request.headers.get('Access-Control-Request-Headers')
        options_cors = webutils.cors(origin=cors_origin,
                                     credentials=True,
                                     headers=headers)
        response = options_cors(_noop_options)()
        return response

    def user_clbk():
        """Get current user from the request."""
        return flask.request.environ.get('REMOTE_USER')

    if authz_arg is None:
        authorizer = authz.NullAuthorizer()
    else:
        authorizer = authz.ClientAuthorizer(user_clbk, authz_arg)

    endpoints = []
    for apiname in apis:
        try:
            apimod = apiname.replace('-', '_')
            _LOGGER.info('Loading api: %s', apimod)

            api_restmod = importlib.import_module('.'.join(
                ['treadmill', 'rest', 'api', apimod]))
            api_implmod = importlib.import_module('.'.join(
                ['treadmill', 'api', apimod]))

            api_impl = api_implmod.init(authorizer)
            endpoint = api_restmod.init(api, cors, api_impl)
            if endpoint is None:
                endpoint = apiname.replace('_', '-').replace('.', '/')
            if not endpoint.startswith('/'):
                endpoint = '/' + endpoint

            endpoints.append(endpoint)

        except ImportError as err:
            _LOGGER.warn('Unable to load %s api: %s', apimod, err)

    return endpoints
Esempio n. 9
0
def _run_sync():
    """Sync app monitor count with instance count."""

    instance_api = instance.init(authz.NullAuthorizer())
    zkclient = context.GLOBAL.zk.conn

    state = {'scheduled': {}, 'monitors': {}}

    @zkclient.ChildrenWatch(z.path.scheduled())
    @exc.exit_on_unhandled
    def _scheduled_watch(children):
        """Watch scheduled instances."""
        scheduled = sorted(children)
        appname_f = lambda n: n[:n.find('#')]
        grouped = collections.defaultdict(
            list,
            {k: list(v)
             for k, v in itertools.groupby(scheduled, appname_f)})
        state['scheduled'] = grouped
        reevaluate(instance_api, state)
        return True

    def _watch_monitor(name):
        """Watch monitor."""

        # Establish data watch on each monitor.
        @zkclient.DataWatch(z.path.appmonitor(name))
        @exc.exit_on_unhandled
        def _monitor_data_watch(data, _stat, event):
            """Monitor individual monitor."""
            if (event and event.type == 'DELETED') or (data is None):
                try:
                    del state['monitors'][name]
                except KeyError:
                    pass

                _LOGGER.info('Removing watch on deleted monitor: %s', name)
                return False

            try:
                count = yaml.load(data)['count']
            except Exception:  # pylint: disable=W0703
                _LOGGER.exception('Invalid monitor: %s', name)
                return False

            _LOGGER.info('Reconfigure monitor: %s, count: %s', name, count)
            state['monitors'][name] = count
            reevaluate(instance_api, state)
            return True

    @zkclient.ChildrenWatch(z.path.appmonitor())
    @exc.exit_on_unhandled
    def _appmonitors_watch(children):
        """Watch app monitors."""

        monitors = set(children)
        extra = set(state['monitors'].keys()) - monitors
        for name in extra:
            _LOGGER.info('Removing extra monitor: %s', name)
            del state['monitors'][name]

        missing = monitors - set(state['monitors'].keys())

        for name in missing:
            _LOGGER.info('Adding missing monitor: %s', name)
            _watch_monitor(name)

    _LOGGER.info('Ready')

    while True:
        time.sleep(6000)