16. NetSpyGlass Server JSON API¶
16.1. API v2.0¶
16.1.1. Status call¶
16.1.1.1. GET /v2/ui/net/:id/status[?s=order]¶
retrieve status. This includes defined network, latest discovery status, information about ongoing network discovery (if any), and views. The UI uses this API call to build the “home” page where each map view appears as a tile.
List of views (tiles) can be sorted according to the optional parameter s. Sort order is defined by the value, which can be ‘name’ or ‘id’. Sorting by the id makes views appear in the order in which they were created. If parameter s is not provided, views are sorted by the id.
16.1.2. Network topology and inventory (discovery data)¶
16.1.2.1. GET /v2/discovery/net/:id/topo?[timestamp=:time|generation=:gen]¶
returns network topology data in json format. Each device is represented by a brief summary that includes its name, address, id and tags. Each link is represented by a set of the following parameters: source device id, destination device id, source interface ifIndex, destination interface ifIndex, and vlan number.
Optional query parameters:
- timestamp if this parameter has value >0, then this call returns topology data from the latest discovery that has completed before the timestamp
- generation if this parameter has value >0, then this call returns data from the discovery with this generation number.
If both timestamp and generation are missing, or timestamp==0
and generation==-1
, then this
method returns topology data from the latest successful discovery.
If both timestamp > 0
and generation > 0
, this method uses the timestamp
16.1.2.2. GET /v2/discovery/net/:id/devices[?timestamp=:time|generation=:gen]¶
returns information about monitored devices (discovery data). Optional parameters timestamp and generation can be used to retrieve device data that corresponds to particular discovery generation
16.1.2.3. GET /v2/discovery/net/:id/devices/:devid[?timestamp=:time|generation=:gen]¶
returns information about device identified by its id (discovery data). Optional parameters timestamp and generation can be used to retrieve device data that corresponds to particular discovery generation
16.1.3. Calls used by the UI to access information about devices¶
16.1.3.1. GET /v2/ui/net/:id/dashboards/device/:id¶
this call serves the first (“Summary”) page of the device panel
16.1.3.2. GET /v2/ui/net/:id/data/device/:devid?[format=(brief|full)][category=:name]¶
returns information about device identified by its id (discovery data) with ability to choose format.
16.1.3.3. GET /v2/ui/net/:id/popup/device/:devid¶
this call returns information used to build popup graph that opens when user clicks device label in maps. This popup displays graph built with monitoring data.
16.1.3.4. GET /v2/ui/net/:id/popup/device/:devid/hwcomp/:idx¶
this call returns information used to build popup graph that opens when user clicks device label in maps. This call returns list of monitoring variables that have non-empty time series for the device identified by :devid and its hardware component with index :idx. If :idx < 0, then this call returns list of all variables with non-empty time series for all hardware components of the device.
16.1.3.5. GET /v2/ui/net/:id/popup/device/:devid/intf/:ifIndex¶
this call returns information used to build popup graph that opens when user clicks link label in maps. This popup displays graph built with monitoring data.
16.1.4. Map Views¶
16.1.4.1. GET /v2/ui/net/:id/views[?type=:view_type]¶
This call returns list of views owned by the current user (or all views if the server runs w/o user authentication). Views can be optionally limited to those of particular type. The view_type parameter is a string that can have one of the following values:
- SYSTEM
- SCRIPTED
- INTERACTIVE
the type should not be quoted.
Returned data has the following format:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | [ {
"id" : 3,
"name" : "backbone",
"devRule" : "",
"linkRule" : "",
"type" : "SCRIPTED",
"editable" : false,
"updatedAt" : 1490122101000,
"layoutUpdatedAt" : 1490585179000,
"formData": ""
}, {
"id" : 4,
"name" : "Datacenter A",
"devRule" : "",
"linkRule" : "",
"type" : "SCRIPTED",
"editable" : false,
"updatedAt" : 1490122101000,
"layoutUpdatedAt" : 1490585177000,
"formData": ""
} ]
|
16.1.4.2. GET /v2/ui/net/:id/views/:view_id¶
This call returns information about view identified by its id in the same format as previous call. Returned data is a list of one item:
1 2 3 4 5 6 7 8 9 10 11 | [ {
"id" : 17,
"name" : "new view 17",
"devRule" : "",
"linkRule" : "",
"type" : "INTERACTIVE",
"editable" : true,
"updatedAt" : 1490662954000,
"layoutUpdatedAt" : 1490662954000,
"formData": ""
} ]
|
16.1.4.3. POST /v2/ui/net/:id/views¶
Create new blank map view. The view is created with all default parameters so no information is expected in the request body or parameters. This call returns HTTP status OK if it was successful and new view id in the response body:
1 2 3 4 | {
"status": "ok",
"id": 1234
}
|
16.1.4.4. POST /v2/ui/net/:id/views/:view_id/update¶
Update the view. Information about it is passed via request body in the following format:
1 2 3 4 5 6 7 8 | {
"name": "view name",
"devRule": "NsgQL matching expression for devices",
"linkRule" : "NsgQL matching expression for interfaces",
"adjacent": "true|false",
"connecting": "true|false",
"formData": "some form data"
}
|
Since view Id is passed via URL path, it is not needed in the request body. However it is not an error if it is present there.
Attribute formData is an opaque text string passed from the UI. This can be json-encoded contents of the view editor form. Calls GET /v2/ui/net/:id/views/:view_id and GET /v2/ui/net/:id/views/ return this information as-is.
This call returns status 200 when operation was successful, or “Bad Request” error with body in case of error:
1 2 3 4 | {
"status" : "error",
"error": "error text"
}
|
16.1.4.5. DELETE /v2/ui/net/:id/views/:view_id¶
Delete the view identified by its id. No information in the request body is expected.
16.1.4.8. POST /v2/ui/net/:id/views/:view_id/validate¶
Validate the view. Information about it is passed via request body in the same format as the call POST /v2/ui/net/:id/views/:view_id/update.
This call returns status 200 when operation was successful, or “Bad Request” error with body in case of error:
1 2 3 4 | {
"status" : "error",
"error": "error text"
}
|
16.1.4.9. GET /v2/ui/net/:id/views/:view_id/map[?timestamp=:time]¶
returns information used to build network map in the UI for the view identified by its id and optional time in the past.
16.1.4.10. GET /v2/ui/net/:id/views/:view_id/map?layout=auto¶
runs automatic map layout algorithm and returns newly built map
16.1.4.11. GET /v2/ui/net/:id/views/:view_id/map?layout=reset¶
reset coordinates of all devices in this map, this makes devices “float”
16.1.4.12. GET /v2/ui/net/:id/views/:view_id/map?layout=fit¶
try to fit the map into browser window by scaling coordinates of all devices linearly
16.1.4.13. GET /v2/ui/net/:id/views/:view_id/preview[?devRule=NSGQL][&linkRule=NSGQL][&hide=true][&connecting=false|true][&adjacent=false|true]¶
this call attempts to rebuild network map for the view view_id using provided NsgQL expressions and flags connecting and adjacent. Parameters devRule and linkRule are NsgQL expressions (only the matching part, usually provided after the WHERE of an NsgQL query is required). Expression provided as a value of query parameter devRule matches devices and expression provided with parameter linkRule matches interfaces of the devices.
Devices and links in the data this call returns have attribute matching that has value true if corresponding device or link matches the filter. If parameter hide is provided and has value true then devices and links that do not match rules are hidden.
16.1.4.14. GET /v2/ui/net/:id/views/:view_id/linkGraphVars¶
returns list of variables defined in the configuration file with parameter deviceDetailsComponents.Interface
16.1.4.15. GET /v2/ui/net/:id/views/:view_id/linkVar/:lv/nodeVar/:nv[?timestamp=:time]¶
returns monitoring data for the map defined by view id for the link variable lv and device variable nv
16.1.4.16. PUT /v2/ui/net/:id/views/:view_id/coordinates¶
updates coordinates of one or several devices in the map defined by the view id. Input data is expected in the request body in JSON format:
1 2 3 4 | [
{ 'id': nodeId1, 'x': x1, 'y': y1 },
...
]
|
16.1.5. Server Health Checking¶
16.1.5.1. GET /v2/ping/net/:netid/[se]¶
This call can be used for server health checking (e.g. when deployed in HA configuration and behind a load balancer). This call is very lightweight and does not require user auth.
Normally, the servlet returns 200 and a single text string “ok” that indicates whether it is ready to serve. If the server runs without HA configuration, response “ok” indicates that it has completed startup process and is ready to serve. The server will respond with HTTP 200 but an empty body if it is in the process of starting up or is being shut down. If the server is a part of HA group, the group leader responds with “ok”, while other servers in the group respond with word “standby”.
When called with additional path component “/se”, i.e. “/v2/ping/net/:netid/se”, the server returns 503 when it is not ready to serve. This includes standalone server that is in the middle of startup or shut down sequence or a member of an HA group that is not a leader. This is intended for proxies that can put a server out of rotation only when it responds with “Service Unavailable (503)”
Note
The path must end with a “/” when option “se” is not used, for example /v2/ping/net/1/
16.1.6. Data Query¶
16.1.6.1. POST /v2/query/net/:id/data/¶
Returns information selected by the parameters of the query sent via request body in json format.
Data must be sent to this API call in NsgQL format ( NetSpyGlass Server Query Language ):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | {
"targets": [
{
"nsgql": "NsgQL SELECT query 1",
"format": "output format"
},
{
"nsgql": "NsgQL SELECT query 2",
"format": "output format"
}
],
"from": "now-30m",
"until": "now",
"groupByTime": "1m",
}
|
16.1.7. Graphs¶
NetSpyGlass UI and Grafana data plugin v2 use Data Query with format=time_series to build graphs.
16.1.8. View Filters¶
16.1.8.1. POST /v2/ui/net/:id/filters/[?user=:user_name]¶
Create new view filter using information passed via request body in JSON format:
1 2 3 4 5 | {
"name": "filter name",
"nsgql": "NsgQL mtching expression",
"formData": ""
}
|
The value of the attribute “formData” is an opaque serialized data block used to fill filter form in the UI. The backend does not interpret this information in any way and just returns it back to the UI in response to the call “GET /v2/ui/net/:id/filters”
Internally, filters are associated with user accounts. The server establishes this association using information about logged in user when it is available. Different users can have filters with the same name.
This call returns HTTP status OK and empty body when it is successful or server error (500) and the following json in case of errors:
1 2 3 | {
"error": "error text"
}
|
Note
Information about logged in user is taken from the authentication data of the API call. When the call is made using access token, then the name of the user is not available and should be passed via optional query parameter user. If parameter user is not supplied when the call is made with access token, then the filter is created in association with a pseudo-user with the name that matches the token.
16.1.8.2. GET /v2/ui/net/:id/filters/[?user=:user_name]¶
returns list of view filters associated with currently logged in user or user name passed via query parameter. Format:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | [
{
"id" : 66970,
"user" : userName,
"deleted" : false,
"createdAt" : 1489539475000,
"updatedAt" : 1489539475000,
"name" : "filter name",
"formData" : "serialized form data",
"nsgql" : "NsgQL expression",
"shared" : false,
},
...
]
|
16.1.8.3. DELETE /v2/ui/net/:id/filters/:filter_id¶
deletes view filter with given Id. Returns status 200 when operation was successful, or “Bad Request” error with body in case of error:
1 2 3 | {
"error": "error text"
}
|
16.1.9. Settings¶
GET /v2/ui/net/:id/settings
this call returns JSON dictionary that contains various server-side parameters defined in the configuration file and elsewhere.
16.1.10. Integrations¶
POST /v2/external/net/:id/kentik/:kentik_api_call
where kentik_api_call can be “url”, “topXdata”, “topXchart”.
the server takes external integration parameters from the configuration section integrations.kentik, makes an API call and returns the data back to the caller. Essentially, the server acts as a proxy, making a call to an external service.
16.1.11. Alerts and Alert silences JSON API¶
16.1.11.1. GET /v2/alerts/net/:netid/alerts[?active=true|false][rule_spec]¶
returns list of alerts that exist in the system, possible filtered in one of ways described below. Note that alert can be in the state “Active” or “Cleared” and this call considers both before applying the filter.
If you want to get only active alerts, supply parameter active=true:
GET /v2/alerts/net/:netid/alerts?active=true
If you want to get only cleared alerts, supply parameter active=false:
GET /v2/alerts/net/:netid/alerts?active=false
You can also apply filter defined by the matching rule that follows the same format used in other API calls, see section rule_spec. API call in the following example matches any alerts that have tags Explicit.alert_group_2 and Explicit.LOCATION_SJC:
GET /v2/alerts/net/:netid/alerts?tags=Explicit.alert_group_2,Explicit.LOCATION_SJC&tagMatch=AND
You can combine parameter active=true with rule match:
GET /v2/alerts/net/:netid/alerts?active=true&tags=Explicit.alert_group_2,Explicit.LOCATION_SJC&tagMatch=AND
This call returns list of dictionaries where each dictionary describes one alert. At this time it looks like this:
{
"key" : "a1b779e08514b5e7e76fb58fa2b2a294",
"name" : "busyCpuAlert",
"deviceName" : "rdac3",
"deviceId" : 131,
"componentName" : "GenuineIntel: Intel(R) Core(TM)2 Duo CPU E7500 @ 2.93GHz",
"componentIndex" : 4294968065,
"value" : "80.0",
"values" : {
"cpuUtil.131.4294968065" : "80.0"
},
"description" : "CPU utilization is over 75% for 20% of time for the last 10 min",
"tags" : [ "Explicit.datanodes_hbase0", "Explicit.hbase0", "Model.linux", "Role.Server", "Role.datanodes_hbase0", "Role.hbase0", "Vendor.NetSnmp" ],
"variable" : "busyCpuAlert.131.4294968065",
"inputVariable" : "cpuUtil.131.4294968065",
"activeSince" : 1433965140000,
"active" : true,
"silenced" : true,
"matchingSilenceId" : 20,
"timeLastNotificationSent" : 0,
"duration" : 600.0,
"percentage" : 20.0,
"notificationTimeMs" : 300000.0
}
key : unique identifier of this alert; this key can be used for deduplication
name : the name of the alert defined in the call to Python function
nw2functions.alert()
deviceName: name of the device
deviceId: id of the device
componentName: name of the component
componentIndex: index of the component
- value : the latest value of the input monitoring variable that triggered the alert. Note that
if the alert configuration uses parameter percentage, the alert is actually triggered by combination of several values in the time series of the input variable rather than this one latest value
- description : alert description taken from the parameter of the call to
nw2functions.alert()
with all macros expanded
- description : alert description taken from the parameter of the call to
tags : tags of this alert. Tags are copied from the input monitoring variable
variable : the triplet for the monitoring variable created for this alert.
inputVariable : the triplet for the input monitoring variable used to create this alert
activeSince : time stamp (in ms) when this alert entered state “active” last time if it is currently active
active : true if alert is active, false otherwise
silenced : true if there is silence that matches this alert, otherwise false
matchingSilenceId : the id of the matching silence. If there is no matching silence, this is equal to 0
timeLastNotificationSent : time (in ms) when we sent notification for this alert last time
- duration : configuration parameter taken from the call to
nw2functions.alert()
that created this alert
- duration : configuration parameter taken from the call to
- percentage : configuration parameter taken from the call to
nw2functions.alert()
that created this alert
- percentage : configuration parameter taken from the call to
- notificationTimeMs : configuration parameter taken from the call to
nw2functions.alert()
that created this alert
- notificationTimeMs : configuration parameter taken from the call to
16.1.11.2. GET /v2/alerts/net/:netid/alerts/:alertKey¶
Returns alert with given key if it exists.
Note
Unlike with other objects, such as networks, devices, vilews, maps and even alert silences (see blow), which use numbers for their Ids, alert key is a string of random characters
16.1.11.3. POST /v2/alerts/net/:netid/silences¶
Add new silence to the system. Takes data from the body of the POST call and creates new alert silcnce. The data should follow this format:
{
"expirationTimeMs": 3600000,
"match" : {
"key": "alertkey",
"varNme": "varName",
"deviceId": deviceId,
"deviceName": "deviceName",
"index": index,
"tags": "Role.Router, !Explicit.test"
}
}
Expiration time interval is in milliseconds. All items in the match directory are optional, you are only required to provide attributes you actually want to use to match alerts.
Note
Even though an empty match is permitted, the silence created with empty match rule never matches any alerts and is useless.
This call returns small JSON dictionary:
{
"id": 1000,
"status": "success",
"message": ""
}
- `id`: id of newly created silence
- `status`: can be "success" or "error"
- `message`: verbose error message returned when `status` has value `error`
16.1.11.4. POST /v2/alerts/net/:netid/silences/:id¶
Updates existing silence with id id. Takes data from the body of the POST call and creates new alert silcnce. The data should follow this format (the same as with the call that creates the silence):
{
"expirationTimeMs": 3600000,
"user": "vadim",
"reason": "doing maitenance for the next hour",
"match" : {
"key": "alertKey",
"varName": "varName",
"deviceId": deviceId,
"deviceName": deviceName,
"index": index,
"tags": "Role.Router, !Explicit.test"
}
}
This call returns small JSON dictionary with the same items as the call that creates new silence:
{
"id": 1000,
"status": "success",
"message": ""
}
- `id`: id of newly created silence
- `status`: can be "success" or "error"
- `message`: verbose error message returned when `status` has value `error`
16.1.11.5. GET /v2/alerts/net/:netid/silences/¶
returns all active silences in JSON format:
[
{
"id": 1000,
"createdAt": 1418269740000,
"updatedAt": 1418269740000,
"expirationTimeMs": 3600000,
"user": "vadim",
"reason": "doing maitenance for the next hour",
"match" : {
"key": "",
"varName": "cpuBusy",
"deviceId": 9,
"deviceName": "router1.sj",
"index": 11,
"tags": "Role.Router, !Explicit.test"
}
},
]
note that this only returns list of active silences, that is, those that have not expired yet. All time values (createdAt, updatedAt and expirationTimeMs) are in milliseconds.
16.1.11.6. GET /v2/alerts/net/:netid/silences/:id¶
returns silence with id :id in JSON format:
[
{
"id": 1000,
"createdAt": 1418269740000,
"updatedAt": 1418269740000,
"expirationTimeMs": 3600000,
"user": "vadim",
"reason": "doing maitenance for the next hour",
"match" : {
"key": "",
"varName": "cpuBusy",
"deviceId": 9,
"deviceName": "",
"index": 0,
"tags": "Role.Router, !Explicit.test"
}
},
]
note that this only returns silence if it is active, that is, it has not expired yet. All time values (createdAt, updatedAt and expirationTimeMs) are in milliseconds.
Matching attributes have default names if they were omitted when silence has been created. These values are:
- key, varName, deviceName, tags: if these attributes are empty string, they are ignored and do not match anything
- deviceId, index: if these attributes have value 0, they are ignored