Skip to content
Snippets Groups Projects
Commit 1466c212 authored by Bjarke Madsen's avatar Bjarke Madsen
Browse files

Only be dependent on grafana hostname

Use datasource-specific config instead of environment config
Add influxdb datasource config
Remove unused config keys
parent 1a1849a5
No related branches found
No related tags found
No related merge requests found
......@@ -4,24 +4,55 @@ import jsonschema
CONFIG_SCHEMA = {
"$schema": "http://json-schema.org/draft-07/schema#",
"definitions": {
"influx-datasource": {
"type": "object",
"properties": {
"name": {"type": "string"},
"username": {"type": "string"},
"password": {"type": "string"},
"type": {"type": "string"},
"url": {"type": "string"},
"database": {"type": "string"},
"basicAuth": {"type": "boolean"},
"access": {"type": "string"},
"isDefault": {"type": "boolean"},
"readOnly": {"type": "boolean"}
},
"required": [
"name",
"type",
"url",
"database",
"basicAuth",
"access",
"isDefault",
"readOnly"
]
}
},
"type": "object",
"properties": {
"admin_username": {"type": "string"},
"admin_password": {"type": "string"},
"hostname": {"type": "string"},
"listen_port": {"type": "integer"},
"grafana_port": {"type": "integer"},
"organizations": {"type": "array", "items": {"type": "string"}},
"BRIAN_ENVIRONMENT": {"type": "string"}
"datasources": {
"type": "object",
"properties": {
"influxdb": {"$ref": "#definitions/influx-datasource"}
},
"additionalProperties": False
},
},
"required": [
"admin_username",
"admin_password",
"hostname",
"listen_port",
"grafana_port",
"organizations",
"BRIAN_ENVIRONMENT"
"datasources"
],
"additionalProperties": False
}
......@@ -31,11 +62,10 @@ def defaults():
return {
"admin_username": "admin",
"admin_password": "admin",
"hostname": "localhost",
"hostname": "localhost:3000",
"listen_port": 3001,
"grafana_port": 3000,
"organizations": ["Main Org."],
"BRIAN_ENVIRONMENT": "test"
"datasources": {}
}
......
......@@ -74,10 +74,21 @@ def _get_dashboard(request: TokenRequest, uid: int):
# supplied dashboards are JSON blobs exported from GUI with a UID.
def create_dashboard(request: TokenRequest, dashboard: Dict):
title = dashboard['title']
existing_dashboard = None
if dashboard.get('uid') is not 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
else:
different = False
if existing_dashboard is None or different:
existing_dashboard = _search_dashboard(request, dashboard)
if existing_dashboard:
......@@ -92,7 +103,6 @@ def create_dashboard(request: TokenRequest, dashboard: Dict):
'dashboard': dashboard,
'overwrite': False
}
title = dashboard["title"]
try:
action = "Updating" if existing_dashboard else "Provisioning"
logger.info(f'{action} dashboard: {title}')
......
import logging
import re
import os
import json
from typing import Dict
......@@ -44,10 +43,17 @@ def get_datasources(request: Request):
return request.get('api/datasources')
def create_datasource(request: TokenRequest, datasource: Dict, environment):
def create_datasource(request: TokenRequest, datasource: Dict, datasources):
try:
datasource["url"] = re.sub(
'test|uat|prod', environment, datasource["url"])
ds_type = datasource["type"]
# find out which params
# we need to configure for this datasource type
config = datasources.get(ds_type, None)
if config is None:
logger.exception(
f'No datasource config could be found for {ds_type}')
return None
datasource.update(config)
r = request.post('api/datasources', json=datasource)
except HTTPError:
logger.exception('Error when provisioning datasource')
......
......@@ -43,11 +43,13 @@ def provision(config):
# Provision missing data sources
for datasource in get_missing_datasource_definitions(token_request):
ds = create_datasource(token_request,
datasource,
config.get('BRIAN_ENVIRONMENT', 'test'))
if ds:
logger.info(f'Provisioned datasource: {datasource["name"]}')
if datasource:
ds = create_datasource(token_request,
datasource,
config.get('datasources'))
if ds:
logger.info(
f'Provisioned datasource: {datasource["name"]}')
# Provision dashboards, overwriting existing ones.
for dashboard in get_dashboard_definitions():
......
......@@ -53,10 +53,10 @@ class Request(object):
class AdminRequest(Request):
def __init__(self, hostname, grafana_port, admin_username, admin_password,
def __init__(self, hostname, admin_username, admin_password,
**kwargs):
self.username = admin_username
url = f'{admin_username}:{admin_password}@{hostname}:{grafana_port}/'
url = f'{admin_username}:{admin_password}@{hostname}/'
super().__init__('http://' + url)
def __str__(self):
......@@ -64,10 +64,10 @@ class AdminRequest(Request):
class TokenRequest(Request):
def __init__(self, hostname, grafana_port, token: str, **kwargs):
def __init__(self, hostname, token: str, **kwargs):
self.token = token
super().__init__(f'http://{hostname}:{grafana_port}/', {
super().__init__(f'http://{hostname}/', {
'Authorization': 'Bearer ' + token
})
......
......@@ -8,18 +8,27 @@ import brian_dashboard_manager
@pytest.fixture
def data_config():
return {
"admin_username": "admin",
"admin_password": "admin",
"hostname": "localhost",
"listen_port": 65001,
"grafana_port": 65005,
"admin_username": "fakeadmin",
"admin_password": "fakeadmin",
"hostname": "myfakehostname.org",
"organizations": [
'Testorg1',
'GÉANT Testorg2',
'NRENsTestorg3',
'General Public'
],
"BRIAN_ENVIRONMENT": "test"
"datasources": {
"influxdb": {
"name": "PollerInfluxDB",
"type": "influxdb",
"access": "proxy",
"url": "http://prod-poller-ui01.geant.org:8086",
"database": "poller",
"basicAuth": False,
"isDefault": True,
"readOnly": False
}
}
}
......
......@@ -79,9 +79,6 @@ def test_create_prod_datasource(data_config):
def post_callback(request):
body = json.loads(request.body)
# we are testing provisioning logic to prod, so the URL needs test ->
# prod translation.
assert body['url'] == 'http://prod-brian-datasource.geant.org:8086'
result = {
'datasource': {
'id': 1,
......@@ -109,9 +106,12 @@ def test_create_prod_datasource(data_config):
url=request.BASE_URL + 'api/datasources',
callback=post_callback)
data = provision.create_datasource(request, BODY, environment='prod')
data = provision.create_datasource(
request, BODY, datasources=data_config['datasources'])
assert data is not None
datasource_type = data['datasource']['type']
datasource_config_url = data_config['datasources'][datasource_type]['url']
assert data['datasource']['url'] == datasource_config_url
@responses.activate
......@@ -134,7 +134,8 @@ def test_create_prod_datasource_fails(data_config):
url=request.BASE_URL + 'api/datasources',
callback=lambda f: (400, {}, ''))
data = provision.create_datasource(request, BODY, environment='prod')
data = provision.create_datasource(
request, BODY, datasources=data_config['datasources'])
# if an error occured when provisioning a datasource, we log the response
# but return None
......
......@@ -11,7 +11,7 @@ from brian_dashboard_manager.grafana.utils.request import \
def test_admin_request(data_config):
ENDPOINT = 'test/url/endpoint'
request = AdminRequest(**data_config)
url = '{admin_username}:{admin_password}@{hostname}:{grafana_port}/'. \
url = '{admin_username}:{admin_password}@{hostname}/'. \
format(**data_config)
assert request.BASE_URL == 'http://' + url
assert request.username == data_config['admin_username']
......@@ -33,7 +33,7 @@ def test_token_request(data_config):
TOKEN = '123'
ENDPOINT = 'test/url/endpoint'
request = TokenRequest(**data_config, token=TOKEN)
assert request.BASE_URL == 'http://{hostname}:{grafana_port}/'.format(
assert request.BASE_URL == 'http://{hostname}/'.format(
**data_config)
assert request.token == TOKEN
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment