diff --git a/.coveragerc b/.coveragerc deleted file mode 100644 index 10c025fbfa1c5cd9566a1b38d8d442b1494a4208..0000000000000000000000000000000000000000 --- a/.coveragerc +++ /dev/null @@ -1,2 +0,0 @@ -[run] -concurrency=multiprocessing,thread \ No newline at end of file diff --git a/LICENSE.txt b/LICENSE.txt new file mode 100644 index 0000000000000000000000000000000000000000..a047e435811c03a31e4c65c0d7ca9b7ce8d0cb2a --- /dev/null +++ b/LICENSE.txt @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2023 GÉANT Vereniging + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/MANIFEST.in b/MANIFEST.in index 04932c963ccc3b400e6ff0224f1bb000240226e6..1842a72e0920e258d37be3cfd645fda7a4f9da39 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -2,4 +2,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 +recursive-include brian_dashboard_manager/templating/templates * +recursive-exclude test * \ No newline at end of file diff --git a/brian_dashboard_manager/config.py b/brian_dashboard_manager/config.py index 3b09bf03a820469594ba41beaca629570182de49..b22ef4e4d11e7ce2764cd9b04ffdfb2f1791685b 100644 --- a/brian_dashboard_manager/config.py +++ b/brian_dashboard_manager/config.py @@ -203,7 +203,7 @@ CONFIG_SCHEMA = { "datasources": { "type": "object", "properties": { - "influxdb": {"$ref": "#definitions/influx-datasource"} + "influxdb": {"$ref": "#/definitions/influx-datasource"} }, "additionalProperties": False }, diff --git a/brian_dashboard_manager/templating/helpers.py b/brian_dashboard_manager/templating/helpers.py index 2e0089a1b535152a7ad2924b81108b01e5299edd..6426eb71d86c0d0f5d29ecb6b3c836407c3ee010 100644 --- a/brian_dashboard_manager/templating/helpers.py +++ b/brian_dashboard_manager/templating/helpers.py @@ -231,11 +231,20 @@ def get_nren_interface_data(services, interfaces, excluded_dashboards): # MDVPN type services don't have data in BRIAN continue + has_v6_interface = False + for interface in _interfaces: + if 'addresses' in interface: + for address in interface['addresses']: + if address.find(':') > 0: + has_v6_interface = True + break + dashboard['SERVICES'].append({ 'measurement': measurement, 'title': title, 'scid': scid, - 'sort': (sid[:2], name) + 'sort': (sid[:2], name), + 'has_v6': has_v6_interface }) def _check_in_aggregate(router, interface): @@ -486,7 +495,7 @@ def get_panel_fields(panel, panel_type, datasource): }) -def default_interface_panel_generator(gridPos): +def default_interface_panel_generator(gridPos, ipv6_only=False): """ Helper for generating panel definitions for dashboards. @@ -494,6 +503,7 @@ def default_interface_panel_generator(gridPos): panel data and panel type. :param gridPos: generator for grid positions + :param ipv6_only: whether to use IPv6 traffic exclusively or not :return: function that generates panel definitions """ @@ -515,20 +525,29 @@ def default_interface_panel_generator(gridPos): result = [] for panel in panels: - result.append(get_panel_fields({ - **panel, - **next(gridPos) - }, 'traffic', datasource)) - if panel.get('has_v6', False): - result.append(get_panel_fields({ - **panel, - **next(gridPos) - }, 'IPv6', datasource)) - if errors: + if ipv6_only: + if panel.get('has_v6', False): + result.append(get_panel_fields({ + **panel, + **next(gridPos) + }, 'IPv6', datasource)) + else: + continue + else: result.append(get_panel_fields({ **panel, **next(gridPos) - }, 'errors', datasource)) + }, 'traffic', datasource)) + if panel.get('has_v6', False): + result.append(get_panel_fields({ + **panel, + **next(gridPos) + }, 'IPv6', datasource)) + if errors: + result.append(get_panel_fields({ + **panel, + **next(gridPos) + }, 'errors', datasource)) return result @@ -567,6 +586,7 @@ def get_nren_dashboard_data_single(data, datasource, tag): agg_panels = [] panel_gen = default_interface_panel_generator(gridPos) + panel_ipv6_gen = default_interface_panel_generator(gridPos, ipv6_only=True) services_dropdown = create_dropdown_panel('Services', **next(gridPos)) @@ -578,6 +598,12 @@ def get_nren_dashboard_data_single(data, datasource, tag): service_panels = panel_gen( sorted(dash['SERVICES'], key=sort_key), datasource) + + services_ipv6_dropdown = create_dropdown_panel('Services - IPv6 Only', **next(gridPos)) + service_ipv6_panels = panel_ipv6_gen( + sorted(dash['SERVICES'], key=sort_key), datasource + ) + iface_dropdown = create_dropdown_panel('Interfaces', **next(gridPos)) phys_panels = panel_gen(dash['PHYSICAL'], datasource, True) @@ -590,6 +616,10 @@ def get_nren_dashboard_data_single(data, datasource, tag): 'dropdown': services_dropdown, 'panels': service_panels, }, + { + 'dropdown': services_ipv6_dropdown, + 'panels': service_ipv6_panels + }, { 'dropdown': iface_dropdown, 'panels': phys_panels, @@ -769,7 +799,7 @@ def get_aggregate_dashboard_data(title, remotes, datasource, tag): ingress and one for egress. :param title: title for the dashboard - :param targets: dictionary of targets for the panels, the key is the + :param remotes: dictionary of targets for the panels, the key is the remote (usually a customer) and the value is a list of targets for that remote. A single target represents how to fetch data for one interface. diff --git a/changelog.md b/changelog.md index daf7df5d8ce05316d8d2f21c63652cefd068ba55..ae6f889ad242271b73c41312a20097bc22475976 100644 --- a/changelog.md +++ b/changelog.md @@ -2,6 +2,9 @@ All notable changes to this project will be documented in this file. +## [0.54] - 2023-02-09 +- POL1-648: Added IPv6 graphs for NREN dashboards + ## [0.53] - 2023-06-21 - Add banner explaining difference between average/mean for >48h time ranges diff --git a/setup.py b/setup.py index bd93bf37a7dcae0578f7753a98ccfdd975682b73..bdef8ce35787a79235b59199077d9c4b4178f3e7 100644 --- a/setup.py +++ b/setup.py @@ -2,7 +2,7 @@ from setuptools import setup, find_packages setup( name='brian-dashboard-manager', - version="0.53", + version="0.54", author='GEANT', author_email='swd@geant.org', description='', @@ -16,4 +16,6 @@ setup( 'sentry-sdk[flask]' ], include_package_data=True, + license='MIT', + license_files=('LICENSE.txt',) ) diff --git a/test/__init__.py b/test/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/test/test_gws_direct.py b/test/test_gws_direct.py index 5ff611024caa768619263c39cecc828d7eecb675..0a263c0f33a2c07ae2ec3fcd4c98020c42c1ca78 100644 --- a/test/test_gws_direct.py +++ b/test/test_gws_direct.py @@ -1,5 +1,5 @@ import responses -from conftest import get_test_data +from test.conftest import get_test_data from brian_dashboard_manager.templating.gws import generate_gws from brian_dashboard_manager.inventory_provider.interfaces import \ get_gws_direct diff --git a/test/test_update.py b/test/test_update.py index 55df28bd65daa4c56e2ff9d4e1597db4fb79b1d1..57b09f2057e5dfb234d0de0d59d8749d05104c7e 100644 --- a/test/test_update.py +++ b/test/test_update.py @@ -3,7 +3,7 @@ import json from brian_dashboard_manager.grafana.provision import provision_folder, \ provision -from conftest import get_test_data +from test.conftest import get_test_data TEST_INTERFACES = [ { diff --git a/tox.ini b/tox.ini index f2c726d273badaeac99d80aa1b1ca0736b1422dd..dc78bc46551ca55171192633bc42e0c3eaaa935f 100644 --- a/tox.ini +++ b/tox.ini @@ -1,24 +1,22 @@ [tox] -envlist = py36 +envlist = py38, py311 [flake8] exclude = venv,.tox max-line-length = 120 +[coverage:run] +concurrency = multiprocessing,thread + [testenv] -setenv = - COVERAGE_PROCESS_START=.coveragerc deps = - coverage + pytest-xdist + pytest-cov flake8 -r requirements.txt commands = coverage erase - coverage run --source brian_dashboard_manager -m pytest {posargs} - coverage combine - coverage xml - coverage html - coverage report --fail-under 75 + pytest -n auto --cov brian_dashboard_manager --cov-fail-under=80 --cov-report html --cov-report xml --cov-report term -p no:checkdocs flake8 sphinx-build -M html docs/source docs/build