import responses import json from brian_dashboard_manager.grafana.provision import provision_folder, \ provision TEST_INTERFACES = [ { "router": "srx2.ch.office.geant.net", "name": "ge-0/0/8", "bundle": [], "bundle-parents": [], "description": "PHY CUSTOMER GEANT CORPORATE SRF000001 | GEANT Corporate to MX1.LON - Via Vodafone", # noqa: E501 "circuits": [ { "id": 679232, "name": "GEANT CORPORATE TO MX1.LON - VIA VODAFONE", "type": "GEANT IP", "status": "non-monitored" } ], "snmp-index": 523, "dashboards": [ "NREN", "RE_CUST" ], "dashboard_info": { "name": "GEANT", "interface_type": "PHYSICAL" }, "dashboards_info": [{ "name": "GEANT", "interface_type": "PHYSICAL" }], "ipv4": [], "ipv6": [] }, { "router": "srx2.ch.office.geant.net", "name": "ge-0/0/8.10", "bundle": [], "bundle-parents": [], "description": "SRV_GLOBAL CUSTOMER GEANT #GEANT_CORPORATE-ViaVodafone | GEANT Corporate to mx1.lon - Via Vodafone ", # noqa: E501 "circuits": [ { "id": 679360, "name": "GEANT_CORPORATE-VIAVODAFONE", "type": "GEANT IP", "status": "non-monitored" } ], "snmp-index": 543, "dashboards": [ "NREN", "RE_CUST" ], "dashboard_info": { "name": "GEANT", "interface_type": "LOGICAL" }, "dashboards_info": [{ "name": "GEANT", "interface_type": "LOGICAL" }], "ipv4": [ "62.40.127.131/31" ], "ipv6": [ "2001:798:99:1::ca/126" ] }, { "router": "srx2.ch.office.geant.net", "name": "ge-0/0/8.11", "bundle": [], "bundle-parents": [], "description": "SRV_GLOBAL CUSTOMER GEANT #GEANT_CORPORATE_ViaVodafone-VRF | GEANT Corporate to mx1.lon - Via Vodafone - for VRF", # noqa: E501 "circuits": [ { "id": 712144, "name": "GEANT_CORPORATE_VIAVODAFONE-VRF", "type": "GEANT IP", "status": "non-monitored" } ], "snmp-index": 545, "dashboards": [ "NREN", "RE_CUST" ], "dashboard_info": { "name": "GEANT", "interface_type": "LOGICAL" }, "dashboards_info": [{ "name": "GEANT", "interface_type": "LOGICAL" }], "ipv4": [ "10.101.0.6/30" ], "ipv6": [] }, { "router": "srx2.ch.office.geant.net", "name": "ge-0/0/8.12", "bundle": [], "bundle-parents": [], "description": "SRV_GLOBAL CUSTOMER GEANT #GEANT_CORPORATE_ViaVodafone-VRF-TEST | GEANT Corporate to mx1.lon - Via Vodafone - DASHBOARD BGP TEST VLAN", # noqa: E501 "circuits": [ { "id": 678920, "name": "GEANT_CORPORATE_VIAVODAFONE-VRF-TEST (DO NOT OPEN A TICKET)", # noqa: E501 "type": "GEANT IP", "status": "non-monitored" } ], "snmp-index": 522, "dashboards": [ "NREN", "RE_CUST" ], "dashboard_info": { "name": "GEANT", "interface_type": "LOGICAL" }, "dashboards_info": [{ "name": "GEANT", "interface_type": "LOGICAL" }], "ipv4": [ "62.40.127.141/31" ], "ipv6": [] }, { "router": "srx2.ch.office.geant.net", "name": "ge-0/0/8.996", "bundle": [], "bundle-parents": [], "description": "SRV_GLOBAL CUSTOMER GEANT #GEANT_OPERATIONS_LabConnectivity | GEANT MX1.LON Infinera VRF to Operations Lab", # noqa: E501 "circuits": [ { "id": 678999, "name": "GEANT_OPERATIONS_LABCONNECTIVITY", "type": "GEANT IP", "status": "non-monitored" } ], "snmp-index": 554, "dashboards": [ "NREN", "RE_CUST" ], "dashboard_info": { "name": "GEANT", "interface_type": "LOGICAL" }, "dashboards_info": [{ "name": "GEANT", "interface_type": "LOGICAL" }], "ipv4": [ "10.1.1.1/30" ], "ipv6": [] }, { "router": "mx1.ams.nl.geant.net", "name": "xe-0/0/0", "bundle": [ "ae16" ], "bundle-parents": [], "description": "PHY CUSTOMER KIAE P_AE16 SRF9915671 |", "circuits": [], "snmp-index": 588, "dashboards": [ "NREN", "RE_CUST" ], "dashboard_info": { "name": "KIAE", "interface_type": "PHYSICAL" }, "dashboards_info": [{ "name": "KIAE", "interface_type": "PHYSICAL" }], "ipv4": [], "ipv6": [] }, { "router": "mx1.ams.nl.geant.net", "name": "xe-0/0/1", "bundle": [ "ae14" ], "bundle-parents": [], "description": "PHY CUSTOMER SWITCH P_AE14 SRF18008 |", "circuits": [], "snmp-index": 589, "dashboards": [ "NREN", "RE_CUST" ], "dashboard_info": { "name": "SWITCH", "interface_type": "PHYSICAL" }, "dashboards_info": [{ "name": "SWITCH", "interface_type": "PHYSICAL" }], "ipv4": [], "ipv6": [] }, { "router": "mx1.ams.nl.geant.net", "name": "ge-0/2/1.0", "bundle": [], "bundle-parents": [], "description": "SRV_L2CIRCUIT INFRASTRUCTURE GEANT GEANT #AMS-ZAG OPENFLOW |", # noqa: E501 "circuits": [], "snmp-index": 687, "dashboards": [ "L2_CIRCUIT" ], "dashboard_info": { "name": "GEANT", "interface_type": "LOGICAL" }, "dashboards_info": [{ "name": "GEANT", "interface_type": "LOGICAL" }], "ipv4": [], "ipv6": [] }, { "router": "mx1.ams.nl.geant.net", "name": "ge-0/2/2.0", "bundle": [], "bundle-parents": [], "description": "SRV_L2CIRCUIT INFRASTRUCTURE GEANT GEANT #AMS-VIE OPENFLOW |", # noqa: E501 "circuits": [], "snmp-index": 711, "dashboards": [ "L2_CIRCUIT" ], "dashboard_info": { "name": "GEANT", "interface_type": "LOGICAL" }, "dashboards_info": [{ "name": "GEANT", "interface_type": "LOGICAL" }], "ipv4": [], "ipv6": [] }, { "router": "mx1.ams.nl.geant.net", "name": "ge-0/2/4.0", "bundle": [], "bundle-parents": [], "description": "SRV_L2CIRCUIT INFRASTRUCTURE GEANT GEANT #AMS-FRA OPENFLOW |", # noqa: E501 "circuits": [], "snmp-index": 718, "dashboards": [ "L2_CIRCUIT" ], "dashboard_info": { "name": "GEANT", "interface_type": "LOGICAL" }, "dashboards_info": [{ "name": "GEANT", "interface_type": "LOGICAL" }], "ipv4": [], "ipv6": [] } ] NREN_INTERFACES = [ { "router": "mx1.dub2.ie.geant.net", "name": "xe-0/0/0", "bundle": [ "ae10" ], "bundle-parents": [], "description": "PHY CUSTOMER HEANET P_AE10 SRF9948758 | HEANET-AP2-LL3", # noqa: E501 "circuits": [], "snmp-index": 554, "dashboards": [ "NREN", "RE_CUST" ], "dashboard_info": { "name": "HEANET", "interface_type": "PHYSICAL" }, "dashboards_info": [{ "name": "HEANET", "interface_type": "PHYSICAL" }], "ipv4": [], "ipv6": [] }, { "router": "mx1.dub2.ie.geant.net", "name": "xe-1/0/1", "bundle": [ "ae10" ], "bundle-parents": [], "description": "PHY CUSTOMER HEANET P_AE10 SRF0000001 | HEANET-AP2-LL2", # noqa: E501 "circuits": [], "snmp-index": 527, "dashboards": [ "NREN", "RE_CUST" ], "dashboard_info": { "name": "HEANET", "interface_type": "PHYSICAL" }, "dashboards_info": [{ "name": "HEANET", "interface_type": "PHYSICAL" }], "ipv4": [], "ipv6": [] }, { "router": "mx1.dub2.ie.geant.net", "name": "xe-1/1/0", "bundle": [ "ae10" ], "bundle-parents": [], "description": "PHY CUSTOMER HEANET P_AE10 SRF9925903 | HEANET-AP2-LL1", # noqa: E501 "circuits": [], "snmp-index": 528, "dashboards": [ "NREN", "RE_CUST" ], "dashboard_info": { "name": "HEANET", "interface_type": "PHYSICAL" }, "dashboards_info": [{ "name": "HEANET", "interface_type": "PHYSICAL" }], "ipv4": [], "ipv6": [] }, { "router": "mx1.dub2.ie.geant.net", "name": "ae10", "bundle": [], "bundle-parents": [ "xe-0/0/0", "xe-1/0/1", "xe-1/1/0" ], "description": "LAG CUSTOMER HEANET SRF9925909 | HEANET-AP2-LAG", "circuits": [], "snmp-index": 596, "dashboards": [ "NREN", "RE_CUST" ], "dashboard_info": { "name": "HEANET", "interface_type": "AGGREGATE" }, "dashboards_info": [{ "name": "HEANET", "interface_type": "AGGREGATE" }], "ipv4": [], "ipv6": [] }, { "router": "mx1.dub2.ie.geant.net", "name": "ae10.12", "bundle": [], "bundle-parents": [ "xe-0/0/0", "xe-1/0/1", "xe-1/1/0" ], "description": "SRV_GLOBAL CUSTOMER HEANET #HEANET-AP2 | ASN1213 | ", "circuits": [ { "id": 662976, "name": "HEANET-AP2", "type": "GEANT IP", "status": "operational" } ], "snmp-index": 713, "dashboards": [ "NREN", "RE_CUST" ], "dashboard_info": { "name": "HEANET", "interface_type": "LOGICAL" }, "dashboards_info": [{ "name": "HEANET", "interface_type": "LOGICAL" }], "ipv4": [ "62.40.125.13/30" ], "ipv6": [ "2001:0798:0018:10aa::15/126" ] }, { "router": "mx1.dub2.ie.geant.net", "name": "ae10.30", "bundle": [], "bundle-parents": [ "xe-0/0/0", "xe-1/0/1", "xe-1/1/0" ], "description": "SRV_MDVPN CUSTOMER HEANET AP2 #HEANET-BGP-LU-CoC-1 |", # noqa: E501 "circuits": [ { "id": 663160, "name": "HEANET-BGP-LU-COC-1", "type": "MD-VPN (NATIVE)", "status": "operational" } ], "snmp-index": 712, "dashboards": [ "MDVPN_CUSTOMERS", "NREN" ], "dashboard_info": { "name": "HEANET", "interface_type": "LOGICAL" }, "dashboards_info": [{ "name": "HEANET", "interface_type": "LOGICAL" }], "ipv4": [ "62.40.102.36/31" ], "ipv6": [] }, { "router": "mx1.dub2.ie.geant.net", "name": "ae10.333", "bundle": [], "bundle-parents": [ "xe-0/0/0", "xe-1/0/1", "xe-1/1/0" ], "description": "SRV_IAS CUSTOMER HEANET #HEANET-AP2-IAS IASPS | ASN1213 ", # noqa: E501 "circuits": [ { "id": 663214, "name": "HEANET-AP2-IAS", "type": "GEANT PEERING", "status": "operational" } ], "snmp-index": 658, "dashboards": [ "IAS_CUSTOMER", "NREN" ], "dashboard_info": { "name": "HEANET", "interface_type": "LOGICAL" }, "dashboards_info": [{ "name": "HEANET", "interface_type": "LOGICAL" }], "ipv4": [ "83.97.88.77/30" ], "ipv6": [ "2001:798:1::61/126" ] }, { "router": "mx1.dub2.ie.geant.net", "name": "ae10.1214", "bundle": [], "bundle-parents": [ "xe-0/0/0", "xe-1/0/1", "xe-1/1/0" ], "description": "SRV_L2CIRCUIT CUSTOMER HEANET GEANT #ams-dub2-HEANET-RARE-21061 |", # noqa: E501 "circuits": [ { "id": 713335, "name": "AMS-DUB2-HEANET-RARE-21061", "type": "GEANT PLUS", "status": "non-monitored" } ], "snmp-index": 790, "dashboards": [ "L2_CIRCUIT" ], "dashboard_info": { "name": "HEANET", "interface_type": "LOGICAL" }, "dashboards_info": [{ "name": "GEANT", "interface_type": "LOGICAL" }, { "name": "HEANET", "interface_type": "LOGICAL" }], "ipv4": [], "ipv6": [] } ] EUMETSAT_MULTICAST = [ { 'router': 'mx1.ams.nl.geant.net', 'oid': '1.3.6.1.2.1.83.1.1.2.1.16.232.223.222.1.193.17.9.3.255.255.255.255', # noqa: E501 'community': '0pBiFbD', 'subscription': '232.223.222.1', 'endpoint': '193.17.9.3' }, { 'router': 'mx1.ams.nl.geant.net', 'oid': '1.3.6.1.2.1.83.1.1.2.1.16.232.223.222.2.193.17.9.3.255.255.255.255', # noqa: E501 'community': '0pBiFbD', 'subscription': '232.223.222.2', 'endpoint': '193.17.9.3' }, { 'router': 'mx1.lon.uk.geant.net', 'oid': '1.3.6.1.2.1.83.1.1.2.1.16.232.223.222.1.193.17.9.3.255.255.255.255', # noqa: E501 'community': '0pBiFbD', 'subscription': '232.223.222.1', 'endpoint': '193.17.9.3' }, { 'router': 'mx1.lon.uk.geant.net', 'oid': '1.3.6.1.2.1.83.1.1.2.1.16.232.223.222.2.193.17.9.3.255.255.255.255', # noqa: E501 'community': '0pBiFbD', 'subscription': '232.223.222.2', 'endpoint': '193.17.9.3' }, { 'router': 'mx1.fra.de.geant.net', 'oid': '1.3.6.1.2.1.83.1.1.2.1.16.232.223.222.1.193.17.9.3.255.255.255.255', # noqa: E501 'community': '0pBiFbD', 'subscription': '232.223.222.1', 'endpoint': '193.17.9.3' }, { 'router': 'mx1.fra.de.geant.net', 'oid': '1.3.6.1.2.1.83.1.1.2.1.16.232.223.222.2.193.17.9.3.255.255.255.255', # noqa: E501 'community': '0pBiFbD', 'subscription': '232.223.222.2', 'endpoint': '193.17.9.3' } ] def generate_folder(data): return { "id": 555, "uid": data['uid'], "title": data['title'], "url": f"/dashboards/f/{data['uid']}/{data['title'].lower()}", "hasAcl": False, "canSave": True, "canEdit": True, "canAdmin": True, "createdBy": "Anonymous", "created": "2021-02-23T15:33:46Z", "updatedBy": "Anonymous", "updated": "2021-02-23T15:33:46Z", "version": 1 } @responses.activate def test_provision_folder(data_config, mocker): dashboards = { 'NREN': { 'tag': ['customers'], 'folder_name': 'NREN Access', 'interfaces': [ iface for iface in TEST_INTERFACES if 'NREN' in iface['dashboards']] }, 'RE_CUST': { 'tag': 'RE_CUST', 'folder_name': 'RE Customer', 'interfaces': [ iface for iface in TEST_INTERFACES if 'RE_CUST' in iface['dashboards']] }, } # just return a generated folder _mocked_find_folder = mocker.patch( 'brian_dashboard_manager.grafana.provision.find_folder') _mocked_find_folder.return_value = generate_folder( {'uid': 'testfolderuid', 'title': 'testfolder'}) def create_dashboard(request, dashboard, folder_id=None): return dashboard mocker.patch( 'brian_dashboard_manager.grafana.provision.create_dashboard', create_dashboard) excluded_dashboards = [] nren_result = provision_folder(None, 'testfolder', dashboards['NREN'], 'testdatasource', excluded_dashboards) assert len(nren_result) == 3 assert nren_result[0]['title'] == 'GEANT' assert nren_result[1]['title'] == 'KIAE' assert nren_result[2]['title'] == 'SWITCH' excluded_dashboards = ['SWITCH'] nren_excluded = provision_folder(None, 'testfolder', dashboards['NREN'], 'testdatasource', excluded_dashboards) assert len(nren_excluded) == 2 assert nren_excluded[0]['title'] == 'GEANT' assert nren_excluded[1]['title'] == 'KIAE' cust_result = provision_folder(None, 'testfolder', dashboards['RE_CUST'], 'testdatasource', ['GEANT']) assert len(cust_result) == 2 assert cust_result[0]['title'] == 'KIAE' assert cust_result[1]['title'] == 'SWITCH' @responses.activate def test_provision(data_config, mocker, client): responses.add( method=responses.GET, url=f"{data_config['inventory_provider']}/poller/interfaces", json=NREN_INTERFACES) responses.add( method=responses.GET, url=f"{data_config['inventory_provider']}/data/interfaces", json=NREN_INTERFACES) responses.add( method=responses.GET, url=f'{data_config["inventory_provider"]}/poller/eumetsat-multicast', json=EUMETSAT_MULTICAST) responses.add( method=responses.DELETE, url=f"http://{data_config['hostname']}/api/folders", json={"message": "Deleted folder"}) responses.add( method=responses.GET, url=f"http://{data_config['hostname']}/api/folders", json=[]) responses.add( method='get', url=f"http://{data_config['hostname']}/api/folders", json=[]) def folder_post(request): data = json.loads(request.body) return 200, {}, json.dumps(generate_folder(data)) responses.add_callback( method=responses.POST, url=f"http://{data_config['hostname']}/api/folders", callback=folder_post) def search_responses(request): if request.params.get('query', None) == 'Home': return 200, {}, json.dumps([]) if request.params.get('type', None) == 'dash-db': return 200, {}, json.dumps([]) assert False # no other queries expected responses.add_callback( method=responses.GET, url=f"http://{data_config['hostname']}/api/search", callback=search_responses) responses.add( method=responses.GET, url=f"http://{data_config['hostname']}/api/datasources", json=[{ "name": "brian-influx-datasource", "type": "influxdb", "access": "proxy", "url": "http://test-brian-datasource.geant.org:8086", "database": "test-db", "basicAuth": False, "isDefault": True, "readOnly": False }]) responses.add( method=responses.POST, url=f"http://{data_config['hostname']}/api/dashboards/db", json={'uid': '999', 'id': 666}) responses.add( method=responses.PUT, url=f"http://{data_config['hostname']}/api/org/preferences", json={'message': 'Preferences updated'}) def homedashboard(request): return 404, {}, '' responses.add_callback( method=responses.GET, url=f"http://{data_config['hostname']}/api/dashboards/uid/home", callback=homedashboard) PROVISIONED_ORGANIZATION = { 'name': data_config['organizations'][0], 'id': 0 } EXISTING_ORGS = [{**org, 'id': i + 1} for i, org in enumerate(data_config['organizations'][1:])] _mocked_get_organizations = mocker.patch( 'brian_dashboard_manager.grafana.provision.get_organizations') # all organizations are provisioned except the first one. _mocked_get_organizations.return_value = EXISTING_ORGS.copy() _mocked_create_organization = mocker.patch( 'brian_dashboard_manager.grafana.provision.create_organization') # spoof creating first organization _mocked_create_organization.return_value = PROVISIONED_ORGANIZATION _mocked_delete_expired_api_tokens = mocker.patch( 'brian_dashboard_manager.grafana.provision.delete_expired_api_tokens') # we dont care about this, , tested separately _mocked_delete_expired_api_tokens.return_value = None _mocked_create_api_token = mocker.patch( 'brian_dashboard_manager.grafana.provision.create_api_token') _mocked_create_api_token.return_value = { 'key': 'testtoken', 'id': 0} # api token _mocked_create_datasource = mocker.patch( 'brian_dashboard_manager.grafana.provision.create_datasource') # we dont care about this, just mark it created _mocked_create_datasource.return_value = True _mocked_get_dashboard_definitions = mocker.patch( 'brian_dashboard_manager.grafana.provision.get_dashboard_definitions') _mocked_gws = mocker.patch( 'brian_dashboard_manager.grafana.provision.get_gws_direct') _mocked_gws.return_value = [] _mocked_gws_indirect = mocker.patch( 'brian_dashboard_manager.grafana.provision.get_gws_indirect') _mocked_gws_indirect.return_value = [] UID = 1 ID = 1 VERSION = 1 TITLE = 'testdashboard' dashboard = {'id': ID, 'uid': UID, 'title': TITLE, 'version': VERSION} _mocked_get_dashboard_definitions.return_value = [ dashboard # test dashboard ] _mocked_create_dashboard = mocker.patch( 'brian_dashboard_manager.grafana.provision.create_dashboard') # we dont care about this, just mark it created # we dont care about this, tested separately _mocked_create_dashboard.return_value = {'uid': '999', 'id': 666} _mocked_delete_api_token = mocker.patch( 'brian_dashboard_manager.grafana.provision.delete_api_token') # we dont care about this, tested separately _mocked_delete_api_token.return_value = None provision(data_config)