Data API

From FreeNATS Wiki
Jump to: navigation, search

JavaScript and XML Data API

FreeNATS provides an Application Program Interface (API) which allows developers to query certain information from the system either in XML format or as JavaScript arrays.

Queries are passed in a URL-encoded query HTTP/S request to api.php

Security

Security is an important consideration as although the API is read-only and designed to be as SQL injection proof as any other portion of the system other information (such as account passwords for a test) may be exposed by someone using the correct functionality of the system but without your permission.

The API security model is similar to that of the graphs. By default only requests authenticated into FreeNATS will be accepted (those presenting the cookies for a valid session).

You can set the variable api.public to 1. At this point there are no authentication requirements for the API and anyone can query it.

The variable api.key can optionally be set to an alphanumeric string. This must then be provided by public (unauthenticated - authenticated users never have to provide an API key) in the request URI as the variable apikey.

However you use this system though if you are using the JavaScript interface then an enterprising "hacker" could always get your key and see raw data through a JavaScript console. XML on a non-user-exposed script is always the recommended method.

API Modes

The API supports two modes (xml for XML and js for JavaScript) which are passed with mode=X in the URI (if no mode is specified XML is assumed).

XML outputs a formatted XML 1.0 document containing the data and various attributes which are not available in JavaScript. The JavaScript output will build an output data array containing all the information (but in a much nastier form).

Queries

A request to the API takes the form of one or more queries with optional parameters. These are passed un the URI as an encoded array with each element numbered individually. The query is passed as query[x]=NAME and any paramaters as param[x]=val&param1[x]=val1&param2[x]=val etc.

For example we may wish to do an "alerts" query and then a "node" query on a node with a nodeid of "fish". In this case the query portion of the URI would be:

    query[0]=alerts&query[1]=node&param[1]=fish

JavaScript API Data Object and Callback

If you specify the type as JavaScript the data is written into an array. By default this data object is named fnd_SOMERANDOM but you can specify the name of the object by passing it as the URI variable dataid.

You can also optionally pass the URI variable callback=JAVASCRIPT_FUNCTION_NAME which will cause the script to call that function passing the data object as the only parameter.


Query Types

node

Outputs all fields from fnnode and some additional data for the nodeid passed in param

Parameters

param[x]=nodeid (required) 

Example

query[x]=node&param[x]=NODEID 

Example XML Output

<node nodeid="NODEID" query="X">

... for every field Z ...
<FIELD-NAME>VALUE</FIELD-NAME>

</node>

Example JavaScript Output

data[x]=new Array;

... for every field Z ...
data[x][Z]=new Array;
data[x][Z][0]=FIELD-NAME;
data[x][Z][1]=VALUE;

Data Provided

All the fields of fnnode are provided in the data along with some additional computed fields but their index (Z in the above example) cannot be guarenteed so types should always be checked. You should have a manual look at the output to see what fields are precisely available but notable fields include:

alertlevel - numeric reprensentation of last status
alerttext - textual string for the same
lastrundt - string datetime the last time the node was tested
lastrunago - string in the form HH:MM:SS showing how long ago the node was last tested

nodelist

Outputs a list of nodes (those enabled or all) and their current alert statuses. Can be used to build further dynamic requests.

Parameters

param[x]=1 (optional) 

If param[x] is omitted or anything other than 1 only enabled nodes will be listed. If it is a 1 then all nodes are returned.

Example

query[x]=node&param[x]=1

Example XML Output

<nodelist count="COUNT" query="X">

... for every node Z ...
<node nodeid="NODEID" alertlevel="ALERTLEVEL">NODEID</node>

</nodelist>

Example JavaScript Output

data[x]=new Array;

... for every node Z ...
data[x][Z]=new Array;
data[x][Z][0]=NODEID;
data[x][Z][1]=ALERTLEVEL;

Data Provided

The node id and the current alert level for each node in the list.


test

Outputs all fields from relevant test table (i.e. fnlocaltest) and some additional data for the testid passed in param. Will optionally output average test values and output over the period if a range is specified in param1 and param2.

Parameters

param[x]=testid (required)

Optional Time Period Parameters:
param1[x]=STARTX (optional)
param2[x]=FINISHX (optional)

STARTX and FINISHX can either be positive numbers which are treated as UNIXTIME (seconds since the epoch), 0 meaning now or a negative number which is the number of seconds ago to run. For example a STARTX of -3600 and a FINISHX of 0 would refer to the period from an hour ago (3600 seconds) to now.

Example

query[x]=test&param[x]=TESTID&param1[x]=STARTX&param2[x]=FINISHX

Example XML Output

<node nodeid="NODEID" query="X">

... for every field Z ...
<FIELD-NAME>VALUE</FIELD-NAME>

</node>


Example JavaScript Output

data[x]=new Array;

