Beispiel #1
0
def api_websocket(accessor=None):
    """Meant for use with the websocket and API.

    Make a connection to this function, and then pass it the API
    path you wish to receive. Function returns only the raw value
    and unit in list form.

    """
    sane_args = dict(request.args)
    sane_args['accessor'] = accessor

    # Refresh the root node before creating the websocket
    psapi.refresh()

    if request.environ.get('wsgi.websocket'):
        config = listener.config['iconfig']
        ws = request.environ['wsgi.websocket']
        while True:
            try:
                message = ws.receive()
                node = psapi.getter(message, config, request.path, cache=True)
                prop = node.name
                val = node.walk(first=True, **sane_args)
                jval = json.dumps(val[prop])
                ws.send(jval)
            except Exception as e:
                # Socket was probably closed by the browser changing pages
                logging.debug(e)
                ws.close()
                break
    return ''
Beispiel #2
0
def graph(accessor=None):
    """
    Accessor method for fetching the HTML for the real-time graphing.

    :param accessor: The API path to be accessed (see /api)
    :type accessor: unicode
    :rtype: flask.Response
    """
    info = {'graph_path': accessor,
            'graph_hash': hash(accessor)}

    # Refresh the root node before creating the websocket
    psapi.refresh()

    node = psapi.getter(accessor, listener.config['iconfig'], request.path, cache=True)
    prop = node.name

    if request.values.get('delta'):
        info['delta'] = 1
    else:
        info['delta'] = 0

    info['graph_prop'] = prop
    query_string = request.query_string
    info['query_string'] = urllib.quote(query_string)

    url = urlparse.urlparse(request.url)
    info['load_from'] = url.scheme + '://' + url.netloc
    info['load_websocket'] = url.netloc

    # Generate page and add cross-domain loading
    response = make_response(render_template('graph.html', **info))
    response.headers['Access-Control-Allow-Origin'] = '*'

    return response
Beispiel #3
0
def graph(accessor=None):
    """
    Accessor method for fetching the HTML for the real-time graphing.

    :param accessor: The API path to be accessed (see /api)
    :type accessor: unicode
    :rtype: flask.Response
    """
    info = {'graph_path': accessor,
            'graph_hash': hash(accessor)}

    node = psapi.getter(accessor, listener.config['iconfig'])
    prop = node.name

    if request.values.get('delta'):
        info['delta'] = 1
    else:
        info['delta'] = 0

    info['graph_prop'] = prop
    query_string = request.query_string
    info['query_string'] = urllib.quote(query_string)

    return render_template('graph.html',
                           **info)
Beispiel #4
0
def api_websocket(accessor=None):
    """Meant for use with the websocket and API.

    Make a connection to this function, and then pass it the API
    path you wish to receive. Function returns only the raw value
    and unit in list form.

    """
    sane_args = dict(request.args)
    sane_args['accessor'] = accessor

    # Refresh the root node before creating the websocket
    psapi.refresh()

    if request.environ.get('wsgi.websocket'):
        config = listener.config['iconfig']
        ws = request.environ['wsgi.websocket']
        while True:
            try:
                message = ws.receive()
                node = psapi.getter(message, config, cache=True)
                prop = node.name
                val = node.walk(first=True, **sane_args)
                jval = json.dumps(val[prop])
                ws.send(jval)
            except (AttributeError, geventwebsocket.WebSocketError) as e:
                # Socket was probably closed by the browser changing pages
                logging.debug(e)
                break
    return ''
Beispiel #5
0
def graph(accessor=None):
    """
    Accessor method for fetching the HTML for the real-time graphing.

    :param accessor: The API path to be accessed (see /api)
    :type accessor: unicode
    :rtype: flask.Response
    """
    info = {'graph_path': accessor,
            'graph_hash': hash(accessor)}

    node = psapi.getter(accessor, listener.config['iconfig'])
    prop = node.name

    if request.values.get('delta'):
        info['delta'] = 1
    else:
        info['delta'] = 0

    info['graph_prop'] = prop
    query_string = request.query_string
    info['query_string'] = urllib.quote(query_string)

    return render_template('graph.html',
                           **info)
