diff --git a/MANIFEST.in b/MANIFEST.in index 199eef4d0314ba203287f5e6ef266505bfaebadb..04932c963ccc3b400e6ff0224f1bb000240226e6 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -1,4 +1,5 @@ include brian_dashboard_manager/logging_default_config.json include brian_dashboard_manager/dashboards/* include brian_dashboard_manager/datasources/* +include config.json.example recursive-include brian_dashboard_manager/templating/templates * \ No newline at end of file diff --git a/README.md b/README.md index 8cae3b99e4e03cbeb9198d8f2eee1d6e3b051617..84a65db87513741d4f9e00fba9afedcdbefc103d 100644 --- a/README.md +++ b/README.md @@ -1,24 +1,33 @@ -# Skeleton Web App +# BRIAN Dashboard Manager ## Overview -This module implements a skeleton Flask-based webservice. +This module is used to provision Organizations and Dashboards in Grafana for BRIAN. +It implements a Flask-based webservice used only to trigger the provisioning process. -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. +The dashboards are generated from a list of interfaces obtained from Inventory Provider. -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. +Jinja templates are populated with data from these interfaces to render Dashboard JSON definitions sent to the Grafana API. +Grafana API-related code lives in the `grafana` package. + +The `brian_dashboard_manager/grafana/provision.py` file is responsible for the entire provisioning lifecycle. + +Grafana API endpoints have wrapper functions in one file for relevant parts of the API, e.g. `brian_dashboard_manager/grafana/dashboard.py` for the dashboard API functions. + +Another example is `brian_dashboard_manager/grafana/organization.py` for the organization API functions. + +Some of the provisioned dashboards are not generated but are just static JSON files. These are put in the `brian_dashboard_manager/dashboards` directory. The same can be done for JSON datasource definitions in the `datasources` directory. + +The `brian_dashboard_manager/templating` package contains the code and Jinja templates used to render dashboard JSON. Most dashboards reuse the same templates, with the exception of NREN-specific dashboards, which has its own template. + +Of note is the `templating/helpers.py` file, which has all of the predicates and helper functions used to group interfaces together and generate the necessary data for the dashboard templates. +The `templating/render.py` has functions for rendering of the various Jinja templates from the given data. ## Configuration This app allows specification of a few -example configuration parameters. These +example configuration parameters. These parameters should stored in a file formatted similarly to `config.json.example`, and the name of this file should be stored in the environment @@ -29,58 +38,37 @@ variable `CONFIG_FILENAME` when running the service. This module has been tested in the following execution environments: - As an embedded Flask application. -For example, the application could be launched as follows: + For example, the application could be launched as follows: ```bash -$ export FLASK_APP=app.py -$ export CONFIG_FILENAME=config.json +$ export FLASK_APP=/path/to/brian_dashboard_manager/app.py +$ export CONFIG_FILENAME=/path/to/config.json $ 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. - + - Details of `gunicorn` configuration can be found in the brian_dashboard_manager Puppet repository. ## Protocol Specification The following resources can be requested from the webservice. ### resources - Any non-empty responses are JSON formatted messages. -#### /data/version - - * /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 - } - ``` +## /update -#### /test/test1 +This resource is used to trigger the provisioning to Grafana. +It responds to the request immediately after starting the provisioning process. -The response will be some json data, as an example ... +```json +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "type": "object", + "properties": { + "message": { + "type": "string" + } + } +} +``` diff --git a/brian_dashboard_manager/__init__.py b/brian_dashboard_manager/__init__.py index e929766837764b2469403562629410388d702957..e21a8480a576e2864f9f062f6c174949b8a356e2 100644 --- a/brian_dashboard_manager/__init__.py +++ b/brian_dashboard_manager/__init__.py @@ -31,7 +31,7 @@ def create_app(): app_config.update(config.load(f)) app = Flask(__name__) - app.secret_key = os.environ.get('SECRET_KEY') or 'super secret session key' + app.secret_key = os.environ.get('SECRET_KEY', 'super secret session key') app.config[CONFIG_KEY] = app_config from brian_dashboard_manager.routes import update diff --git a/config.json.example b/config.json.example new file mode 100644 index 0000000000000000000000000000000000000000..a50cc66bd1316eb5763750bf3a5a5ec41a091c01 --- /dev/null +++ b/config.json.example @@ -0,0 +1,18 @@ +{ + "admin_username": "admin", + "admin_password": "admin", + "hostname": "localhost:3000", + "inventory_provider": "http://inventory-provider01.geant.org:8080", + "datasources": { + "influxdb": { + "name": "PollerInfluxDB", + "type": "influxdb", + "access": "proxy", + "url": "http://test-poller-ui01.geant.org:8086", + "database": "poller", + "basicAuth": false, + "isDefault": true, + "readOnly": false + } + } +} \ No newline at end of file