Data API
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¶m1[x]=val1¶m2[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¶m[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¶m[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¶m[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¶m[x]=TESTID¶m1[x]=STARTX¶m2[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¶m[x]=TESTID¶m1[x]=STARTX¶m2[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¶m[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.="¶m[".$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+"¶m[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>