-
Inventory Provider
- Overview
- Configuration
- Running this module
-
Protocol Specification
- /data/version
- /data/routers
- /data/interfaces
- /data/pop
- /jobs/update
- /jobs/log
- /jobs/reload-router-config
- /jobs/check-task-status
- /classifier/juniper-link-info
- /classifier/peer-info
- /classifier/infinera-lambda-info
- /classifier/coriant-info
- /poller/interfaces
- /lg/routers
- /msr/access-services
- /testing/flushdb
- /testing/infinera-dna-addresses
- /testing/coriant-tnms-addresses
- /testing/juniper-server-addresses
- /data/snmp
- /data/bgp
- Backend (Redis) Storage Schema
Inventory Provider
Overview
This module implements a Flask-based webservice which provides some access to GÉANT network router inventory information.
The webservice is communicates with clients over HTTP.
Responses to valid requests are returned as JSON messages.
The server will therefore return an error unless
application/json
is in the Accept
request header field.
HTTP communication and JSON grammar details are beyond the scope of this document. Please refer to RFC 2616 and www.json.org for more details.
Configuration
Several configuration files must be provided when launching the web service.
The runtime-accessible filename of the first configuration file
must be stored in the environment variable
SETTINGS_FILENAME
.
The configuration file is python and defines a single variable. The following is an example:
INVENTORY_PROVIDER_CONFIG_FILENAME = "/somepath/config.json"
ENABLE_TESTING_ROUTES = True
-
INVENTORY_PROVIDER_CONFIG_FILENAME
: [REQUIRED] Run-time accessible filename of a json file containing the server configuration parameters. This file must be formatted according to the following json schema:{ "$schema": "http://json-schema.org/draft-07/schema#", "definitions": { "timeout": { "type": "number", "maximum": 10, # sanity "exclusiveMinimum": 0 }, "database-credentials": { "type": "object", "properties": { "hostname": {"type": "string"}, "dbname": {"type": "string"}, "username": {"type": "string"}, "password": {"type": "string"} }, "required": ["hostname", "dbname", "username", "password"], "additionalProperties": False }, "ssh-credentials": { "type": "object", "properties": { "username": {"type": "string"}, "private-key": {"type": "string"}, "known-hosts": {"type": "string"} }, "required": ["private-key", "known-hosts"], "additionalProperties": False }, "redis-credentials": { "type": "object", "properties": { "hostname": {"type": "string"}, "port": {"type": "integer"}, "socket_timeout": {"$ref": "#/definitions/timeout"} }, "required": ["hostname", "port"], "additionalProperties": False }, "redis-sentinel-config": { "type": "object", "properties": { "hostname": {"type": "string"}, "port": {"type": "integer"}, "name": {"type": "string"}, "redis_socket_timeout": {"$ref": "#/definitions/timeout"}, "sentinel_socket_timeout": {"$ref": "#/definitions/timeout"} }, "required": ["hostname", "port", "name"], "additionalProperties": False }, "interface-address": { "type": "object", "properties": { "address": {"type": "string"}, "network": {"type": "string"}, "interface": {"type": "string"}, "router": {"type": "string"} }, "required": ["address", "network", "interface", "router"], "additionalProperties": False } }, "type": "object", "properties": { "ops-db": {"$ref": "#/definitions/database-credentials"}, "ssh": {"$ref": "#/definitions/ssh-credentials"}, "redis": {"$ref": "#/definitions/redis-credentials"}, "sentinel": {"$ref": "#/definitions/redis-sentinel-config"}, "redis-databases": { "type": "array", "minItems": 1, "items": {"type": "integer"} }, "managed-routers": {"type": "string"}, "unmanaged-interfaces": { "type": "array", "items": {"$ref": "#/definitions/interface-address"} } }, "oneOf": [ { "required": [ "ops-db", "ssh", "redis", "redis-databases", "managed-routers"] }, { "required": [ "ops-db", "ssh", "sentinel", "redis-databases", "managed-routers"] } ], "additionalProperties": False }
-
ENABLE_TESTING_ROUTES
: [OPTIONAL (default value: False)] Flat (can be any value that evaluates to True) to enable routes to special utilities used for testing. This must never be enabled in a production environment.
Running this module
This module has been tested in the following execution environments:
- As an embedded Flask application. For example, the application could be launched as follows:
$ export FLASK_APP=app.py
$ export SETTINGS_FILENAME=settings.cfg
$ flask run
-
As an Apache/
mod_wsgi
service.- Details of Apache and
mod_wsgi
configuration are beyond the scope of this document.
- Details of Apache and
-
As a
gunicorn
wsgi service.- Details of
gunicorn
configuration are beyond the scope of this document.
- Details of
Protocol Specification
The following resources can be requested from the webservice.
resources
Any non-empty responses are JSON formatted messages.
/data/version
- /data/version
The response will be an object containing the module and protocol versions of the running server and will be formatted as follows:
{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"properties": {
"api": {
"type": "string",
"pattern": r'\d+\.\d+'
},
"module": {
"type": "string",
"pattern": r'\d+\.\d+'
}
},
"required": ["api", "module"],
"additionalProperties": False
}
/data/routers
- /data/routers
The response will be a list of router hostnames for which information is available and will be formatted as follows:
{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "array",
"items": {"type": "string"}
}
/data/interfaces
- /data/interfaces</
hostname
>
The response will be a list of information about the interfaces present on the requested host and will be formatted as follows:
```json
{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "array",
"items": {
"type": "object",
"properties": {
"name": {"type": "string"},
"router": {"type": "string"},
"description": {"type": "string"},
"ipv4": {
"type": "array",
"items": {"type": "string"}
},
"ipv6": {
"type": "array",
"items": {"type": "string"}
}
},
"required": ["name", "description", "router", "ipv4", "ipv6"],
"additionalProperties": False
}
}
```
/data/pop
- /data/pop/
name
Returns location information for the equipment identified
by name
.
The response will be formatted as follows:
```json
{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"definitions": {
"pop-info": {
"type": "object",
"properties": {
"name": {"type": "string"},
"abbreviation": {"type": "string"},
"country": {"type": "string"},
"city": {"type": "string"},
"longitude": {"type": "number"},
"latitude": {"type": "number"}
},
"required": [
"name",
"abbreviation",
"country",
"city",
"longitude",
"latitude"
],
"additionalProperties": False
},
"equipment-info": {
"type": "object",
"properties": {
'equipment-name': {"type": "string"},
'status': {"type": "string"},
'pop': {"$ref": "#/definitions/pop-info"}
},
"required": [
"equipment-name",
"status",
"pop"
],
"additionalProperties": False
}
},
"type": "array",
"items": {"$ref": "#/definitions/equipment-info"}
}
```
/jobs/update
- /jobs/update
This resource updates the inventory network data for juniper devices.
The function completes asynchronously and a list of outstanding
task id's is returned so the caller can
use /jobs/check-task-status
to determine when all jobs
are finished. The response will be formatted as follows:
{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "array",
"items": {"type": "string"}
}
/jobs/log
- /jobs/log
This resource returns the state of the previous (or current)
tasks associated with a call to /jobs/update
. The response
contains error or warning messages, if any were generated.
{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"properties": {
"pending": {"type": "array", "items": {"type": "string"}},
"errors": {"type": "array", "items": {"type": "string"}},
"failed": {"type": "array", "items": {"type": "string"}},
"warnings": {"type": "array", "items": {"type": "string"}},
},
"required": ["pending", "errors", "failed", "warnings"],
"additionalProperties": False
}
/jobs/reload-router-config
- /jobs/reload-router-config/
equipment-name
This resource updates the inventory network data for
the identified juniper device. This function completes
asynchronously and returns the same value as
/jobs/update
, except the return contains exactly
one task id.
/jobs/check-task-status
- /jobs/check-task-status/
task-id
This resource returns the current status of
an asynchronous task started by /jobs/update
or jobs/reload-router-config
. The return value
will be formatted as follows:
{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"properties": {
"id": {"type": "string"},
"status": {"type": "string"},
"exception": {"type": "boolean"},
"ready": {"type": "boolean"},
"success": {"type": "boolean"},
"result": {"type": "object"}
},
"required": ["id", "status", "exception", "ready", "success"],
"additionalProperties": False
}
/classifier/juniper-link-info
- /classifier/juniper-link-info/
source-equipment
/source-interface
The source-equipment is the equipment that causes the trap, not the NMS that sends it.
The response will be an object containing the metadata, formatted according to the following schema:
```json
{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"definitions": {
"location-endpoint": {
"type": "object",
"properties": {
"equipment": {"type": "string"},
"name": {"type": "string"},
"abbreviation": {"type": "string"}
},
"required": ["equipment", "name", "abbreviation"],
"additionalProperties": False
},
"location": {
"type": "object",
"properties": {
"a": {"$ref": "#/definitions/location-endpoint"},
"b": {"$ref": "#/definitions/location-endpoint"}
},
"required": ["a"],
"additionalProperties": False
},
"locations-list": {
"type": "array",
"items": {"$ref": "#/definitions/location"}
},
"ip-address": {
"type": "string",
"oneOf": [
{"pattern": r'^(\d+\.){3}\d+$'},
{"pattern": r'^([a-f\d]{4}:){7}[a-f\d]{4}$'}
]
},
"ipv4-interface-address": {
"type": "string",
"pattern": r'^(\d+\.){3}\d+/\d+$'
},
"ipv6-interface-address": {
"type": "string",
"pattern": r'^[a-f\d:]+/\d+$'
},
"snmp-info": {
"type": "object",
"properties": {
"community": {"type": "string"},
"index": {"type": "integer"}
},
"required": ["community", "index"],
"additionalProperties": False
},
"interface-info": {
"type": "object",
"properties": {
"name": {"type": "string"},
"description": {"type": "string"},
"ipv4": {
"type": "array",
"items": {"$ref": "#/definitions/ipv4-interface-address"}
},
"ipv6": {
"type": "array",
"items": {"$ref": "#/definitions/ipv6-interface-address"}
},
"bundle": {"type": "array"},
"bundle_members": {"type": "array"},
"snmp": {"$ref": "#/definitions/snmp-info"}
},
"required": ["name", "description", "ipv4", "ipv6"],
"additionalProperties": False
},
"service-info": {
"type": "object",
"properties": {
"name": {"type": "string"},
"status": {
"type": "string",
"enum": ["operational", "installed", "planned", "ordered"]
},
"circuit_type": {
"type": "string",
"enum": ["path", "service", "l2circuit"]
},
"project": {"type": "string"}
"equipment": {"type": "string"},
"pop": {"type": "string"},
"pop_abbreviation": {"type": "string"},
"other_end_pop": {"type": "string"},
"other_end_pop_abbreviation": {"type": "string"},
"other_end_equipment": {"type": "string"},
"port": {"type": "string"},
"other_end_port": {"type": "string"},
"logical_unit": {
"oneOf": [
{"type": "integer"},
{"type": "string", "maxLength": 0}
]
},
"other_end_logical_unit": {
"oneOf": [
{"type": "integer"},
{"type": "string", "maxLength": 0}
]
},
"manufacturer": {
"type": "string",
"enum": ["juniper", "coriant", "infinera",
"cisco", "hewlett packard",
"corsa", "graham smith uk ltd",
"unknown", ""]
},
"card_id": {"type": "string"},
"other_end_card_id": {"type": "string"},
"interface_name": {"type": "string"},
"other_end_interface_name": {"type": "string"},
'other_end_pop_name': {"type": "string"},
'pop_name': {"type": "string"}
},
"additionalProperties": False
},
"related-service-info": {
"type": "object",
"properties": {
"name": {"type": "string"},
"status": {
"type": "string",
"enum": ["operational", "installed", "planned", "ordered"]
},
"circuit_type": {
"type": "string",
"enum": ["path", "service", "l2circuit"]
},
"project": {"type": "string"}
},
"required": ["name", "status", "circuit_type", "project"],
"additionalProperties": False
}
},
"type": "object",
"properties": {
"services": {
"type": "array",
"items": {"$ref": "#/definitions/service-info"}
},
"interface": {"$ref": "#/definitions/interface-info"},
"related-services": {
"type": "array",
"items": {"$ref": "#/definitions/related-service-info"}
},
"locations": {"$ref": "#/definitions/locations-list"}
},
# "required": ["interface"],
"additionalProperties": False
}
```
- `locations`: info about the `a` (and `b`, if relevant)
ends of the circuit
- `services`: info about the service served by this interface
- `interface`: relevant interface parameters
- `related-services`: all top-level services depending on this interface
/classifier/peer-info
- /classifier/peer-info/
address
The address
parameter should be the ip address of
a remote peer. If this address is found in the system
then information about the interface is returned, otherwise
404 is returned (or 422 if the address can't be parsed)
The response will be formatted according to the following syntax:
```json
{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"definitions": {
"location-endpoint": {
"type": "object",
"properties": {
"equipment": {"type": "string"},
"name": {"type": "string"},
"abbreviation": {"type": "string"}
},
"required": ["equipment", "name", "abbreviation"],
"additionalProperties": False
},
"location": {
"type": "object",
"properties": {
"a": {"$ref": "#/definitions/location-endpoint"},
"b": {"$ref": "#/definitions/location-endpoint"}
},
"required": ["a"],
"additionalProperties": False
},
"locations-list": {
"type": "array",
"items": {"$ref": "#/definitions/location"}
},
"ip-address": {
"type": "string",
"oneOf": [
{"pattern": r'^(\d+\.){3}\d+$'},
{"pattern": r'^([a-f\d]{4}:){7}[a-f\d]{4}$'}
]
},
"interface-address": {
"type": "string",
"oneOf": [
{"pattern": r'^(\d+\.){3}\d+/\d+$'},
{"pattern": r'^[a-f\d:]+/\d+$'}
]
},
"vpn-rr-peer": {
"type": "object",
"properties": {
"name": {"$ref": "#/definitions/ip-address"},
"description": {"type": "string"},
"peer-as": {"type": "integer"},
"router": {"type": "string"}
},
"required": ["name", "description"],
"additionalProperties": False
},
"ix-public-peer": {
"type": "object",
"properties": {
"name": {"$ref": "#/definitions/ip-address"},
"description": {"type": "string"},
"router": {"type": "string"},
"as": {
"type": "object",
"properties": {
"local": {"type": "integer"},
"peer": {"type": "integer"},
},
"required": ["local", "peer"],
"additionalProperties": False
}
},
"required": ["name", "description", "as"],
"additionalProperties": False
},
"ix-public-peer-list": {
"type": "array",
"items": {"$ref": "#/definitions/ip-address"}
},
"ix-public-peer-info": {
"type": "object",
"properties": {
"peer": {"$ref": "#/definitions/ix-public-peer"},
"group": {"$ref": "#/definitions/ix-public-peer-list"},
"router": {"$ref": "#/definitions/ix-public-peer-list"}
},
"required": ["peer", "group", "router"],
"additionalProperties": False
},
"interface-info": {
"type": "object",
"properties": {
"name": {"$ref": "#/definitions/ip-address"},
"interface address": {
"$ref": "#/definitions/interface-address"},
"interface name": {"type": "string"},
"router": {"type": "string"}
},
"required": [
"name", "interface address", "interface name", "router"],
"additionalProperties": False
},
"service-info": {
"type": "object"
},
"interface-lookup-info": {
"type": "object",
"properties": {
"interface": {"$ref": "#/definitions/interface-info"},
"services": {
"type": "array",
"items": {"$ref": "#/definitions/service-info"}
}
}
}
},
"type": "object",
"properties": {
"ix-public-peer-info": {
"$ref": "#/definitions/ix-public-peer-info"},
"vpn-rr-peer-info": {"$ref": "#/definitions/vpn-rr-peer"},
"interfaces": {
"type": "array",
"items": {"$ref": "#/definitions/interface-lookup-info"}
},
"locations": {"$ref": "#/definitions/locations-list"}
},
"additionalProperties": False
}
```
- `locations`: info about the `a` (and `b`, if relevant)
ends of the circuit
- `interfaces`: interfaces involved on either end and service info
- `vpn-rr-peer-info`: peering info
- `ix-public-peer-info`: peering info
/classifier/infinera-lambda-info
- /classifier/infinera-lambda-info/
source-equipment
/source-interface
The source-equipment is the equipment that causes the trap, not the NMS that sends it.
The response will be an object containing the metadata, formatted according to the following schema:
```json
{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"definitions": {
"location-endpoint": {
"type": "object",
"properties": {
"equipment": {"type": "string"},
"name": {"type": "string"},
"abbreviation": {"type": "string"}
},
"required": ["equipment", "name", "abbreviation"],
"additionalProperties": False
},
"location": {
"type": "object",
"properties": {
"a": {"$ref": "#/definitions/location-endpoint"},
"b": {"$ref": "#/definitions/location-endpoint"}
},
"required": ["a"],
"additionalProperties": False
},
"locations-list": {
"type": "array",
"items": {"$ref": "#/definitions/location"}
},
"service-info": {
"type": "object",
"properties": {
"id": {"type": "integer"},
"name": {"type": "string"},
"status": {
"type": "string",
"enum": ["operational", "installed", "planned", "ordered"]
},
"circuit_type": {
"type": "string",
"enum": ["path", "service", "l2circuit"]
},
"service_type": {"type": "string"},
"project": {"type": "string"},
"pop_name": {"type": "string"},
"pop_abbreviation": {"type": "string"},
"other_end_pop_name": {"type": "string"},
"other_end_pop_abbreviation": {"type": "string"},
"equipment": {"type": "string"},
"other_end_equipment": {"type": "string"},
"port": {"type": "string"},
"other_end_port": {"type": "string"},
"logical_unit": {
"oneOf": [
{"type": "integer"},
{"type": "string", "maxLength": 0}
]
},
"other_end_logical_unit": {
"oneOf": [
{"type": "integer"},
{"type": "string", "maxLength": 0}
]
},
"manufacturer": {
"type": "string",
"enum": ["juniper", "coriant", "infinera",
"cisco", "hewlett packard",
"corsa", "graham smith uk ltd",
"unknown", ""]
},
"card_id": {"type": "string"},
"other_end_card_id": {"type": "string"},
"interface_name": {"type": "string"},
"other_end_interface_name": {"type": "string"}
},
"additionalProperties": False
},
"related-service-info": {
"type": "object",
"properties": {
"name": {"type": "string"},
"status": {
"type": "string",
"enum": ["operational", "installed", "planned", "ordered"]
},
"circuit_type": {
"type": "string",
"enum": ["path", "service", "l2circuit"]
},
"project": {"type": "string"}
},
"required": ["name", "status", "circuit_type", "project"],
"additionalProperties": False
},
"geant-lambda": {
"type": "object",
"properties": {
"id": {"type": "integer"},
"name": {"type": "string"},
"project": {"type": "string"},
"status": {
"type": "string",
"enum": ["operational", "installed", "planned", "ordered"]
},
},
"additionalProperties": False
}
},
"type": "object",
"properties": {
"services": {
"type": "array",
"items": {"$ref": "#/definitions/service-info"}
},
"related-services": {
"type": "array",
"items": {"$ref": "#/definitions/related-service-info"}
},
"geant-lambda": {
"$ref": "#/definitions/geant-lambda"
},
"locations": {"$ref": "#/definitions/locations-list"}
},
"additionalProperties": False
}
```
- `locations`: info about the `a` (and `b`, if relevant)
ends of the circuit
- `services`: info about any services that use this port
- `related-services`: any top-level services depending on this circuit
- `geant-lambda`: info about the lambda service using this port
/classifier/coriant-info
- /classifier/coriant-info/
equipment name
/entity name
Returns information about the effective path of a coriant card/port combination.
The response will be formatted according to the following schema:
```json
{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"definitions": {
"location-endpoint": {
"type": "object",
"properties": {
"equipment": {"type": "string"},
"name": {"type": "string"},
"abbreviation": {"type": "string"}
},
"required": ["equipment", "name", "abbreviation"],
"additionalProperties": False
},
"location": {
"type": "object",
"properties": {
"a": {"$ref": "#/definitions/location-endpoint"},
"b": {"$ref": "#/definitions/location-endpoint"}
},
"required": ["a"],
"additionalProperties": False
},
"locations-list": {
"type": "array",
"items": {"$ref": "#/definitions/location"}
},
"pop-info": {
"type": "object",
"properties": {
"name": {"type": "string"},
"abbreviation": {"type": "string"},
"country": {"type": "string"},
"city": {"type": "string"},
"longitude": {"type": "number"},
"latitude": {"type": "number"}
},
"required": [
"name",
"abbreviation",
"country",
"city",
"longitude",
"latitude"
],
"additionalProperties": False
},
"endpoint": {
"type": "object",
"properties": {
"equipment name": {"type": "string"},
"card id": {"type": "string"},
"port number": {"type": "string"},
"pop": {"$ref": "#/definitions/pop-info"}
},
"required": ["equipment name", "port number", "pop"],
"additionalProperties": False
},
"path": {
"type": "object",
"properties": {
'category': {"type": "string"},
'circuit_type': {"type": "string"},
'service_type': {"type": "string"},
'peering_type': {"type": "string"},
'status': {"type": "string"},
'name': {"type": "string"},
'a': {"$ref": "#/definitions/endpoint"},
'b': {"$ref": "#/definitions/endpoint"}
},
"required": [
"category",
"circuit_type",
"service_type",
"peering_type",
"status",
"a",
"b"],
"additionalProperties": False
},
"related-service-info": {
"type": "object",
"properties": {
"name": {"type": "string"},
"status": {
"type": "string",
"enum": ["operational", "installed", "planned", "ordered"]
},
"circuit_type": {
"type": "string",
"enum": ["path", "service", "l2circuit"]
},
"project": {"type": "string"}
},
"additionalProperties": False
}
},
"type": "object",
"properties": {
"equipment name": {"type": "string"},
"card id": {"type": "string"},
"port number": {"type": "string"},
"path": {"$ref": "#/definitions/path"},
"related-services": {
"type": "array",
"items": {"$ref": "#/definitions/related-service-info"}
},
},
"required": ["equipment name", "card id", "port number"],
"additionalProperties": False
}
```
- `locations`: info about the `a` and `b` ends of the circuit
- `path`: detailed path info (included `a` and `b` ends)
- `related-services`: any top-level services depending on this circuit
/poller/interfaces
- /poller/interfaces</
hostname
>
The response will be the list of active interfaces on the
router hostname
.
Each element of the returned list contains information necessary
for setting up snmp throughput counter polling.
The response will be formatted according to the following schema:
```json
{
"$schema": "http://json-schema.org/draft-07/schema#",
"definitions": {
"service": {
"type": "object",
"properties": {
"id": {"type": "integer"},
"name": {"type": "string"},
"type": {"type": "string"},
"status": {"type": "string"},
},
"required": ["id", "name", "type", "status"],
"additionalProperties": False
},
"interface": {
"type": "object",
"properties": {
"router": {"type": "string"},
"name": {"type": "string"},
"description": {"type": "string"},
"snmp-index": {
"type": "integer",
"minimum": 1
},
"bundle": {
"type": "array",
"items": {"type": "string"}
},
"bundle-parents": {
"type": "array",
"items": {"type": "string"}
},
"circuits": {
"type": "array",
"items": {"$ref": "#/definitions/service"}
}
},
"required": [
"router", "name", "description",
"snmp-index", "bundle", "bundle-parents",
"circuits"],
"additionalProperties": False
},
},
"type": "array",
"items": {"$ref": "#/definitions/interface"}
}
```
/lg/routers
- /lg/routers/
access