From 662c18a062868b532984f5daf559f8e3d75804b7 Mon Sep 17 00:00:00 2001
From: Erik Reid <erik.reid@geant.org>
Date: Sun, 24 Jan 2021 20:58:07 +0100
Subject: [PATCH] added lg, data, poller routes to docs

move schemas from test to sources
---
 README.md                             | 1640 +------------------------
 docs/source/protocol/classifier.rst   |    2 +
 docs/source/protocol/data.rst         |   22 +
 docs/source/protocol/index.rst        |    7 +-
 docs/source/protocol/jobs.rst         |   24 +
 docs/source/protocol/lg.rst           |   12 +
 docs/source/protocol/poller.rst       |   12 +
 inventory_provider/routes/data.py     |  110 ++
 inventory_provider/routes/jobs.py     |  101 ++
 inventory_provider/routes/lg.py       |   62 +
 inventory_provider/routes/poller.py   |   68 +-
 test/per_router/test_poller_routes.py |   51 +-
 test/test_general_poller_routes.py    |   52 +-
 test/test_job_routes.py               |   60 +-
 test/test_lg_routes.py                |   47 +-
 15 files changed, 438 insertions(+), 1832 deletions(-)
 create mode 100644 docs/source/protocol/data.rst
 create mode 100644 docs/source/protocol/jobs.rst
 create mode 100644 docs/source/protocol/lg.rst
 create mode 100644 docs/source/protocol/poller.rst

