Newer
Older
"""
Grafana Dashhboard API endpoints wrapper functions.
"""
from brian_dashboard_manager.grafana.utils.request import TokenRequest
logger = logging.getLogger(__name__)
# Returns dictionary for each dashboard JSON definition in supplied directory
def get_dashboard_definitions(dir=None): # pragma: no cover
dashboard_dir = dir or os.path.join(
os.path.dirname(__file__), '../dashboards/')
for (dirpath, _, filenames) in os.walk(dashboard_dir):
for file in filenames:
if file.endswith('.json'):
filename = os.path.join(dirpath, file)
dashboard = json.load(open(filename, 'r'))
yield dashboard
def delete_dashboard(request: TokenRequest, dashboard, folder_id=None):
try:
r = None
uid = dashboard.get('uid')
if uid:
return _delete_dashboard(request, uid)
elif dashboard.get('title'):
# if a folder ID is not supplied,
# dashboard title should be globally unique
dash = _search_dashboard(request, dashboard, folder_id)
if dash is None:
return True
_delete_dashboard(request, dash.get(
'dashboard', {}).get('uid', ''))
logger.info(f'Deleted dashboard: {dashboard.get("title")}')
return r is not None
except HTTPError:
dump = json.dumps(dashboard, indent=2)
logger.exception(
f'Error when deleting dashboard:\n{dump}')
return None
# Deletes a single dashboard for the organization
# the API token is registered to.
def _delete_dashboard(request: TokenRequest, uid: int):
try:
r = request.delete(f'api/dashboards/uid/{uid}')
if r and 'deleted' in r.get('message', ''):
return True
except HTTPError as e:
if e.response is not None and e.response.status_code == 404:
return True
logger.exception(f'Error when deleting dashboard with UID #{uid}')
# Deletes all dashboards for the organization
# the API token is registered to.
def delete_dashboards(request: TokenRequest):
r = request.get('api/search')
if r and len(r) > 0:
for dash in r:
_delete_dashboard(request, dash['uid'])
return True
Bjarke Madsen
committed
# 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 = {
**({'query': title} if title else {}),
'type': 'dash-db',
'limit': 5000,
'page': 1
}
r = request.get('api/search', params=param)
if title:
return r[0]
else:
while True:
param['page'] += 1
page = request.get('api/search', params=param)
if len(page) > 0:
r.extend(page)
else:
break
return r
# Searches Grafana for a dashboard
# matching the title of the provided dashboard.
def _search_dashboard(request: TokenRequest, dashboard: Dict, folder_id=None):
Bjarke Madsen
committed
params = {
'query': dashboard["title"]
Bjarke Madsen
committed
}
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 dash['title'] == dashboard['title']:
definition = _get_dashboard(request, dash['uid'])
return definition
return None
except HTTPError:
return None
# Fetches dashboard with given UID for the token's organization.
def _get_dashboard(request: TokenRequest, uid: int):
try:
r = request.get(f'api/dashboards/uid/{uid}')
except HTTPError:
return None
return r
# Creates or updates (if exists) given dashboard for the token's organization.
# supplied dashboards are JSON blobs exported from GUI with a UID.
def create_dashboard(request: TokenRequest, dashboard: Dict, folder_id=None):
has_uid = dashboard.get('uid') is not None
if has_uid:
existing_dashboard = _get_dashboard(request, uid=dashboard['uid'])
# The title might not match the one that's provisioned with that UID.
# Try to find it by searching for the title instead.
if existing_dashboard is not None:
grafana_title = existing_dashboard['dashboard']['title']
different = grafana_title != title
different = False
if existing_dashboard is None or different:
existing_dashboard = _search_dashboard(request, dashboard, folder_id)
if existing_dashboard:
dashboard['uid'] = existing_dashboard['dashboard']['uid']
dashboard['id'] = existing_dashboard['dashboard']['id']
dashboard['version'] = existing_dashboard['dashboard']['version']
else:
# We are creating a new dashboard, delete ID if it exists.
del dashboard['id']
payload = {
'dashboard': dashboard,
'overwrite': False
}
if folder_id:
payload['folderId'] = folder_id
# action = "Updating" if existing_dashboard else "Creating"
# logger.info(f'{action} dashboard: {title}')
r = request.post('api/dashboards/db', json=payload)
except HTTPError:
logger.exception(f'Error when provisioning dashboard {title}')