... for every field Z ...
data[x][Z]=new Array;
data[x][Z][0]=FIELD-NAME;
data[x][Z][1]=VALUE;

Data Provided

All the fields of the relevant test table are provided in the data along with some additional computed fields but their index (Z in the above example) cannot be guarenteed so types should always be checked. You should have a manual look at the output to see what fields are precisely available but notable fields include:

alertlevel - numeric reprensentation of last status
alerttext - textual string for the same
lastrundt - string datetime the last time the node was tested
lastrunago - string in the form HH:MM:SS showing how long ago the node was last tested lastvalue - last value recorded by the test

If you have provided a time range in param1 and 2 then you will have the following fields available:

period.tested - number of test records for the period
period.passed - number passed
period.failed - number failed
period.untested - number untested (scheduling etc)
period.warning - number of warnings
period.average - average value of passed (and warned) tests

testdata

Outputs recorded data for the test specified over the period given

Parameters

param[x]=testid (required)
param1[x]=STARTX (required)
param2[x]=FINISHX (required)

STARTX and FINISHX have the same function as for the "test" query above.

Example

query[x]=testdata&param[x]=TESTID&param1[x]=STARTX&param2[x]=FINISHX 

Example XML Output

<testdata testid="TESTID" query="X" counter="NUM_ROWS">

... for every record Z ...
<record recordx="RECORDX" alertlevel="ALERTLEVEL">VALUE</record>

</testdata>

Example JavaScript Output

data[x]=new Array;

... for every record Z ...
data[x][Z]=new Array;
data[x][Z][0]=RECORDX;
data[x][Z][1]=VALUE;
data[x][Z][2]=ALERTLEVEL;

Data Provided

Data is provided in rows in the format described above


group

Outputs all fields from the fngroup table and some additional data for the groupid passed in param.

Parameters

param[x]=groupid (required)

Example

query[x]=group&param[x]=GROUPID

Example XML Output

<group testid="GROUPID" query="X">

... for every field Z ...
<FIELD-NAME>VALUE</FIELD-NAME>

</group>

Example JavaScript Output

data[x]=new Array;

... for every field Z ...
data[x][Z]=new Array;
data[x][Z][0]=FIELD-NAME;
data[x][Z][1]=VALUE;


Data Provided

All the fields of the group table are provided in the data along with some additional computed fields but their index (Z in the above example) cannot be guarenteed so types should always be checked. You should have a manual look at the output to see what fields are precisely available but notable fields include:

alertlevel - numeric reprensentation of last status
alerttext - textual string for the same
groupname - name of the group
groupdesc - description of the group

alerts

Outputs all currently alerting nodes

Parameters

No parameters

Example

query[x]=alerts

Example XML Output

<alerts count="NUM_ALERTS" query="X">

... for every alerting node ...
<node nodeid="NODEID" alertlevel="ALERTLEVEL">NODEID</node>

</alerts>

Example JavaScript Output

data[x]=new Array;

... for every alerting node ...
data[x][Z]=NODEID;


Data Provided

All alerting nodes are provided. The number of alerts can be simply checked with the count attribute (XML) or checking the length of the array (JS).



Example Output

To give you an idea here are some (abbreviated) example outputs for a single query[0] of type node for the nodeid bob.

XML Output

<freenats-data>
<alerts count="0" query="0">
</alerts>
<node nodeid="bob" query="1">
<nodeid>bob</nodeid>
<nodename>bob</nodename>
<nodedesc>Bob</nodedesc>
<hostname>10.0.10.248</hostname>
<nodeenabled>1</nodeenabled>
<pingtest>0</pingtest>
<pingfatal>0</pingfatal>
<alertlevel>0</alertlevel>
<nodeicon></nodeicon>
<weight>11</weight>
<nodealert>0</nodealert>
<scheduleid>0</scheduleid>
<name>bob</name>
<alerttext>Passed</alerttext>
</node>
</freenats-data>


JavaScript Output

No dataid passed so the data object name is randomly generated

