Grafana

Grafana 5 ist noch eine AngularJS-basierte Applikation, mit einigen React.js-Komponenten. Plugins sind Angular-Controller, die in data/plugins/your-module/dist/module.js abgelegt und von SystemJS geladen werden. Die Migration von AngularJS hin zu React wurde gegen Ende 2018 gestartet, und mit Grafana 7 ein grosser Meilenstein erreicht. Damit ändert sich allerdings auch die Plugin-Entwicklung.

Links

Installation

Installation der OSS-Variante:

/etc/yum.repos.d/grafana.repo
[grafana]
name=grafana
baseurl=https://packages.grafana.com/oss/rpm
repo_gpgcheck=1
enabled=1
gpgcheck=1
gpgkey=https://packages.grafana.com/gpg.key
sslverify=1
sslcacert=/etc/pki/tls/certs/ca-bundle.crt
yum -y install grafana
/etc/grafana/grafana.ini
# The public facing domain name used to access grafana from a browser
# set this, otherwise some redirects might not work (for example OAuth)
domain = 192.168.122.97

# default admin user, created on startup
admin_user = grafana-admin

# default admin password, can be changed before first start of grafana,  or in profile settings
admin_password = password

Wird Grafana ohne separate Datenbank wie MariaDB oder PostgreSQL konfiguriert, nutzt es seine integrierte SQLite-Datenbank.

systemctl daemon-reload
systemctl enable grafana-server
systemctl start grafana-server

Port 3000/tcp freigeben.

http://192.168.122.193:3000/login, Login mit „grafana-admin“ und „password“.

Logging:

tail -f /var/log/grafana/grafana.log

Kiosk-Mode

Um Grafana-Dashboards ohne störende Menüs im Kiosk-Mode laufen zu lassen, die Dashboard-URL um den Parameter &kiosk ergänzen.

Keycloak (OAuth)

Grafana-Seite

Grafana lässt sich an Keycloak (für Grafana ein OAuth-IdP) anbinden. Die Grafana-Seite muss wie folgt konfiguriert werden:

/etc/grafana/grafana.ini
[auth.generic_oauth]
enabled = true
name = Keycloak IdP
allow_sign_up = true
client_id = grafana
client_secret = e8d78053-fd47-4ec3-b6dc-87357f18f8d5
scopes = openid email profile
;email_attribute_name = email:primary
;email_attribute_path =
;login_attribute_path =
;id_token_attribute_name =
auth_url = http://keycloak:8080/auth/realms/grafana/protocol/openid-connect/auth
token_url = http://keycloak:8080/auth/realms/grafana/protocol/openid-connect/token
api_url = http://keycloak:8080/auth/realms/grafana/protocol/openid-connect/userinfo
;allowed_domains =
;team_ids =
;allowed_organizations =
role_attribute_path = "contains(roles[*], 'admin') && 'Admin' || contains(roles[*], 'editor') && 'Editor' || 'Viewer'"
;tls_skip_verify_insecure = false
;tls_client_cert =
;tls_client_key =
;tls_client_ca =

allow_sign_up = true ist notwendig, da ansonsten Grafana den von Keycloak übermittelten Benutzer nicht in seiner eigenen Datenbank anlegen kann (man erhält die Fehlermeldung Not allowing oauth_generic_oauth login, user not found in internal user database and allow signup = false).

Wer mag, einen Admin-User im Keycloak angelegt hat und Keycloak vertraut, kann das klassische Anmelde-Formular per disable_login_form = false abschalten, so dass nur noch eine Anmeldung per Keycloak möglich ist

Keycloak-Seite

Besonderheiten eines Realms für Grafana: der OAuth-Client in Grafana versteht Roles - Keycloak teilt Grafana also die gewünschte Berechtigungsstufe mit. Im Beispiel wird eine admin-Rolle angelegt, der ein Keycloak-User zugewiesen wird.

