def __init__(self, cConfigIP, bLogToDefaultOutputIP=False): self.tConfig = json.loads(open(cConfigIP).read(), object_pairs_hook=dict) for cDir in (self.tConfig['logdir'], self.tConfig['workdir']): if not os.path.exists(cDir): os.makedirs(cDir) cLogfile = os.path.join( self.tConfig['logdir'], '{}_{}.log'.format(self.tConfig['logfile'], datetime.now().strftime('%Y-%m-%d'))) self.oLog = logging.getLogger(cLogfile) oLogFormatter = logging.Formatter( '[%(asctime)s] [%(process)s] [%(levelname)s] %(message)s') hLogfileHandler = logging.FileHandler(cLogfile) hLogfileHandler.setFormatter(oLogFormatter) self.oLog.hLogfileHandler = hLogfileHandler self.oLog.addHandler(hLogfileHandler) self.oLog.setLevel(logging.INFO) if self.tConfig['log_tee_stdout']: oConsole = logging.StreamHandler(stream=sys.stdout) oConsole.setFormatter(oLogFormatter) oConsole.setLevel(logging.INFO) self.oLog.addHandler(oConsole) self.oGrafanaClient = GrafanaClient( (self.tConfig['grafana_user'], self.tConfig['grafana_password']), host=self.tConfig['grafana_host'], port=self.tConfig['grafana_port'])
def test_auth(self): gc = GrafanaClient("test") self.assertEquals(gc.api_key, "test") self.assertEquals(gc.authentication_method, GrafanaClient.AUTHENTICATE_WITH_API_KEY) gc = GrafanaClient(("test", "test")) self.assertEquals(gc.login, "test") self.assertEquals(gc.password, "test") self.assertEquals(gc.authentication_method, GrafanaClient.AUTHENTICATE_WITH_LOGIN_CREDENTIALS)
def test_create_apikey(self): gc = GrafanaClient(("admin", "admin"), os.getenv("DOCKER_HOST"), 3000) keys = gc.auth.keys.get() self.assertEqual(keys, []) created = gc.auth.keys.create(name="test-key", role="Admin") self.assertIsInstance(created, dict) gc = GrafanaClient(created["key"], os.getenv("DOCKER_HOST"), 3000) org = gc.org.get() self.assertEqual(org["name"], "Main Org.")
class c_msmetrics_grafana_pause_all_notifications_xu(object): ''' Pause or unpause all Grafana notifications, main class ''' def __init__(self, cConfigIP, bLogToDefaultOutputIP=False): self.tConfig = json.loads(open(cConfigIP).read(), object_pairs_hook=dict) for cDir in (self.tConfig['logdir'], self.tConfig['workdir']): if not os.path.exists(cDir): os.makedirs(cDir) cLogfile = os.path.join( self.tConfig['logdir'], '{}_{}.log'.format(self.tConfig['logfile'], datetime.now().strftime('%Y-%m-%d'))) self.oLog = logging.getLogger(cLogfile) oLogFormatter = logging.Formatter( '[%(asctime)s] [%(process)s] [%(levelname)s] %(message)s') hLogfileHandler = logging.FileHandler(cLogfile) hLogfileHandler.setFormatter(oLogFormatter) self.oLog.hLogfileHandler = hLogfileHandler self.oLog.addHandler(hLogfileHandler) self.oLog.setLevel(logging.INFO) if self.tConfig['log_tee_stdout']: oConsole = logging.StreamHandler(stream=sys.stdout) oConsole.setFormatter(oLogFormatter) oConsole.setLevel(logging.INFO) self.oLog.addHandler(oConsole) self.oGrafanaClient = GrafanaClient( (self.tConfig['grafana_user'], self.tConfig['grafana_password']), host=self.tConfig['grafana_host'], port=self.tConfig['grafana_port']) def ClientStart(self): self.oLog.info( 'Started client c_msmetrics_grafana_pause_all_notifications_xu.') self.PauseNotifications(sys.argv[2] == 'pause') def PauseNotifications(self, bPauseIP=True): tAlerts = self.oGrafanaClient.alerts() if self.tConfig['verbose_logging'] and not bPauseIP: self.oLog.info('pause_but_no_unpause: "{}"'.format( self.tConfig['pause_but_no_unpause'])) for tAlert in tAlerts: if (not bPauseIP) and re.match( pattern=self.tConfig['pause_but_no_unpause'], string=tAlert['name']): if self.tConfig['verbose_logging']: self.oLog.info('Skipping unpause of "{}"'.format( tAlert['name'])) continue iAlertId = tAlert['id'] if self.tConfig['verbose_logging']: self.oLog.info('{:<10}id={:<10}{:<40}{:<40}{}'.format( 'Pausing:' if bPauseIP else 'Unpausing:', iAlertId, tAlert['name'], tAlert['dashboardUri'], tAlert['state'])) tResponse = self.oGrafanaClient.alerts[iAlertId].pause.create( paused=bPauseIP) if self.tConfig['verbose_logging']: self.oLog.info('{}'.format(repr(tResponse)))
def test_construct_api_url(self): gc = GrafanaClient("test", "a", 1000, "b", "https") self.assertEqual(gc.construct_api_url("c"), "https://a:1000/b/api/c") gc = GrafanaClient("test") self.assertEqual(gc.construct_api_url("a"), "http://127.0.0.1/api/a") self.assertEqual(repr(gc), "<GrafanaApiClient at 'http://127.0.0.1/api/'>")
def main(): """Perform a basic configuration of the local Grafana Server.""" parser = argparse.ArgumentParser(description=__doc__) parser.add_argument('-u', '--user', default='root', nargs='?') parser.add_argument('-c', '--current_password', default='admin') parser.add_argument('-p', '--new_password') args = parser.parse_args() client = GrafanaClient(('admin', args.current_password), host='127.0.0.1', port=3000) payload = { 'name': 'mysql-default', 'isDefault': True, 'type': 'mysql', 'url': 'localhost:3306', 'user': args.user, 'password': args.new_password, 'database': 'flash_stache', 'access': 'proxy' } try: result = client.datasources.create(**payload)['message'] except (GrafanaClientError, GrafanaUnauthorizedError) as error: result = 'Failed to add the default datasource.\n{}'.format(error) print result # Update the admin password: pass_payload = { 'oldPassword': args.current_password, 'newPassword': args.new_password, 'confirmNew': args.new_password, } try: result = client.make_raw_request('PUT', 'user/password', pass_payload)['message'] except (GrafanaClientError, GrafanaUnauthorizedError) as error: result = 'Failed to update the password for the Grafana admin user.\n{}'.format( error) print result
def test_create_dashboard(self): """Create new dashboard""" gc = GrafanaClient(None, os.getenv("DOCKER_HOST"), 3001) dashboard = gc.dashboards.db.create(dashboard={ "id": None, "title": "Test Dashboard", "tags": ["test"], "timezone": "browser", "rows": [] }, overwrite=False) self.assertEqual(dashboard["slug"], "test-dashboard") dashboard = gc.dashboards.db["test-dashboard"].get() self.assertIsInstance(dashboard, dict) self.assertEqual(dashboard["dashboard"]["title"], "Test Dashboard")
def test_create_datasource(self): """Create Data Source""" gc = GrafanaClient(None, os.getenv("DOCKER_HOST"), 3001) dss = gc.datasources.get() self.assertEqual(dss, []) created = gc.datasources.create(name="test-datasource", type="graphite", url="http://localhost", access="proxy", basicAuth=False) self.assertIsInstance(created, dict) byid = gc.datasources[created["id"]].get() self.assertEqual(byid["name"], "test-datasource") byname = gc.datasources.name["test-datasource"].get() self.assertEqual(byname["id"], created["id"]) response = gc.datasources.name["test-datasource"].delete() self.assertDictEqual(response, {"message": "Data source deleted"}) dss = gc.datasources.get() self.assertEqual(dss, [])
def test_construct_api_url(self): gc = GrafanaClient("test", "a", 1000, "b", "https") self.assertEquals(gc.construct_api_url("c"), "https://a:1000/b/api/c") gc = GrafanaClient("test") self.assertEquals(gc.construct_api_url("a"), "http://127.0.0.1/api/a") self.assertEquals(repr(gc), "<GrafanaApiClient at 'http://127.0.0.1/api/'>")
def get_client(self): return GrafanaClient( (self.settings.grafana_username, self.settings.grafana_password), host='localhost', port=3000)
def test_token_auth(self): gc = GrafanaClient("api_key") self.assertEqual(gc.session.auth.token, "api_key")
def test_basic_auth(self): gc = GrafanaClient(("login", "password")) self.assertEqual(gc.session.auth.username, "login") self.assertEqual(gc.session.auth.password, "password")
def test_login(self): gc = GrafanaClient(("admin", "admin"), os.getenv("DOCKER_HOST"), 3000) org = gc.org.get() self.assertEqual(org["name"], "Main Org.")
def __init__(self, server): self.client = GrafanaClient(app.config['GRAFANA_KEY'], host=app.config['GRAFANA_HOST']) self.server = server
def test_home_dashboard(self): """Get home dashboard""" gc = GrafanaClient(None, os.getenv("DOCKER_HOST"), 3001) dashboard = gc.dashboards.home.get() self.assertIsInstance(dashboard, dict)
def connect(self): self.grafana_client = GrafanaClient((self.username, self.password), host=self.host, port=self.port) try: self.ensure_instant_folder() except Exception as ex: log.warn(u'Problem creating instant folder: {ex}', ex=ex)
class GrafanaApi(object): """ A small wrapper around ``grafana_api_client``. https://pypi.python.org/pypi/grafana_api_client """ def __init__(self, host='localhost', port=3000, username='******', password='******'): self.host = host self.port = port self.username = username self.password = password # A GrafanaClient instance self.grafana_client = None # The uid of the "Instant Dashboards" folder self.instant_folder_uid = u'instagraf' self.instant_folder_title = u'# Instant Dashboards' self.connect() def connect(self): self.grafana_client = GrafanaClient((self.username, self.password), host=self.host, port=self.port) try: self.ensure_instant_folder() except Exception as ex: log.warn(u'Problem creating instant folder: {ex}', ex=ex) def ensure_instant_folder(self): return self.ensure_folder(uid=self.instant_folder_uid, title=self.instant_folder_title) def ensure_folder(self, uid=None, title=None): try: return self.get_folder(uid=uid) except GrafanaClientError as ex: if '404' in ex.message or 'not-found' in ex.message or 'Folder not found' in ex.message: log.debug(u'Folder with uid="{uid}" not found, creating', uid=uid) try: return self.create_folder(uid=uid, title=title) except Exception as ex: log.warn(u'Problem creating folder uid="{uid}", title="{title}": {ex}', uid=uid, title=title, ex=ex) else: log.warn(u'Problem getting folder uid="{uid}"": {ex}', uid=uid, ex=ex) raise def create_folder(self, uid=None, title=None): log.info(u'Creating folder with uid="{uid}" and title="{title}"', uid=uid, title=title) data = {} if uid: data['uid'] = uid if title: data['title'] = title try: return self.grafana_client.folders.create(**data) except GrafanaPreconditionFailedError as ex: # Ignore modifications from other users while doing our own # TODO: Add some locking mechanisms to protect against these issues if 'version-mismatch' in ex.message or 'The folder has been changed by someone else' in ex.message: #log.warn('{message}', message=ex.message) pass else: raise def get_folder(self, uid): log.info('Get folder with uid="{}"'.format(uid)) data = self.grafana_client.folders[uid].get() return data def create_datasource(self, name=None, data=None): data = data or {} data.setdefault('name', name) data.setdefault('access', 'proxy') name = data['name'] # TODO: can delete by datasource "id" only. have to inquire using "GET /api/datasources" first """ try: logger.info('deleting datasource: {}'.format(name)) response = self.grafana_client.datasources[name].delete() print response except GrafanaClientError as ex: if '404' in ex.message or 'Dashboard not found' in ex.message: logger.warn(slm(ex.message)) else: raise """ try: log.info(u'Checking/Creating datasource "{}"'.format(name)) response = self.grafana_client.datasources.create(**data) log.info('response: {response}', response=response) except GrafanaServerError as ex: if 'Failed to add datasource' in ex.message: pass else: raise except GrafanaClientError as ex: if 'Data source with same name already exists' in ex.message: pass else: raise #print grafana.datasources() def create_dashboard(self, dashboard, name=None, delete=False): if not name: name = dashboard.get_title() name = self.format_dashboard_name(name) if delete: try: log.info(u'Deleting dashboard "{}"'.format(name)) response = self.grafana_client.dashboards.db[name].delete() log.info(u'Grafana response: {response}', response=response) except GrafanaClientError as ex: if '404' in ex.message or 'Dashboard not found' in ex.message: log.warn(u'{message}', message=ex.message) else: raise try: log.info(u'Creating/updating dashboard "{}"'.format(name)) dashboard_payload = dashboard.wrap_api() response = self.grafana_client.dashboards.db.create(**dashboard_payload) log.info(u'Grafana response: {response}', response=response) except GrafanaPreconditionFailedError as ex: if 'name-exists' in ex.message or 'A dashboard with the same name already exists' in ex.message: log.warn(u'{message}', message=ex.message) else: raise try: log.info(u'Checking dashboard "{}"'.format(name)) dashboard = self.grafana_client.dashboards.db[name].get() except GrafanaClientError as ex: if '404' in ex.message or 'Dashboard not found' in ex.message: log.warn(u'{message}', message=ex.message) else: raise def get_dashboard(self, name): try: name = self.format_dashboard_name(name) log.info(u'Getting dashboard "{}"'.format(name)) dashboard = self.grafana_client.dashboards.db[name].get() return dashboard['dashboard'] except GrafanaClientError as ex: if '404' in ex.message or 'Dashboard not found' in ex.message: log.info(u'{message}', message=ex.message) else: raise def get_dashboard_by_uid(self, uid): """ Will return the dashboard given the dashboard unique identifier (uid). http://docs.grafana.org/http_api/dashboard/#get-dashboard-by-uid :param uid: Unique dashboard identifier (uid) :return: Dashboard data structure as dictionary """ return self.grafana_client.dashboards.uid[uid].get() def format_dashboard_name(self, name): return name.replace(' ', '-') def demo(self): print grafana.org() # {"id":1,"name":"Main Org."} #client.org.replace(name="Your Org Ltd.") # {"id":1,"name":"Your Org Ltd."} def get_dashboards(self): return self.grafana_client.search(type='dash-db')
def test_unauthorized(self): gc = GrafanaClient(None, os.getenv("DOCKER_HOST"), 3000) with self.assertRaises(GrafanaUnauthorizedError): dashboard = gc.dashboards.home.get()