From 531ec25468a754ab37a4802f28c63fe689d8238f Mon Sep 17 00:00:00 2001
From: Bjarke Madsen <bjarke.madsen@geant.org>
Date: Mon, 13 Sep 2021 15:46:09 +0200
Subject: [PATCH] Add ignored_folders config option for provisioning manually
 maintained folders

---
 brian_dashboard_manager/grafana/dashboard.py | 25 +++++++++++++++-----
 brian_dashboard_manager/grafana/provision.py | 25 +++++++++++++++++++-
 2 files changed, 43 insertions(+), 7 deletions(-)

diff --git a/brian_dashboard_manager/grafana/dashboard.py b/brian_dashboard_manager/grafana/dashboard.py
index 012ccad..e7b856d 100644
--- a/brian_dashboard_manager/grafana/dashboard.py
+++ b/brian_dashboard_manager/grafana/dashboard.py
@@ -73,6 +73,18 @@ def delete_dashboards(request: TokenRequest):
     return True
 
 
+# lists all dashboards, optionally within a folder
+def list_dashboards(request: TokenRequest, folder_id=None):
+    params = {
+        'query': ''
+    }
+    if folder_id is not None:
+        params['folderIds'] = folder_id
+
+    r = request.get('api/search', params=params)
+    return r
+
+
 # Searches for a dashboard with given title
 def find_dashboard(request: TokenRequest, title=None):
     param = {
@@ -102,16 +114,17 @@ def find_dashboard(request: TokenRequest, title=None):
 # matching the title of the provided dashboard.
 def _search_dashboard(request: TokenRequest, dashboard: Dict, folder_id=None):
     try:
-        r = request.get('api/search', params={
+        params = {
             'query': dashboard["title"]
-        })
+        }
+        if folder_id is not None:
+            params['folderIds'] = folder_id
+
+        r = request.get('api/search', params=params)
         if r and isinstance(r, list):
             if len(r) >= 1:
                 for dash in r:
-                    if folder_id:
-                        if folder_id != dash.get('folderId'):
-                            continue
-                    if dash['title'] == dashboard['title']:
+                    if dash['title'].lower() == dashboard['title'].lower():
                         definition = _get_dashboard(request, dash['uid'])
                         return definition
         return None
diff --git a/brian_dashboard_manager/grafana/provision.py b/brian_dashboard_manager/grafana/provision.py
index 8a70538..bccb7e9 100644
--- a/brian_dashboard_manager/grafana/provision.py
+++ b/brian_dashboard_manager/grafana/provision.py
@@ -18,7 +18,8 @@ from brian_dashboard_manager.grafana.organization import \
     get_organizations, create_organization, create_api_token, \
     delete_api_token, delete_expired_api_tokens, set_home_dashboard
 from brian_dashboard_manager.grafana.dashboard import find_dashboard, \
-    get_dashboard_definitions, create_dashboard, delete_dashboard
+    get_dashboard_definitions, create_dashboard, delete_dashboard, \
+    list_dashboards
 from brian_dashboard_manager.grafana.datasource import \
     check_provisioned, create_datasource
 from brian_dashboard_manager.grafana.folder import find_folder, \
@@ -45,10 +46,21 @@ def provision_folder(token_request, folder_name, dash,
     Function to provision dashboards within a folder.
     """
 
+    def _check_valid(interface):
+        return interface['dashboard_info']['name'] != ''
+
     folder = find_folder(token_request, folder_name)
     tag = dash['tag']
     interfaces = dash['interfaces']
 
+    empty_names = [iface for iface in interfaces if not _check_valid(iface)]
+
+    if any(empty_names):
+        for iface in empty_names:
+            logger.info('Invalid dashboard name on interface:')
+            logger.info(json.dumps(iface, indent=2))
+        interfaces = list(filter(_check_valid, interfaces))
+
     # dashboard should include error panels
     errors = dash.get('errors', False)
 
@@ -122,6 +134,7 @@ def provision(config):
     all_orgs = get_organizations(request)
 
     orgs_to_provision = config.get('organizations', DEFAULT_ORGANIZATIONS)
+    ignored_folders = config.get('ignored_folders', [])
 
     missing = (org['name'] for org in orgs_to_provision
                if org['name'] not in [org['name'] for org in all_orgs])
@@ -444,6 +457,16 @@ def provision(config):
         # just hardcode that we updated home dashboard
         updated['home'] = True
 
+        # get dashboard UIDs from ignored folders
+        # and make sure we don't touch them
+        for name in ignored_folders:
+            folder = find_folder(request, name)
+            to_ignore = list_dashboards(request, folder['id'])
+
+            for dash in to_ignore:
+                # mark it updated, so we don't modify it.
+                updated[dash['uid']] = True
+
         for dash, provisioned in updated.items():
             if not provisioned:
                 logger.info(f'Deleting stale dashboard with UID {dash}')
-- 
GitLab