Beispiel #6
0
def api(accessor=''):
    """
    The function that serves up all the metrics. Given some path/to/a/metric it will
    retrieve the metric and do the necessary walking of the tree.

    :param accessor: The path/to/the/desired/metric
    :type accessor: unicode
    :rtype: flask.Response
    """
    
    # Setup sane/safe arguments for actually getting the data. We take in all
    # arguments that were passed via GET/POST. If they passed a config variable
    # we clobber it, as we trust what is in the config.
    sane_args = dict(request.values)

    # Special cases for 'service' and 'process' to make NCPA v1.7 backwards compatible
    # with probably the most disgusting code ever written but needed to work ASAP for
    # those who had checks set up before the changes.
    path = [re.sub('%2f', '/', x, flags=re.I) for x in accessor.split('/') if x]
    if len(path) > 0 and path[0] == 'api':
        path = path[1:]
    if len(path) > 0:
        node_name, rest_path = path[0], path[1:]

        if node_name == "service":
            accessor = "services"
            if len(rest_path) > 0:
                sane_args['service'] = [rest_path[0]]
                if len(rest_path) == 2:
                    sane_args['status'] = [rest_path[1]]
                    sane_args['check'] = True;
        elif node_name == "process":
            accessor = "processes"
            if len(rest_path) > 0:
                sane_args['name'] = [rest_path[0]]
                if len(rest_path) == 2:
                    if rest_path[1] == "count":
                        sane_args['check'] = True
            
    try:
        config = listener.config['iconfig']
        node = psapi.getter(accessor, config)
    except ValueError as exc:
        logging.exception(exc)
        return error(msg='Referencing node that does not exist: %s' % accessor)
    except IndexError as exc:
        # Hide the actual exception and just show nice output to users about changes in the API functionality
        return error(msg='Could not access location specified. Changes to API calls were made in NCPA v1.7, check documentation on making API calls.')

    # Set the accessor and variables
    sane_args['accessor'] = accessor
    sane_args['config'] = config
    if not 'check' in sane_args:
        sane_args['check'] = request.args.get('check', False);

    if sane_args['check']:
        value = node.run_check(**sane_args)
    else:
        value = node.walk(**sane_args)
    return jsonify({'value': value})
Beispiel #7
0
def graph(accessor=None):
    """
    Accessor method for fetching the HTML for the real-time graphing.

    :param accessor: The API path to be accessed (see /api)
    :type accessor: unicode
    :rtype: flask.Response
    """
    info = {'graph_path': accessor,
            'graph_hash': hash(accessor)}

    # Refresh the root node before creating the websocket
    psapi.refresh()

    node = psapi.getter(accessor, listener.config['iconfig'], request.path, cache=True)
    prop = node.name

    if request.values.get('delta'):
        info['delta'] = 1
    else:
        info['delta'] = 0

    info['graph_prop'] = prop
    query_string = request.query_string
    info['query_string'] = urllib.quote(query_string)

    url = urlparse.urlparse(request.url)
    info['load_from'] = url.scheme + '://' + url.netloc
    info['load_websocket'] = url.netloc

    # Generate page and add cross-domain loading
    response = make_response(render_template('graph.html', **info))
    response.headers['Access-Control-Allow-Origin'] = '*'

    return response
Beispiel #8
0
def api(accessor=''):
    """
    The function that serves up all the metrics. Given some path/to/a/metric it will
    retrieve the metric and do the necessary walking of the tree.

    :param accessor: The path/to/the/desired/metric
    :type accessor: unicode
    :rtype: flask.Response
    """

    # Setup sane/safe arguments for actually getting the data. We take in all
    # arguments that were passed via GET/POST. If they passed a config variable
    # we clobber it, as we trust what is in the config.
    sane_args = {}
    for value in request.values:
        sane_args[value] = request.args.getlist(value)

    # Set the full requested path
    full_path = request.path

    # Set the accessor and variables
    sane_args['debug'] = request.args.get('debug', False)
    sane_args['remote_addr'] = request.remote_addr
    sane_args['accessor'] = accessor

    # Add config to sane_args
    config = listener.config['iconfig']
    sane_args['config'] = config

    # Check if we are running a check or not
    if not 'check' in sane_args:
        sane_args['check'] = request.args.get('check', False)

    # Try to get the node that was specified
    try:
        node = psapi.getter(accessor, config, full_path, request.args)
    except ValueError as exc:
        logging.exception(exc)
        return error(msg='Referencing node that does not exist: %s' % accessor)
    except IndexError as exc:
        # Hide the actual exception and just show nice output to users about changes in the API functionality
        return error(msg='Could not access location specified. Changes to API calls were made in NCPA v1.7, check documentation on making API calls.')

    # Check for default unit in the config values
    default_units = get_config_value('general', 'default_units')
    if default_units:
        if not 'units' in sane_args:
            sane_args['units'] = default_units

    if sane_args['check']:
        value = node.run_check(**sane_args)
    else:
        value = node.walk(**sane_args)

    # Generate page and add cross-domain loading
    json_data = json.dumps(dict(value), ensure_ascii=False, indent=None if request.is_xhr else 4)
    response = Response(json_data, mimetype='application/json')
    response.headers['Access-Control-Allow-Origin'] = '*'
    return response