Neuer Client „Grafana“ mit „openid-connect“.

  • Clients > „grafana“ > Settings

    • Client ID: grafana

    • Name: Grafana (wird im Self-Service-Portal unter „Applications“ verwendet)

    • Description: Any descriptive text (wird im Self-Service-Portal unter „Applications“ verwendet)

    • Client Protocol: openid-connect

    • Access Type: confidential

    • Valid Redirect URIs: http://grafana:3000/login/generic_oauth

    • Base URL: http://grafana:3000/login/generic_oauth (wird im Self-Service-Portal unter „Applications“ verwendet)

  • Clients > „grafana“ > Roles > Add

    • admin

    • editor

    • viewer

Benutzer anlegen und Rolle zuweisen:

  • Users > User suchen, Edit > Role Mappings > Client Roles > „grafana“ > Assign „admin“ role (oder „editor“, oder „viewer“)

Wir möchten im Client-Token nur das mitteilen, was wir explizit definieren:

  • Clients > „grafana“ > Scope > Full Scope Allowed: OFF

Grafana muss anschliessend in der Lage sein, die Berechtigungsstufe aus dem JWT-Token zu extrahieren. Dazu muss in Keycloak ein „Client Mapper“ definiert werden:

  • Clients > „grafana“ > Mappers > Create

    • Name: Keycloak Role to Client Role

    • Mapper Type: User Client Role

    • Client ID: grafana

    • Token Claim Name: roles

    • Claim JSON type: string

    • Add to ID token: ON

    • Add to access token: OFF

    • Add to userinfo: OFF

Der Benutzer wird bei der Anmeldung in Grafana an Keycloak umgeleitet. Ist der Benutzer authentifiziert, wird er in Grafana mit der ihm in Keycloak zugeordneten Rolle angelegt. Wird die Rolle des Benutzers nachträglich in Keycloak geändert, erhält der Benutzer seine neue Gruppenzugehörigkeit beim nächsten Login in Grafana.

Das Grafana-API

Im Beispiel: Export aller Datasources aus Grafana per API (ist auch nicht anders möglich).

Zunächst im Grafana unter Configuration > API Keys einen neuen API-Key erstellen. Den Bearer-TOken unbedingt notieren. Anschliessend lassen sich API-Calls durchführen, beispielsweise:

# Content of Dashboards > Home
curl -H "Authorization: Bearer eyJrIjoiTTZFSjVDdVo1ZTNtOUZkN1Myc3pva3hGcjZCakxhOHIiLCJuIjoiY3VybGVyIiwiaWQiOjF9" http://10.80.32.52:3000/api/dashboards/home | jq

# Export all Datasources (API-Key needs Admin Permissions)
curl -H "Authorization: Bearer eyJrIjoiTTZFSjVDdVo1ZTNtOUZkN1Myc3pva3hGcjZCakxhOHIiLCJuIjoiY3VybGVyIiwiaWQiOjF9" http://10.80.32.52:3000/api/datasources | jq

Das API ist hier beschrieben: https://grafana.com/docs/grafana/latest/http_api/

Plugins

Plugins müssen für bestimmte Grafana-Versionen signiert sein, damit sie dort geladen werden können. Ausnahmen lassen sich so definieren:

/etc/grafana/grafana.ini
[plugins]
# Enter a comma-separated list of plugin identifiers to identify plugins that are allowed
# to be loaded even if they lack a valid signature.
allow_loading_unsigned_plugins = simpod-json-datasource

Plugin-Entwicklung

Seit Grafana 7.0 wird die Entwicklung Angular-basierter Plugins nicht mehr empfohlen (gelten jetzt als „Legacy Plugins“), daher React verwenden.

Techniken:

  • Bis Version 6: Angular, node & npm/yarn, Build-Prozess basiert auf grunt

  • Ab Version 7: React/JSX, node & yarn

Plugin Typen:

  • Panel: Custom visualization for your dashboards

  • Data Source: plugin to add support for your own data sources

  • Backend Data Source: lets your data source plugin communicate with a process running on the server instead in the Browser

Built on 2022-06-03