var fnd_76af489a76=new Array();
fnd_76af489a76[0]=new Array();
fnd_76af489a76[1]=new Array();
fnd_76af489a76[1][0]=new Array;
fnd_76af489a76[1][0][0]='nodeid';
fnd_76af489a76[1][0][1]='bob';
fnd_76af489a76[1][1]=new Array;
fnd_76af489a76[1][1][0]='nodename';
fnd_76af489a76[1][1][1]='bob';
fnd_76af489a76[1][2]=new Array;
fnd_76af489a76[1][2][0]='nodedesc';
fnd_76af489a76[1][2][1]='Bob';
fnd_76af489a76[1][3]=new Array;
fnd_76af489a76[1][3][0]='hostname';
fnd_76af489a76[1][3][1]='10.0.10.248';
fnd_76af489a76[1][4]=new Array;
fnd_76af489a76[1][4][0]='nodeenabled';
fnd_76af489a76[1][4][1]='1';
fnd_76af489a76[1][5]=new Array;
fnd_76af489a76[1][5][0]='pingtest';
fnd_76af489a76[1][5][1]='0';
fnd_76af489a76[1][6]=new Array;
fnd_76af489a76[1][6][0]='pingfatal';
fnd_76af489a76[1][6][1]='0';
fnd_76af489a76[1][7]=new Array;
fnd_76af489a76[1][7][0]='alertlevel';
fnd_76af489a76[1][7][1]='0';
fnd_76af489a76[1][8]=new Array;
fnd_76af489a76[1][8][0]='nodeicon';
fnd_76af489a76[1][8][1]='';
fnd_76af489a76[1][9]=new Array;
fnd_76af489a76[1][9][0]='weight';
fnd_76af489a76[1][9][1]='11';
fnd_76af489a76[1][10]=new Array;
fnd_76af489a76[1][10][0]='nodealert';
fnd_76af489a76[1][10][1]='0';
fnd_76af489a76[1][11]=new Array;
fnd_76af489a76[1][11][0]='scheduleid';
fnd_76af489a76[1][11][1]='0';
fnd_76af489a76[1][12]=new Array;
fnd_76af489a76[1][12][0]='name';
fnd_76af489a76[1][12][1]='bob';
fnd_76af489a76[1][13]=new Array;
fnd_76af489a76[1][13][0]='alerttext';
fnd_76af489a76[1][13][1]='Passed';


And if the URI variable callback=DataHandler was passed the following would also be output:

DataHandler(fnd_76af489a76);


Code Examples

Simple PHP Script to Dump XML Output to Screen

<?php
$target = "http://FREENATS_URL/api.php?mode=xml";


$query=array();
$param=array();

$query[0]="alerts";

$query[1]="node";
$param[1]="bob";

$key=""; // Set Your API Key Here

$url=$target."&apikey=".$key;

foreach($query as $key => $val)
	{
	$url.="&query[".$key."]=".$val;
	if (isset($param[$key])) $url.="&param[".$key."]=".$param[$key];
	}
	
echo "<html><title>FreeNATS API XML</title>";
echo "<b>".$url."</b><br><br>";


echo "<pre>";

$depth = 0;

function startElement($parser, $name, $attrs) 
{
    global $depth;
    for ($i = 0; $i < $depth; $i++) {
        echo "  ";
    }
    echo "+ $name ";
    foreach($attrs as $key => $val)
    	{
	    echo $key."=".$val." ";
    	}
    echo "\n";
    $depth++;
}

function endElement($parser, $name) 
{
    global $depth;
    $depth--;
}

function characterData($parser, $data) 
{
	$data=trim($data); // remove whitespace
	if ($data!="")
		{
	    global $depth;
	    for ($i = 0; $i < $depth; $i++) {
	        echo "  ";
	    }
	    
	   	echo $data."\n";
		}
}

$xml_parser = xml_parser_create();
xml_set_element_handler($xml_parser, "startElement", "endElement");
xml_set_character_data_handler($xml_parser, "characterData");
if (!($fp = fopen($url, "r"))) {
    die("could not open XML input");
}

while ($data = fread($fp, 4096)) {
    if (get_magic_quotes_gpc()) $data=stripslashes($data);
    $result=xml_parse($xml_parser, $data, feof($fp))
    if (!$result) {
        die(sprintf("XML error: %s at line %d",
                    xml_error_string(xml_get_error_code($xml_parser)),
                    xml_get_current_line_number($xml_parser)));
    }
}
fclose($fp);
xml_parser_free($xml_parser);
echo "</pre>";

?>

Simple JavaScript/HTML Example

<html><title>FreeNATS API JavaScript</title>
<body>
<script type="text/javascript">



function HandleData(data)
{
document.write("<pre>");
if (data[0].length>0) // data[0] is the query[0] result array for alerts
	{
	document.write("There are alerts\n");
	}
else document.write("There are no alerts\n");

document.write("\nStatus for Node Queried in Q1\n");
for (i=0; i<data[1].length; i++)
	{
	document.write(data[1][i][0]+"="+data[1][i][1]+"\n");
	}

document.write("</pre>");
}



// Now Build the URL
var url="http://FREENATS_URL/api.php?mode=js";
url=url+"&apikey=";

url=url+"&query[0]=alerts";

url=url+"&query[1]=node";
url=url+"&param[1]=bob";

url=url+"&callback=HandleData";

document.write(url+"\n");

var output="<script src=\"";
output=output+url;
output=output+"\" ";
output=output+"type=\"";
output=output+"text/javascript\"";
output=output+">";
document.write(output);



</script>