Beispiel #9
0
def graph(accessor=None):
    """
    Accessor method for fetching the HTML for the real-time graphing.

    :param accessor: The API path to be accessed (see /api)
    :type accessor: unicode
    :rtype: flask.Response
    """
    info = {'graph_path': accessor,
            'graph_hash': hash(accessor)}

    node = psapi.getter(accessor, listener.config['iconfig'])
    prop = node.name

    if request.values.get('delta'):
        info['delta'] = 1
    else:
        info['delta'] = 0

    unit = request.args.get('unit', 'a').upper()
    if unit in ['K', 'M', 'G']:
        info['unit'] = unit
    else:
        info['unit'] = ''

    factor = 1
    if unit == 'K':
        factor = 1e3
    elif unit == 'M':
        factor = 1e6
    elif unit == 'G':
        factor = 1e9
    info['factor'] = factor

    node = psapi.getter(accessor, listener.config['iconfig'])
    prop = node.name

    info['graph_prop'] = prop
    query_string = request.query_string
    info['query_string'] = urllib.quote(query_string)

    return render_template('graph.html',
                           **info)
Beispiel #10
0
def api_websocket(accessor=None):
    """Meant for use with the websocket and API.

    Make a connection to this function, and then pass it the API
    path you wish to receive. Function returns only the raw value
    and unit in list form.

    """
    sane_args = dict(request.args)
    sane_args['accessor'] = accessor

    if request.environ.get('wsgi.websocket'):
        config = listener.config['iconfig']
        ws = request.environ['wsgi.websocket']
        while True:
            message = ws.receive()
            node = psapi.getter(message, config)
            prop = node.name
            val = node.walk(first=True, **sane_args)
            jval = json.dumps(val[prop])
            ws.send(jval)
    return
Beispiel #11
0
def api_websocket(accessor=None):
    """Meant for use with the websocket and API.

    Make a connection to this function, and then pass it the API
    path you wish to receive. Function returns only the raw value
    and unit in list form.

    """
    sane_args = dict(request.args)
    sane_args['accessor'] = accessor

    if request.environ.get('wsgi.websocket'):
        config = listener.config['iconfig']
        ws = request.environ['wsgi.websocket']
        while True:
            message = ws.receive()
            node = psapi.getter(message, config)
            prop = node.name
            val = node.walk(first=True, **sane_args)
            jval = json.dumps(val[prop])
            ws.send(jval)
    return
Beispiel #12
0
def api(accessor=''):
    """
    The function that serves up all the metrics. Given some path/to/a/metric it will
    retrieve the metric and do the necessary walking of the tree.

    :param accessor: The path/to/the/desired/metric
    :type accessor: unicode
    :rtype: flask.Response
    """

    # Setup sane/safe arguments for actually getting the data. We take in all
    # arguments that were passed via GET/POST. If they passed a config variable
    # we clobber it, as we trust what is in the config.
    sane_args = {}
    for value in request.values:
        sane_args[value] = request.args.getlist(value)

    #
    # As of version 2.0.0 there are now 3 different paths that are backwards
    # compatible using this section. After looking into it further the location
    # of this should be around here. Changing the incoming request is the only
    # way to make something happen without updating the way the API looks/returns.
    # You can think of these as aliases. Below explains the aliases and when they
    # will be removed. As of 2.0.0 they are deprecated. Will be removed in 3.
    #
    # Deprecated Aliases:
    #
    #   Aliases (up to 1.8.1)     || Location (2.0.0)
    #   ---------------------------------------------------------------------
    #   api/service/<servicename> -> api/services?service=<servicename>
    #   api/process/<processname> -> api/processes?name=<processname>
    #   api/agent/plugin/<plugin> -> api/plugins/<plugin>
    #
    path = [
        re.sub('%2f', '/', x, flags=re.I) for x in accessor.split('/') if x
    ]
    if len(path) > 0 and path[0] == 'api':
        path = path[1:]
    if len(path) > 0:
        node_name, rest_path = path[0], path[1:]

        if node_name == "service":
            accessor = "services"
            if len(rest_path) > 0:
                sane_args['service'] = [rest_path[0]]
                if len(rest_path) == 2:
                    sane_args['status'] = [rest_path[1]]
                    sane_args['check'] = True
        elif node_name == "process":
            accessor = "processes"
            if len(rest_path) > 0:
                sane_args['name'] = [rest_path[0]]
                if len(rest_path) == 2:
                    if rest_path[1] == "count":
                        sane_args['check'] = True
        elif node_name == "agent":
            accessor = "plugins"
            if 'plugin' in rest_path[0] and len(rest_path) > 1:
                accessor = "plugins/" + rest_path[1]

    # Set the full requested path
    full_path = request.path

    try:
        config = listener.config['iconfig']
        node = psapi.getter(accessor, config, full_path)
    except ValueError as exc:
        logging.exception(exc)
        return error(msg='Referencing node that does not exist: %s' % accessor)
    except IndexError as exc:
        # Hide the actual exception and just show nice output to users about changes in the API functionality
        return error(
            msg=
            'Could not access location specified. Changes to API calls were made in NCPA v1.7, check documentation on making API calls.'
        )

    # Set the accessor and variables
    sane_args['remote_addr'] = request.remote_addr
    sane_args['accessor'] = accessor
    sane_args['config'] = config

    sane_args['debug'] = request.args.get('debug', False)

    if not 'check' in sane_args:
        sane_args['check'] = request.args.get('check', False)

    if sane_args['check']:
        value = node.run_check(**sane_args)
    else:
        value = node.walk(**sane_args)

    # Generate page and add cross-domain loading
    response = Response(json.dumps(dict(value),
                                   ensure_ascii=False,
                                   indent=None if request.is_xhr else 4),
                        mimetype='application/json')
    response.headers['Access-Control-Allow-Origin'] = '*'
    return response
