gfdatasource, but in Python

This commit is contained in:
Jonathan Lange 2016-12-09 19:18:27 +00:00
parent a06f911ab9
commit bb04913b01
3 changed files with 132 additions and 0 deletions

8
gfdatasource/Dockerfile Normal file
View File

@ -0,0 +1,8 @@
FROM alpine:3.4
LABEL works.weave.role=system
RUN apk update && apk upgrade && apk add python3
RUN python3 -m ensurepip && pip3 install --upgrade pip
COPY requirements.txt /
RUN pip3 install -r requirements.txt
COPY gfdatasource /
ENTRYPOINT ["/gfdatasource"]

122
gfdatasource/gfdatasource Executable file
View File

@ -0,0 +1,122 @@
#!/usr/bin/env python3
"""Tools for maintaining Grafana datasources."""
import argparse
import attr
import requests
import sys
from urllib.parse import ParseResult, urlparse
@attr.s
class BasicAuthCredentials(object):
username = attr.ib()
password = attr.ib()
def to_json_dict(self):
return {
'basicAuth': True,
'basicAuthUser': self.username,
'basicAuthPassword': self.password
}
@attr.s
class DataSource(object):
"""A data source for Grafana."""
name = attr.ib()
type = attr.ib()
url = attr.ib()
access = attr.ib()
credentials = attr.ib()
def to_json_dict(self):
data = {
'name': self.name,
'type': self.type,
'url': self.url,
'access': self.access,
}
if self.credentials:
data.update(self.credentials)
return data
@attr.s
class GrafanaAPI(object):
"""HTTP client for Grafana's API."""
base_url = attr.ib()
credentials = attr.ib()
def _get_session(self):
if not self.credentials:
return requests.Session()
return requests.Session(
auth=(self.credentials.username, self.credentials.password))
def update_datasource(self, data_source):
return self._get_session().post(
'/'.join([self.base_url, 'datasource']),
json=data_source.to_json_dict())
def make_parser():
parser = argparse.ArgumentParser(prog='gfdatasource')
parser.add_argument(
'--grafana-url', type=urlparse,
default='http',
help="URL of Grafana API",
)
parser.add_argument(
'--data-source-url', type=urlparse,
help="URL of data source",
)
parser.add_argument(
'--access', type=str, default='proxy',
help="Type of access used by Grafana to the data source",
)
parser.add_argument(
'--type', type=str, default='prometheus',
help="The type of data source",
)
parser.add_argument(
'--name', type=str, default='Prometheus',
help="The name of the data source",
)
parser.add_argument(
'--update-interval', type=int, default=10,
help="How frequently to update Grafana, in seconds",
)
return parser
def _split_creds(url):
creds = BasicAuthCredentials(url.username, url.password)
netloc = url.netloc.split('@')[1] if '@' in url.netloc else url.netloc
url = ParseResult(
scheme=url.scheme,
netloc=netloc,
path=url.path,
params=url.params,
query=url.query,
fragment=url.fragment,
)
return url, creds
def main():
parser = make_parser()
opts = parser.parse_args(sys.argv[1:])
grafana_url, grafana_creds = _split_creds(opts.grafana_url)
grafana_api = GrafanaAPI(base_url=grafana_url, credentials=grafana_creds)
datasource_url, datasource_creds = _split_creds(opts.data_source_url)
datasource = DataSource(base_url=datasource_url, credentials=datasource_creds)
while True:
grafana_api.update_datasource(datasource)
time.sleep(opts.update_interval)
main()

View File

@ -0,0 +1,2 @@
attrs==16.3.0
requests==2.12.3