From f21a006f5ddeb28aa13f5169ff7dc87a67c197d9 Mon Sep 17 00:00:00 2001
From: Erik Reid <erik.reid@geant.org>
Date: Tue, 22 Nov 2022 14:22:32 +0100
Subject: [PATCH] added validation to docs

---
 docs/source/basic-tools.rst                   |  2 +
 docs/source/index.rst                         |  2 +-
 resource_management/cli.py                    | 14 ++--
 .../hardware/{__init.py__ => __init__.py}     |  0
 resource_management/hardware/router.py        | 69 +++++++++++++++++++
 5 files changed, 78 insertions(+), 9 deletions(-)
 rename resource_management/hardware/{__init.py__ => __init__.py} (100%)

diff --git a/docs/source/basic-tools.rst b/docs/source/basic-tools.rst
index 484dd74..b223174 100644
--- a/docs/source/basic-tools.rst
+++ b/docs/source/basic-tools.rst
@@ -4,3 +4,5 @@ CLI Tools
 =========================
 
 .. automodule:: resource_management.cli
+
+.. automodule:: resource_management.hardware.router
diff --git a/docs/source/index.rst b/docs/source/index.rst
index 05090e0..5d9e5bf 100644
--- a/docs/source/index.rst
+++ b/docs/source/index.rst
@@ -11,7 +11,7 @@ Documentation for the NAT Resource Management tools
 ------------------
 
 Configuration file format
----------------------
+---------------------------------
 
 The following example indicates the schema for the configuration file required to call the Resource Management client::
 
diff --git a/resource_management/cli.py b/resource_management/cli.py
index f961d6a..77dfada 100644
--- a/resource_management/cli.py
+++ b/resource_management/cli.py
@@ -29,7 +29,7 @@ to this schema:
 import json
 import click
 import logging
-from jsonschema.exceptions import ValidationError
+from jsonschema import validate, ValidationError
 
 import environment
 import config
@@ -38,7 +38,7 @@ from db import mysql_dsn
 from db import init_db_model
 from db import model
 from db import session_scope
-from hardware.router import junos_router
+from hardware.router import load_line_cards, LINE_CARDS_LIST_SCHEMA
 
 environment.setup_logging()
 logger = logging.getLogger(__name__)
@@ -81,14 +81,12 @@ def create(config, fqdn):
     """
 
     router_config = config["router"]
-    jr = junos_router(fqdn, router_config)
-    router = jr.load_router()
-    jr.close_device()
-    logger.info("Obtained the following hardware info about router: {0}"
-                .format(router))
+    line_cards = list(load_line_cards(fqdn, router_config))
+    # logger.info("Obtained the following hardware info about router: {0}"
+    #             .format(router))
 
     try:
-        junos_router_schema.validate(router)
+        validate(line_cards, LINE_CARDS_LIST_SCHEMA)
     except ValidationError as e:
         raise click.BadParameter(e.message)
 
diff --git a/resource_management/hardware/__init.py__ b/resource_management/hardware/__init__.py
similarity index 100%
rename from resource_management/hardware/__init.py__
rename to resource_management/hardware/__init__.py
diff --git a/resource_management/hardware/router.py b/resource_management/hardware/router.py
index 7cbd42f..79f66f5 100644
--- a/resource_management/hardware/router.py
+++ b/resource_management/hardware/router.py
@@ -1,3 +1,13 @@
+"""
+
+router utilities
+===================
+
+.. contents:: :local:
+
+.. autofunction:: resource_management.hardware.router.load_line_cards
+
+"""
 import logging
 
 from jnpr.junos import Device
@@ -7,6 +17,50 @@ from jnpr.junos.op.phyport import PhyPortTable
 import contextlib
 
 
+LINE_CARDS_LIST_SCHEMA = {
+    '$schema': 'http://json-schema.org/draft-07/schema#',
+
+    'definitions': {
+        'node': {
+            'type': 'string'
+        },
+        'line-card': {
+            'type': 'array',
+            'items': {
+                'type': 'object',
+                'properties': {
+                    'model': {'type': 'string'},
+                    'position': {'type': 'integer', 'minimum': 0}
+                },
+                'required': ['model', 'position'],
+                'additionalProperties': False
+            }
+        },
+        'port': {
+            'type': 'array',
+            'items': {
+                'type': 'object',
+                'properties': {
+                    'name': {'type': 'string', 'pattern': '^[0-9]{1,2}\\/[0-9]{1,3}'},
+                    'speed': {'type': 'integer', 'minimum': 0},
+                    '_line_card_position': {'type': 'integer', 'minimum': 0}
+                },
+                'required': ['name', 'speed', '_line_card_position'],
+                'additionalProperties': False
+            }
+        }
+    },
+
+    'type': 'object',
+    'properties': {
+        'node': {'$ref': '#/definitions/node'},
+        'line_cards': {'$ref': '#/definitions/line-card'},
+        'ports': {'$ref': '#/definitions/port'}
+    },
+    'required': ['node', 'line_cards', 'ports'],
+    'additionalProperties': False
+}
+
 @contextlib.contextmanager
 def device(hostname, username, key_filename, port=830):
     dev = Device(
@@ -22,6 +76,21 @@ def device(hostname, username, key_filename, port=830):
 
 
 def load_line_cards(hostname, username, key_filename, port=830):
+    """
+     Loads all line cards from the given hostname
+
+     The response will be formatted according to the following schema:
+
+     .. asjson::
+        resource_management.hardware.router.load_line_cards.LINE_CARDS_LIST_SCHEMA
+
+     :param hostname: router hostname
+     :param username: router username
+     :param key_filename: ssh private key filename
+     :param port: netconf port
+     :return: yields elements of the LINE_CARDS_LIST_SCHEMA
+     """
+
     with device(
             hostname=hostname,
             port=port,
-- 
GitLab