Beispiel #13
0
def api(accessor=''):
    """
    The function that serves up all the metrics. Given some path/to/a/metric it will
    retrieve the metric and do the necessary walking of the tree.

    :param accessor: The path/to/the/desired/metric
    :type accessor: unicode
    :rtype: flask.Response
    """

    # Setup sane/safe arguments for actually getting the data. We take in all
    # arguments that were passed via GET/POST. If they passed a config variable
    # we clobber it, as we trust what is in the config.
    sane_args = {}
    for value in request.values:
        sane_args[value] = request.args.getlist(value)

    #
    # As of version 2.0.0 there are now 3 different paths that are backwards
    # compatible using this section. After looking into it further the location
    # of this should be around here. Changing the incoming request is the only
    # way to make something happen without updating the way the API looks/returns.
    # You can think of these as aliases. Below explains the aliases and when they
    # will be removed. As of 2.0.0 they are deprecated. Will be removed in 2.1.0.
    #
    # Deprecated Aliases:
    #
    #   Aliases (up to 1.8.1)     || Location (2.0.0)
    #   ---------------------------------------------------------------------
    #   api/service/<servicename> -> api/services?service=<servicename>
    #   api/process/<processname> -> api/processes?name=<processname>
    #   api/agent/plugin/<plugin> -> api/plugins/<plugin>
    #
    path = [re.sub('%2f', '/', x, flags=re.I) for x in accessor.split('/') if x]
    if len(path) > 0 and path[0] == 'api':
        path = path[1:]
    if len(path) > 0:
        node_name, rest_path = path[0], path[1:]

        if node_name == "service":
            accessor = "services"
            if len(rest_path) > 0:
                sane_args['service'] = [rest_path[0]]
                if len(rest_path) == 2:
                    sane_args['status'] = [rest_path[1]]
                    sane_args['check'] = True;
        elif node_name == "process":
            accessor = "processes"
            if len(rest_path) > 0:
                sane_args['name'] = [rest_path[0]]
                if len(rest_path) == 2:
                    if rest_path[1] == "count":
                        sane_args['check'] = True
        elif node_name == "agent":
            accessor = "plugins"
            if 'plugin' in rest_path[0] and len(rest_path) > 1:
                accessor = "plugins/" + rest_path[1]

    # Set the full requested path
    full_path = request.path

    try:
        config = listener.config['iconfig']
        node = psapi.getter(accessor, config, full_path)
    except ValueError as exc:
        logging.exception(exc)
        return error(msg='Referencing node that does not exist: %s' % accessor)
    except IndexError as exc:
        # Hide the actual exception and just show nice output to users about changes in the API functionality
        return error(msg='Could not access location specified. Changes to API calls were made in NCPA v1.7, check documentation on making API calls.')

    # Set the accessor and variables
    sane_args['remote_addr'] = request.remote_addr
    sane_args['accessor'] = accessor
    sane_args['config'] = config

    sane_args['debug'] = request.args.get('debug', False)

    if not 'check' in sane_args:
        sane_args['check'] = request.args.get('check', False)

    if sane_args['check']:
        value = node.run_check(**sane_args)
    else:
        value = node.walk(**sane_args)

    # Generate page and add cross-domain loading
    response = Response(json.dumps(dict(value), indent=None if request.is_xhr else 4), mimetype='application/json')
    response.headers['Access-Control-Allow-Origin'] = '*'
    return response