diff --git a/README.md b/README.md
index b993b2c7..9157e3ed 100644
--- a/README.md
+++ b/README.md
@@ -1,209 +1,31 @@
+# Inventory Provider
+
+The Inventory Provider
+acts as a single point of truth for
+information about the GÉANT network, exposed by
+by an HTTP API.
+
+Sphinx documentation is generated in `/docs`.
+
 
 * [Inventory Provider](#inventory-provider)
-  * [Overview](#overview)
-  * [Configuration](#configuration)
-  * [Running this module](#running-this-module)
   * [Protocol Specification](#protocol-specification)
-    * [/data/version](#dataversion)
-    * [/data/routers](#datarouters)
-    * [/data/interfaces](#datainterfaces)
-    * [/data/pop](#datapop)
+
     * [/jobs/update](#jobsupdate)
     * [/jobs/log](#jobslog)
     * [/jobs/reload-router-config](#jobsreload-router-config)
     * [/jobs/check-task-status](#jobscheck-task-status)
-    * [/classifier/juniper-link-info](#classifierjuniper-link-info)
-    * [/classifier/peer-info](#classifierpeer-info)
-    * [/classifier/infinera-lambda-info](#classifierinfinera-lambda-info)
-    * [/classifier/coriant-info](#classifiercoriant-info)
-    * [/poller/interfaces](#pollerinterfaces)
-    * [/lg/routers](#lgrouters)
     * [/msr/access-services](#msraccess-services)
     * [/testing/flushdb](#testingflushdb)
     * [/testing/infinera-dna-addresses](#testinginfinera-dna-addresses)
     * [/testing/coriant-tnms-addresses](#testingcoriant-tnms-addresses)
     * [/testing/juniper-server-addresses](#testingjuniper-server-addresses)
-    * [/data/snmp](#datasnmp)
-    * [/data/bgp](#databgp)
-  * [Backend (Redis) Storage Schema](#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](https://tools.ietf.org/html/rfc2616)
-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:
-
-```python
-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:
-
-    ```json
-    {
-        "$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:
-
-```bash
-$ 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.
-
-- As a `gunicorn` wsgi service.
-  - Details of `gunicorn` configuration are
-    beyond the scope of this document.
-
-
 ## Protocol Specification
 
 The following resources can be requested from the webservice.
@@ -212,1018 +34,6 @@ The following resources can be requested from the webservice.
 
 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:
-
-  ```json
-  {
-        "$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:
-
-  ```json
-  {
-      "$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:
-
-  ```json
-  {
-    "$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.
-
-  ```json
-  {
-    "$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:
-
-  ```json
-  {
-    "$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"}
-                    }
-                }
-            },
-            "snmp-info": {
-                "type": "object",
-                "properties": {
-                    "hostname": {"type": "string"},
-                    "oid": {"type": "string"},
-                    "community": {"type": "string"}
-                },
-                "required": ["oid", "community", "hostname"],
-                "additionalProperties": False
-            },
-            "asn-group-member": {
-                "type": "object",
-                "properties": {
-                    "router": {"type": "string"},
-                    "address": {"type": "string"},
-                    "group": {"type": "string"}
-                },
-                "required": ["router", "address", "group"],
-                "additionalProperties": False
-            },
-            "asn-group": {
-                "type": "object",
-                "properties": {
-                    "asn": {"type": "integer"},
-                    "peers": {
-                        "type": "array",
-                        "items": {"$ref": "#/definitions/asn-group-member"}
-                    }
-                },
-                "required": ["asn", "peers"],
-                "additionalProperties": False
-            }
-
-        },
-
-        "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"},
-            "snmp": {
-                "type": "array",
-                "items": {"$ref": "#/definitions/snmp-info"}
-            },
-            "asn": {"$ref": "#/definitions/asn-group"}
-        },
-        "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`*
-
-  The response will be the list of routers with pop location information.
-  The list will be filtered according to the value of the `access` parameter.
-
-  There are 2 valid values for `access`, these are: `public`, `all`
-
-  The response will be formatted according to the following schema:
-
-    ```json
-    {
-        "$schema": "http://json-schema.org/draft-07/schema#",
-
-        "definitions": {
-            "pop-info": {
-                "type": "object",
-                "properties": {
-                    "name": {"type": "string"},
-                    "abbreviation": {"type": "string"},
-                    "country": {"type": "string"},
-                    "country code": {"type": "string"},
-                    "city": {"type": "string"},
-                    "longitude": {"type": "number"},
-                    "latitude": {"type": "number"}
-                },
-                "required": [
-                    "name",
-                    "abbreviation",
-                    "country",
-                    "country code",
-                    "city",
-                    "longitude",
-                    "latitude"
-                ],
-                "additionalProperties": False
-            },
-            "router": {
-                "type": "object",
-                "properties": {
-                    "equipment name": {"type": "string"},
-                    "type": {
-                        "type": "string",
-                        "enum": ["INTERNAL", "CORE"]
-                    },
-                    "pop": {"$ref": "#/definitions/pop-info"}
-                },
-                "required": ["equipment name", "type", "pop"],
-                "additionalProperties": False
-            }
-        },
-
-        "type": "array",
-        "items": {"$ref": "#/definitions/router"}
-    }
-    ```
-
-
-#### /msr/access-services
-
-  * /msr/access-services
-
-  The response will be the list of services that
-  are of type 'IP Acccess', and will 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"},
-                    "equipment": {"type": "string"},
-                    "pop_name": {"type": "string"},
-                    "other_end_equipment": {"type": "string"},
-                    "other_end_pop_name": {"type": "string"},
-                    "speed_value": {"type": "integer"},
-                    "speed_unit": {"type": "string"}
-                },
-                "required": [
-                    "id", "name",
-                    "pop_name", "equipment",
-                    "other_end_pop_name", "other_end_equipment",
-                    "speed_value", "speed_unit"
-                ],
-                "additionalProperties": False
-            }
-        },
-
-        "type": "array",
-        "items": {"$ref": "#/definitions/service"}
-    }
-    ```
-
 ### Testing utilities
 
 The following routes are only available if the server
@@ -1253,436 +63,8 @@ are intended to be deleted.
 
     ```json
     {
-        "$schema": "http://json-schema.org/draft-07/schema#",
+        "$schema": "http://json-schema.org/raft-07/schema#",
         "type": "array",
         "items": {"type": "string"}
     }
     ```
-
-
-#### /data/snmp
-
-  * /data/snmp/*`hostname`*
-
-  The response will be a list of information about
-   the interfaces discovered through snmp
-    queries 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": {
-                "index": {"type": "string"},
-                "name": {"type": "string"}
-            },
-            "required": ["index", "name"],
-            "additionalProperties": False
-        }
-    }
-    ```
-
-#### /data/bgp
-
-  * /data/bgp/*`hostname`*
-
-  The response will be a list of information about
-   the bgp peerings configured for the requested host
-   and will be formatted as follows:
-
-    ```json
-    {
-        "$schema": "http://json-schema.org/draft-07/schema#",
-        "type": "array",
-        "items": {
-            "type": "object",
-            "properties": {
-                "description": {"type": "string"},
-                "as": {
-                    "type": "object",
-                    "properties": {
-                        "peer": {
-                            "type": "string",
-                            "pattern": r'^\d+$'
-                        },
-                        "local": {
-                            "type": "string",
-                            "pattern": r'^\d+$'
-                        },
-                    },
-                    "required": ["peer", "local"],
-                    "additionalProperties": False
-                },
-            },
-            "required": ["description", "as"],
-            "additionalProperties": False
-        }
-    }
-    ```
-
-## Backend (Redis) Storage Schema
-
-* `netconf:<hostname>`
-
-  * key example
-    * `netconf:mx1.ams.nl.geant.net`
-  * value format
-    * cf. validation in `inventory_provider.juniper.load_config`
-
-* `snmp-interfaces:<hostname>`
-
-  * key example:
-    * `snmp-interfaces:mx1.lon2.uk.geant.net`
-  * value schema
-    TODO: this needs to be checked ...
-    ```json
-    {
-        "$schema": "http://json-schema.org/draft-07/schema#",
-
-        "definitions": {
-            "v4ifc": {
-                "type": "object",
-                "properties": {
-                    "v4Address": {
-                        "type": "string",
-                        "pattern": r'^(\d+\.){3}\d+$'
-                    },
-                    "v4Mask": {
-                        "type": "string",
-                        "pattern": r'^(\d+\.){3}\d+$'
-                    },
-                    "v4InterfaceName": {"type": "string"},
-                    "index": {
-                        "type": "string",
-                        "pattern": r'^\d+$'
-                    }
-                },
-                "required": [
-                    "v4Address", "v4Mask", "v4InterfaceName", "index"],
-                "additionalProperties": False
-            },
-            "v6ifc": {
-                "type": "object",
-                "properties": {
-                    "v6Address": {
-                        "type": "string",
-                        "pattern": r'^[a-f\d:]+$'
-                    },
-                    "v6Mask": {
-                        "type": "string",
-                        "pattern": r'^\d+$'
-                    },
-                    "v6InterfaceName": {"type": "string"},
-                    "index": {
-                        "type": "string",
-                        "pattern": r'^\d+$'
-                    }
-                },
-                "required": [
-                    "v6Address", "v6Mask", "v6InterfaceName", "index"],
-                "additionalProperties": False
-            }
-        },
-
-        "type": "array",
-         "items": {
-            "anyOf": [
-                {"$ref": "#/definitions/v4ifc"},
-                {"$ref": "#/definitions/v6ifc"}
-            ]
-        }
-    }
-    ```
-
-
-* `opsdb:interface_services:<equipment name>:<interface name>`
-
-  * key examples
-    * `opsdb:interface_services:mx1.ams.nl.geant.net:ae15.1103`
-    * `opsdb:interface_services:Lab node 2:1-1/5`
-  * value schema
-    ```json
-    {
-        "$schema": "http://json-schema.org/draft-07/schema#",
-
-        "definitions": {
-            "interface": {
-                "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"},
-                    "equipment": {"type": "string"},
-                    "port": {
-                        "anyOf": [
-                            {
-                                "type": "string",
-                                "pattern": r'^[\d:]+$'
-                            },
-                            {
-                                "type": "string",
-                                "enum": ['console']
-                            }
-                        ]
-                    },
-                    "logical_unit": {
-                        "anyOf": [
-                            {"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"},
-                    "interface_name": {"type": "string"}
-                },
-                "required": ["id", "name", "status",
-                             "circuit_type", "service_type",
-                             "project", "equipment", "port",
-                             "logical_unit", "manufacturer",
-                             "card_id", "interface_name"],
-                "additionalProperties": False
-            }
-        },
-
-        "type": "object",
-        "patternProperties": {
-            "^.+$": {
-                "type": "array",
-                "items": {"$ref": "#/definitions/interface"}
-            }
-        }
-    }
-    ```
-
-
-* `opsdb:location:<equipment name>`
-
-  * key examples
-    * `opsdb:location:mx1.ams.nl.geant.net`
-    * `opsdb:location:taas.srv1.par.fr.geant.net`
-    * `opsdb:location:A test EX 3-Oct`
-  * value schema
-    ```json
-    {
-        "$schema": "http://json-schema.org/draft-07/schema#",
-        "type": "array",
-        "items": {
-            "type": "object",
-            "properties": {
-                "absid": {"type": "integer"},
-                "equipment_name": {"type": "string"},
-                "pop_name": {"type": "string"},
-                "pop_abbreviation": {"type": "string"},
-                "pop_site_id": {"type": "string"},
-                "country": {"type": "string"},
-                "longitude": {"type": "number"},
-                "latitude": {"type": "number"},
-            },
-            "required": ["absid", "equipment_name",
-                         "pop_name", "pop_abbreviation", "pop_site_id",
-                         "country", "longitude", "latitude"],
-            "additionalProperties": False
-        }
-    }
-    ```
-
-* `opsdb:services:children:<circuit db id>`
-* `opsdb:services:parents:<circuit db id>`
-
-  * key examples
-    * `opsdb:services:children:12363`
-    * `opsdb:services:parents:14407`
-  * value schema
-    TODO: this needs to be checked ...
-    ```json
-    {
-        "$schema": "http://json-schema.org/draft-07/schema#",
-
-        "definitions": {
-            "circuit_relationship": {
-                "type": "object",
-                "properties": {
-                    "parent_circuit": {"type": "string"},
-                    "parent_circuit_id": {"type": "integer"},
-                    "parent_circuit_status": {
-                        "type": "string",
-                        "enum": ["operational", "installed", "planned", "ordered"]
-                    },
-                    "child_circuit": {"type": "string"},
-                    "child_circuit_id": {"type": "integer"},
-                    "child_circuit_status": {
-                        "type": "string",
-                        "enum": ["operational", "installed", "planned", "ordered"]
-                    }
-                    "circuit_group": {"type": "integer"},
-                },
-                "required": [
-                    "parent_circuit",
-                    "parent_circuit_id",
-                    "parent_circuit_status",
-                    "child_circuit",
-                    "child_circuit_id",
-                    "child_circuit_status",
-                    "circuit_group"
-                ],
-                "additionalProperties": False
-            }
-        },
-
-        "type": "object",
-        "patternProperties": {
-            "^\d+$": {
-                "type": "array",
-                "items": {"$ref": "#/definitions/circuit_relationship"}
-            }
-        }
-    }
-    ```
-
-* `alarmsdb:interface_status:<equipment name>:<interface name>`
-  * key examples
-    * `alarmsdb:interface_status:Lab node 1:1-1/3`
-    *  `alarmsdb:interface_status:mx1.ams.nl.geant.net:ae15.1500`
-  * valid values:
-    TODO: verify these values
-    * `unknown`
-    * `up`
-    * `down`
-
-
-* `ix_public_peer:<address>`
-  * key examples
-    * `ix_public_peer:193.203.0.203`
-    * `ix_public_peer:2001:07f8:00a0:0000:0000:5926:0000:0002`
-  * valid values:
-    ```json
-    {
-        "$schema": "http://json-schema.org/draft-07/schema#",
-
-        "definitions": {
-            "ip-address": {
-                "type": "string",
-                "oneOf": [
-                    {"pattern": r'^(\d+\.){3}\d+$'},
-                    {"pattern": r'^([a-f\d]{4}:){7}[a-f\d]{4}$'}
-                ]
-            }
-        },
-
-        "type": "object",
-        "properties": {
-            "name": {"$ref": "#/definitions/ip-address"},
-            "description": {"type": "string"},
-            "as": {
-                "type": "object",
-                "properties": {
-                    "local": {"type": "integer"},
-                    "peer": {"type": "integer"},
-                },
-                "required": ["local", "peer"],
-                "additionalProperties": False
-            }
-        },
-        "required": ["name", "description", "as"],
-        "additionalProperties": False
-    }
-    ```
-
-* `vpn_rr_peers/<address>`
-  * key examples
-    * `vpn_rr_peers:193.203.0.203`
-  * valid values:
-    ```json
-    {
-        "$schema": "http://json-schema.org/draft-07/schema#",
-
-        "definitions": {
-            "ip-address": {
-                "type": "string",
-                "oneOf": [
-                    {"pattern": r'^(\d+\.){3}\d+$'},
-                    {"pattern": r'^([a-f\d]{4}:){7}[a-f\d]{4}$'}
-                ]
-            }
-        },
-
-        "type": "object",
-        "properties": {
-            "name": {"$ref": "#/definitions/ip-address"},
-            "description": {"type": "string"},
-            "peer-as": {"type": "integer"}
-        },
-        "required": ["name", "description"],
-        "additionalProperties": False
-    }
-    ```
-
-* `reverse_interface_addresses/<address>`
-  * key examples
-    * `reverse_interface_addresses:193.203.0.203`
-    * `reverse_interface_addresses:2001:07f8:00a0:0000:0000:5926:0000:0002`
-  * valid values:
-    ```json
-    {
-        "$schema": "http://json-schema.org/draft-07/schema#",
-
-        "definitions": {
-            "v4a": {
-                "type": "string",
-                "pattern": r'^(\d+\.){3}\d+$'
-            },
-            "v6a": {
-                "type": "string",
-                "pattern": r'^([a-f\d]{4}:){7}[a-f\d]{4}$'
-            },
-            "v4i": {
-                "type": "string",
-                "pattern": r'^(\d+\.){3}\d+/\d+$'
-            },
-            "v6i": {
-                "type": "string",
-                "pattern": r'^[a-f\d:]+/\d+$'
-            }
-        },
-
-        "type": "array",
-        "items": {
-            "type": "object",
-            "properties": {
-                "name": {
-                    "oneOf": [
-                        {"$ref": "#/definitions/v4a"},
-                        {"$ref": "#/definitions/v6a"}
-                    ]
-                },
-                "interface address": {
-                    "oneOf": [
-                        {"$ref": "#/definitions/v4i"},
-                        {"$ref": "#/definitions/v6i"}
-                    ]
-                },
-                "interface name": {"type": "string"},
-            },
-            "required": ["name", "interface address", "interface name"],
-            "additionalProperties": False
-        }
-    }
-    ```
diff --git a/docs/source/protocol/classifier.rst b/docs/source/protocol/classifier.rst
index 3b2b348c..df7036ad 100644
--- a/docs/source/protocol/classifier.rst
+++ b/docs/source/protocol/classifier.rst
@@ -4,6 +4,8 @@
 Classifier Endpoints
 =========================
 
+These endpoints are intended for use by Dashboard V3.
+
 /classifier/peer-info
 ---------------------
 
diff --git a/docs/source/protocol/data.rst b/docs/source/protocol/data.rst
new file mode 100644
index 00000000..753f3fc5
--- /dev/null
+++ b/docs/source/protocol/data.rst
@@ -0,0 +1,22 @@
+.. poller endpoint docs
+
+
+Data Endpoints
+=========================
+
+These endpoints are temporary and will be removed.
+
+/data/routers
+---------------------------------
+
+.. autofunction:: inventory_provider.routes.data.routers
+
+/data/interfaces
+---------------------------------
+
+.. autofunction:: inventory_provider.routes.data.interfaces
+
+/data/pop
+---------------------------------
+
+.. autofunction:: inventory_provider.routes.data.equipment_location
diff --git a/docs/source/protocol/index.rst b/docs/source/protocol/index.rst
index 9d2da5e9..068ea0ec 100644
--- a/docs/source/protocol/index.rst
+++ b/docs/source/protocol/index.rst
@@ -29,6 +29,7 @@ API modules
    :caption: Contents:
 
    classifier
-
-
-
+   poller
+   lg
+   data
+   jobs
diff --git a/docs/source/protocol/jobs.rst b/docs/source/protocol/jobs.rst
new file mode 100644
index 00000000..866f98e1
--- /dev/null
+++ b/docs/source/protocol/jobs.rst
@@ -0,0 +1,24 @@
+.. poller endpoint docs
+
+
+Jobs Endpoints
+=========================
+
+These endpoints are used for monitoring running jobs.
+
+/jobs/update
+---------------------------------
+
+.. autofunction:: inventory_provider.routes.jobs.update
+
+
+/jobs/check-task-status
+---------------------------------
+
+.. autofunction:: inventory_provider.routes.jobs.check_task_status
+
+
+/jobs/log
+---------------------------------
+
+.. autofunction:: inventory_provider.routes.jobs.load_task_log
diff --git a/docs/source/protocol/lg.rst b/docs/source/protocol/lg.rst
new file mode 100644
index 00000000..c6ce6541
--- /dev/null
+++ b/docs/source/protocol/lg.rst
@@ -0,0 +1,12 @@
+.. LG endpoint docs
+
+
+LG Endpoints
+=========================
+
+These endpoints are intended for use by LG.
+
+/lg/interfaces
+---------------------------------
+
+.. autofunction:: inventory_provider.routes.lg.routers
diff --git a/docs/source/protocol/poller.rst b/docs/source/protocol/poller.rst
new file mode 100644
index 00000000..617414f5
--- /dev/null
+++ b/docs/source/protocol/poller.rst
@@ -0,0 +1,12 @@
+.. poller endpoint docs
+
+
+Poller Endpoints
+=========================
+
+These endpoints are intended for use by BRIAN.
+
+/poller/interfaces
+---------------------------------
+
+.. autofunction:: inventory_provider.routes.poller.interfaces
diff --git a/inventory_provider/routes/data.py b/inventory_provider/routes/data.py
index f25bd80d..e49a0fab 100644
--- a/inventory_provider/routes/data.py
+++ b/inventory_provider/routes/data.py
@@ -9,6 +9,81 @@ from inventory_provider.db import opsdb
 
 routes = Blueprint("inventory-data-query-routes", __name__)
 
+ROUTERS_RESPONSE_SCHEMA = {
+    "$schema": "http://json-schema.org/draft-07/schema#",
+    "type": "array",
+    "items": {"type": "string"}
+}
+
+ROUTER_INTERFACES_SCHEMA = {
+    "$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
+    }
+}
+
+POP_RESPONSE_SCHEMA = {
+    "$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"}
+}
+
 
 @routes.after_request
 def after_request(resp):
@@ -18,6 +93,17 @@ def after_request(resp):
 @routes.route("/routers", methods=['GET', 'POST'])
 @common.require_accepts_json
 def routers():
+    """
+    Handler for `/data/routers`.
+
+    The response will be a list of router hostnames
+    for which information is available and will formatted
+    according to the following schema:
+
+    .. asjson:: inventory_provider.routes.data.ROUTERS_RESPONSE_SCHEMA
+
+    :return:
+    """
     r = common.get_current_redis()
     result = []
     for k in r.keys('netconf:*'):
@@ -31,6 +117,18 @@ def routers():
 @routes.route("/interfaces/<hostname>", methods=['GET', 'POST'])
 @common.require_accepts_json
 def router_interfaces(hostname=None):
+    """
+    Handler for `/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:
+
+    .. asjson:: inventory_provider.routes.data.ROUTER_INTERFACES_SCHEMA
+
+    :param hostname: optional hostname
+    :return:
+    """
 
     cache_key = f'classifier-cache:netconf-interfaces:{hostname}' \
         if hostname else 'classifier-cache:netconf-interfaces:all'
@@ -67,6 +165,18 @@ def router_interfaces(hostname=None):
 @routes.route("/pop/<equipment_name>", methods=['GET', 'POST'])
 @common.require_accepts_json
 def equipment_location(equipment_name):
+    """
+    Handler for `/data/pop/[equipment name]`.
+
+    Returns location information for the equipment identified
+    by `equipment name` and will be formatted as follows:
+
+    .. asjson:: inventory_provider.routes.data.POP_RESPONSE_SCHEMA
+
+    :param equipment_name: equipment name
+    :return:
+    """
+
     config = current_app.config['INVENTORY_PROVIDER_CONFIG']
 
     with db.connection(config['ops-db']) as cx:
diff --git a/inventory_provider/routes/jobs.py b/inventory_provider/routes/jobs.py
index af879679..00f6a6a2 100644
--- a/inventory_provider/routes/jobs.py
+++ b/inventory_provider/routes/jobs.py
@@ -13,6 +13,70 @@ routes = Blueprint("inventory-data-job-routes", __name__)
 logger = logging.getLogger(__name__)
 
 
+TASK_ID_RESPONSE_SCHEMA = {
+    "$schema": "http://json-schema.org/draft-07/schema#",
+    "type": "object",
+    "properties": {
+        "task id": {"type": "string"}
+    },
+    "required": ["task id"],
+    "additionalProperties": False
+}
+
+TASK_LOG_RESPONSE_SCHEMA = {
+    "$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
+}
+
+INDIVIDUAL_TASK_STATUS_RESPONSE_SCHEMA = {
+    "$schema": "http://json-schema.org/draft-07/schema#",
+    "definitions": {
+        "task": {
+            "type": "object",
+            "properties": {
+                "id": {"type": "string"},
+                "status": {"type": "string"},
+                "exception": {"type": "boolean"},
+                "ready": {"type": "boolean"},
+                "success": {"type": "boolean"},
+                "result": {"type": ["object", "null"]},
+                "parent": {"type": ["string", "null"]}
+            },
+            "required": [
+                "id", "status", "exception", "ready", "success", "parent"],
+            "additionalProperties": False
+        }
+    },
+
+    "type": "array",
+    "items": {"$ref": "#/definitions/task"}
+}
+
+
+# INDIVIDUAL_TASK_STATUS_RESPONSE_SCHEMA = {
+#     "$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
+# }
+
+
 @routes.after_request
 def after_request(resp):
     return common.after_request(resp)
@@ -21,7 +85,19 @@ def after_request(resp):
 @routes.route("/update", methods=['GET', 'POST'])
 @common.require_accepts_json
 def update():
+    """
+    Handler for `/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:
 
+    .. asjson:: inventory_provider.routes.jobs.TASK_ID_RESPONSE_SCHEMA
+
+    :return:
+    """
     force = request.args.get('force', default='false', type=str)
     try:
         force = strtobool(force)
@@ -55,6 +131,20 @@ def reload_router_config(equipment_name):
 @routes.route("check-task-status/<task_id>", methods=['GET', 'POST'])
 @common.require_accepts_json
 def check_task_status(task_id):
+    """
+    Handler for /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:
+
+    .. asjson::
+       inventory_provider.routes.jobs.INDIVIDUAL_TASK_STATUS_RESPONSE_SCHEMA
+
+    :param task_id:
+    :return:
+    """
     return jsonify(list(worker.check_task_status(task_id)))
 
 
@@ -76,7 +166,18 @@ def check_update_status():
 @routes.route("log", methods=['GET', 'POST'])
 @common.require_accepts_json
 def load_task_log():
+    """
+    Handler for `/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, and
+    will be formatted according to the following schema:
+
+    .. asjson:: inventory_provider.routes.jobs.TASK_LOG_RESPONSE_SCHEMA
 
+    :return:
+    """
     FINALIZATION_EVENTS = {'task-succeeded', 'task-failed', 'task-revoked'}
 
     config = current_app.config['INVENTORY_PROVIDER_CONFIG']
diff --git a/inventory_provider/routes/lg.py b/inventory_provider/routes/lg.py
index bcb528cc..af190383 100644
--- a/inventory_provider/routes/lg.py
+++ b/inventory_provider/routes/lg.py
@@ -10,6 +10,52 @@ ACCESS_PUBLIC = 'public'
 ACCESS_INTERNAL = 'all'
 
 
+LG_ROUTERS_SCHEMA = {
+    "$schema": "http://json-schema.org/draft-07/schema#",
+
+    "definitions": {
+        "pop-info": {
+            "type": "object",
+            "properties": {
+                "name": {"type": "string"},
+                "abbreviation": {"type": "string"},
+                "country": {"type": "string"},
+                "country code": {"type": "string"},
+                "city": {"type": "string"},
+                "longitude": {"type": "number"},
+                "latitude": {"type": "number"}
+            },
+            "required": [
+                "name",
+                "abbreviation",
+                "country",
+                "country code",
+                "city",
+                "longitude",
+                "latitude"
+            ],
+            "additionalProperties": False
+        },
+        "router": {
+            "type": "object",
+            "properties": {
+                "equipment name": {"type": "string"},
+                "type": {
+                    "type": "string",
+                    "enum": ["INTERNAL", "CORE"]
+                },
+                "pop": {"$ref": "#/definitions/pop-info"}
+            },
+            "required": ["equipment name", "type", "pop"],
+            "additionalProperties": False
+        }
+    },
+
+    "type": "array",
+    "items": {"$ref": "#/definitions/router"}
+}
+
+
 @routes.after_request
 def after_request(resp):
     return common.after_request(resp)
@@ -18,6 +64,22 @@ def after_request(resp):
 @routes.route("/routers/<string:access>", methods=['GET', 'POST'])
 @common.require_accepts_json
 def routers(access):
+    """
+    Handler for `/lg/routers/[access]` that returns a list of
+    router information for use by LG.
+
+    Endpoints `/lg/routers/public` and `/lg/routers/all`
+    are supported, and only publicly accessible routers
+    or all routers, respectively, are returned.
+
+    The response will be formatted according to the following schema:
+
+    .. asjson::
+       inventory_provider.routes.lg.LG_ROUTERS_SCHEMA
+
+    :param access: one of `public` or `all`
+    :return:
+    """
 
     if access not in {ACCESS_INTERNAL, ACCESS_PUBLIC}:
         return Response(
diff --git a/inventory_provider/routes/poller.py b/inventory_provider/routes/poller.py
index f51067f1..228ae0b7 100644
--- a/inventory_provider/routes/poller.py
+++ b/inventory_provider/routes/poller.py
@@ -9,6 +9,56 @@ from inventory_provider.routes import common
 logger = logging.getLogger(__name__)
 routes = Blueprint('poller-support-routes', __name__)
 
+INTERFACE_LIST_SCHEMA = {
+    '$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'}
+}
+
 
 @routes.after_request
 def after_request(resp):
@@ -137,7 +187,23 @@ def _load_poller_interfaces(hostname=None):
 @routes.route("/interfaces", methods=['GET', 'POST'])
 @routes.route('/interfaces/<hostname>', methods=['GET', 'POST'])
 @common.require_accepts_json
-def poller_interface_oids(hostname=None):
+def interfaces(hostname=None):
+    """
+    Handler for `/poller/interfaces` and
+    `/poller/interfaces/<hostname>`
+    which returns information for either all interfaces
+    or those on the requested hostname.
+
+    The response is a list of information for all
+    interfaces that should be polled, including service
+    information and snmp information.
+
+    .. asjson::
+       inventory_provider.routes.poller.INTERFACE_LIST_SCHEMA
+
+    :param hostname: optional, if present should be a router hostname
+    :return:
+    """
 
     cache_key = f'classifier-cache:poller-interfaces:{hostname}' \
         if hostname else 'classifier-cache:poller-interfaces:all'
diff --git a/test/per_router/test_poller_routes.py b/test/per_router/test_poller_routes.py
index 07acce19..d7351c09 100644
--- a/test/per_router/test_poller_routes.py
+++ b/test/per_router/test_poller_routes.py
@@ -1,61 +1,12 @@
 import json
 import jsonschema
+from inventory_provider.routes.poller import INTERFACE_LIST_SCHEMA
 
 DEFAULT_REQUEST_HEADERS = {
     "Content-type": "application/json",
     "Accept": ["application/json"]
 }
 
-INTERFACE_LIST_SCHEMA = {
-    '$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'}
-}
-
 
 def test_router_interfaces(router, client):
     rv = client.post(
diff --git a/test/test_general_poller_routes.py b/test/test_general_poller_routes.py
index 52419788..0cdbc90c 100644
--- a/test/test_general_poller_routes.py
+++ b/test/test_general_poller_routes.py
@@ -1,62 +1,12 @@
 import json
 import jsonschema
+from inventory_provider.routes.poller import INTERFACE_LIST_SCHEMA
 
 DEFAULT_REQUEST_HEADERS = {
     "Content-type": "application/json",
     "Accept": ["application/json"]
 }
 
-INTERFACE_LIST_SCHEMA = {
-    '$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'}
-}
-
-
 def test_get_all_interfaces(client):
     rv = client.get(
         '/poller/interfaces',
diff --git a/test/test_job_routes.py b/test/test_job_routes.py
index 33bbde51..f3a4df17 100644
--- a/test/test_job_routes.py
+++ b/test/test_job_routes.py
@@ -2,59 +2,15 @@ import json
 import jsonschema
 
 from inventory_provider.tasks.common import _get_redis, DB_LATCH_SCHEMA
+from inventory_provider.routes.jobs \
+    import INDIVIDUAL_TASK_STATUS_RESPONSE_SCHEMA, \
+    TASK_LOG_RESPONSE_SCHEMA, TASK_ID_RESPONSE_SCHEMA
 
 DEFAULT_REQUEST_HEADERS = {
     "Content-type": "application/json",
     "Accept": ["application/json"]
 }
 
-TASK_ID_RESPONSE_SCHEMA = {
-    "$schema": "http://json-schema.org/draft-07/schema#",
-    "type": "object",
-    "properties": {
-        "task id": {"type": "string"}
-    },
-    "required": ["task id"],
-    "additionalProperties": False
-}
-
-TASK_STATUS_SCHEMA = {
-    "$schema": "http://json-schema.org/draft-07/schema#",
-    "definitions": {
-        "task": {
-            "type": "object",
-            "properties": {
-                "id": {"type": "string"},
-                "status": {"type": "string"},
-                "exception": {"type": "boolean"},
-                "ready": {"type": "boolean"},
-                "success": {"type": "boolean"},
-                "result": {"type": ["object", "null"]},
-                "parent": {"type": ["string", "null"]}
-            },
-            "required": [
-                "id", "status", "exception", "ready", "success", "parent"],
-            "additionalProperties": False
-        }
-    },
-
-    "type": "array",
-    "items": {"$ref": "#/definitions/task"}
-}
-
-TASK_LOG_SCHEMA = {
-    "$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
-}
-
 
 def backend_db():
     return _get_redis({
@@ -175,7 +131,7 @@ def test_check_update_status(client, mocker):
         headers=DEFAULT_REQUEST_HEADERS)
     assert rv.status_code == 200
     result = json.loads(rv.data.decode('utf-8'))
-    jsonschema.validate(result, TASK_STATUS_SCHEMA)
+    jsonschema.validate(result, INDIVIDUAL_TASK_STATUS_RESPONSE_SCHEMA)
     for status in result:
         assert status['id'] == 'zz55'
         assert status['status'] == 'SUCCESS'
@@ -207,7 +163,7 @@ def test_check_task_status_success(client, mocker):
         headers=DEFAULT_REQUEST_HEADERS)
     assert rv.status_code == 200
     result = json.loads(rv.data.decode('utf-8'))
-    jsonschema.validate(result, TASK_STATUS_SCHEMA)
+    jsonschema.validate(result, INDIVIDUAL_TASK_STATUS_RESPONSE_SCHEMA)
     for status in result:
         assert status['id'] == 'abc'
         assert status['status'] == 'SUCCESS'
@@ -228,7 +184,7 @@ def test_check_task_status_custom_status(client, mocker):
         headers=DEFAULT_REQUEST_HEADERS)
     assert rv.status_code == 200
     result = json.loads(rv.data.decode('utf-8'))
-    jsonschema.validate(result, TASK_STATUS_SCHEMA)
+    jsonschema.validate(result, INDIVIDUAL_TASK_STATUS_RESPONSE_SCHEMA)
     for status in result:
         assert status['id'] == 'xyz'
         assert status['status'] == 'custom'
@@ -248,7 +204,7 @@ def test_check_task_status_exception(client, mocker):
         headers=DEFAULT_REQUEST_HEADERS)
     assert rv.status_code == 200
     result = json.loads(rv.data.decode('utf-8'))
-    jsonschema.validate(result, TASK_STATUS_SCHEMA)
+    jsonschema.validate(result, INDIVIDUAL_TASK_STATUS_RESPONSE_SCHEMA)
     for status in result:
         assert status['id'] == '123-xyz.ABC'
         assert status['status'] == 'FAILURE'
@@ -380,7 +336,7 @@ def test_job_log(client):
         headers=DEFAULT_REQUEST_HEADERS)
     assert rv.status_code == 200
     result = json.loads(rv.data.decode('utf-8'))
-    jsonschema.validate(result, TASK_LOG_SCHEMA)
+    jsonschema.validate(result, TASK_LOG_RESPONSE_SCHEMA)
 
     assert len(result['errors']) == 3
     assert len(result['pending']) == 3
diff --git a/test/test_lg_routes.py b/test/test_lg_routes.py
index e45e3b59..f1a41270 100644
--- a/test/test_lg_routes.py
+++ b/test/test_lg_routes.py
@@ -1,58 +1,13 @@
 import json
 import jsonschema
 import pytest
+from inventory_provider.routes.lg import LG_ROUTERS_SCHEMA
 
 DEFAULT_REQUEST_HEADERS = {
     "Content-type": "application/json",
     "Accept": ["application/json"]
 }
 
-LG_ROUTERS_SCHEMA = {
-    "$schema": "http://json-schema.org/draft-07/schema#",
-
-    "definitions": {
-        "pop-info": {
-            "type": "object",
-            "properties": {
-                "name": {"type": "string"},
-                "abbreviation": {"type": "string"},
-                "country": {"type": "string"},
-                "country code": {"type": "string"},
-                "city": {"type": "string"},
-                "longitude": {"type": "number"},
-                "latitude": {"type": "number"}
-            },
-            "required": [
-                "name",
-                "abbreviation",
-                "country",
-                "country code",
-                "city",
-                "longitude",
-                "latitude"
-            ],
-            "additionalProperties": False
-        },
-        "router": {
-            "type": "object",
-            "properties": {
-                "equipment name": {"type": "string"},
-                "type": {
-                    "type": "string",
-                    "enum": ["INTERNAL", "CORE"]
-                },
-                "pop": {"$ref": "#/definitions/pop-info"}
-            },
-            "required": ["equipment name", "type", "pop"],
-            "additionalProperties": False
-        }
-    },
-
-    "type": "array",
-    "items": {"$ref": "#/definitions/router"}
-}
-
-
 def test_public_routers(client):
     rv = client.get(
         '/lg/routers/public',
-- 
GitLab