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 ''
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
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)
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 ''
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})
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
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)
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
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
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