Merge pull request #191768 from KFearsoff/grafana-rfc42
nixos/grafana: refactor for RFC42
This commit is contained in:
commit
f9afc634e3
|
@ -873,6 +873,34 @@
|
|||
has been hardened.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
The <literal>services.grafana</literal> options were converted
|
||||
to a
|
||||
<link xlink:href="https://github.com/NixOS/rfcs/blob/master/rfcs/0042-config-option.md">RFC
|
||||
0042</link> configuration.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
The <literal>services.grafana.provision.datasources</literal>
|
||||
and <literal>services.grafana.provision.dashboards</literal>
|
||||
options were converted to a
|
||||
<link xlink:href="https://github.com/NixOS/rfcs/blob/master/rfcs/0042-config-option.md">RFC
|
||||
0042</link> configuration. They also now support specifying
|
||||
the provisioning YAML file with <literal>path</literal>
|
||||
option.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
The <literal>services.grafana.provision.alerting</literal>
|
||||
option was added. It includes suboptions for every
|
||||
alerting-related objects (with the exception of
|
||||
<literal>notifiers</literal>), which means it’s now possible
|
||||
to configure modern Grafana alerting declaratively.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
Matrix Synapse now requires entries in the
|
||||
|
|
|
@ -282,6 +282,12 @@ Available as [services.patroni](options.html#opt-services.patroni.enable).
|
|||
|
||||
- The `services.matrix-synapse` systemd unit has been hardened.
|
||||
|
||||
- The `services.grafana` options were converted to a [RFC 0042](https://github.com/NixOS/rfcs/blob/master/rfcs/0042-config-option.md) configuration.
|
||||
|
||||
- The `services.grafana.provision.datasources` and `services.grafana.provision.dashboards` options were converted to a [RFC 0042](https://github.com/NixOS/rfcs/blob/master/rfcs/0042-config-option.md) configuration. They also now support specifying the provisioning YAML file with `path` option.
|
||||
|
||||
- The `services.grafana.provision.alerting` option was added. It includes suboptions for every alerting-related objects (with the exception of `notifiers`), which means it's now possible to configure modern Grafana alerting declaratively.
|
||||
|
||||
- Matrix Synapse now requires entries in the `state_group_edges` table to be unique, in order to prevent accidentally introducing duplicate information (for example, because a database backup was restored multiple times). If your Synapse database already has duplicate rows in this table, this could fail with an error and require manual remediation.
|
||||
|
||||
- The `diamond` package has been update from 0.8.36 to 2.0.15. See the [upstream release notes](https://github.com/bbuchfink/diamond/releases) for more details.
|
||||
|
|
|
@ -106,9 +106,9 @@ in {
|
|||
}
|
||||
];
|
||||
|
||||
services.grafana.extraOptions = mkIf cfg.provisionGrafana {
|
||||
RENDERING_SERVER_URL = "http://localhost:${toString cfg.settings.service.port}/render";
|
||||
RENDERING_CALLBACK_URL = "http://localhost:${toString config.services.grafana.port}";
|
||||
services.grafana.settings.rendering = mkIf cfg.provisionGrafana {
|
||||
url = "http://localhost:${toString cfg.settings.service.port}/render";
|
||||
callback_url = "http://localhost:${toString config.services.grafana.port}";
|
||||
};
|
||||
|
||||
services.grafana-image-renderer.chromium = mkDefault pkgs.chromium;
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -15,7 +15,7 @@
|
|||
<para>
|
||||
Litestream service is managed by a dedicated user named <literal>litestream</literal>
|
||||
which needs permission to the database file. Here's an example config which gives
|
||||
required permissions to access <link linkend="opt-services.grafana.database.path">
|
||||
required permissions to access <link linkend="opt-services.grafana.settings.database.path">
|
||||
grafana database</link>:
|
||||
<programlisting>
|
||||
{ pkgs, ... }:
|
||||
|
|
|
@ -231,7 +231,7 @@ in {
|
|||
gollum = handleTest ./gollum.nix {};
|
||||
google-oslogin = handleTest ./google-oslogin {};
|
||||
gotify-server = handleTest ./gotify-server.nix {};
|
||||
grafana = handleTest ./grafana.nix {};
|
||||
grafana = handleTest ./grafana {};
|
||||
grafana-agent = handleTest ./grafana-agent.nix {};
|
||||
graphite = handleTest ./graphite.nix {};
|
||||
graylog = handleTest ./graylog.nix {};
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import ./make-test-python.nix ({ lib, pkgs, ... }:
|
||||
import ../make-test-python.nix ({ lib, pkgs, ... }:
|
||||
|
||||
let
|
||||
inherit (lib) mkMerge nameValuePair maintainers;
|
||||
|
@ -17,6 +17,8 @@ let
|
|||
};
|
||||
|
||||
extraNodeConfs = {
|
||||
sqlite = {};
|
||||
|
||||
declarativePlugins = {
|
||||
services.grafana.declarativePlugins = [ pkgs.grafanaPlugins.grafana-clock-panel ];
|
||||
};
|
||||
|
@ -52,14 +54,9 @@ let
|
|||
};
|
||||
};
|
||||
|
||||
nodes = builtins.listToAttrs (map (dbName:
|
||||
nameValuePair dbName (mkMerge [
|
||||
baseGrafanaConf
|
||||
(extraNodeConfs.${dbName} or {})
|
||||
])) [ "sqlite" "declarativePlugins" "postgresql" "mysql" ]);
|
||||
|
||||
nodes = builtins.mapAttrs (_: val: mkMerge [ val baseGrafanaConf ]) extraNodeConfs;
|
||||
in {
|
||||
name = "grafana";
|
||||
name = "grafana-basic";
|
||||
|
||||
meta = with maintainers; {
|
||||
maintainers = [ willibutz ];
|
9
nixos/tests/grafana/default.nix
Normal file
9
nixos/tests/grafana/default.nix
Normal file
|
@ -0,0 +1,9 @@
|
|||
{ system ? builtins.currentSystem
|
||||
, config ? { }
|
||||
, pkgs ? import ../../.. { inherit system config; }
|
||||
}:
|
||||
|
||||
{
|
||||
basic = import ./basic.nix { inherit system pkgs; };
|
||||
provision = import ./provision { inherit system pkgs; };
|
||||
}
|
9
nixos/tests/grafana/provision/contact-points.yaml
Normal file
9
nixos/tests/grafana/provision/contact-points.yaml
Normal file
|
@ -0,0 +1,9 @@
|
|||
apiVersion: 1
|
||||
|
||||
contactPoints:
|
||||
- name: "Test Contact Point"
|
||||
receivers:
|
||||
- uid: "test_contact_point"
|
||||
type: prometheus-alertmanager
|
||||
settings:
|
||||
url: http://localhost:9000
|
6
nixos/tests/grafana/provision/dashboards.yaml
Normal file
6
nixos/tests/grafana/provision/dashboards.yaml
Normal file
|
@ -0,0 +1,6 @@
|
|||
apiVersion: 1
|
||||
|
||||
providers:
|
||||
- name: 'default'
|
||||
options:
|
||||
path: /var/lib/grafana/dashboards
|
7
nixos/tests/grafana/provision/datasources.yaml
Normal file
7
nixos/tests/grafana/provision/datasources.yaml
Normal file
|
@ -0,0 +1,7 @@
|
|||
apiVersion: 1
|
||||
|
||||
datasources:
|
||||
- name: 'Test Datasource'
|
||||
type: 'testdata'
|
||||
access: 'proxy'
|
||||
uid: 'test_datasource'
|
223
nixos/tests/grafana/provision/default.nix
Normal file
223
nixos/tests/grafana/provision/default.nix
Normal file
|
@ -0,0 +1,223 @@
|
|||
import ../../make-test-python.nix ({ lib, pkgs, ... }:
|
||||
|
||||
let
|
||||
inherit (lib) mkMerge nameValuePair maintainers;
|
||||
|
||||
baseGrafanaConf = {
|
||||
services.grafana = {
|
||||
enable = true;
|
||||
addr = "localhost";
|
||||
analytics.reporting.enable = false;
|
||||
domain = "localhost";
|
||||
security = {
|
||||
adminUser = "testadmin";
|
||||
adminPassword = "snakeoilpwd";
|
||||
};
|
||||
provision.enable = true;
|
||||
};
|
||||
|
||||
systemd.tmpfiles.rules = [
|
||||
"L /var/lib/grafana/dashboards/test.json 0700 grafana grafana - ${pkgs.writeText "test.json" (builtins.readFile ./test_dashboard.json)}"
|
||||
];
|
||||
};
|
||||
|
||||
extraNodeConfs = {
|
||||
provisionOld = {
|
||||
services.grafana.provision = {
|
||||
datasources = [{
|
||||
name = "Test Datasource";
|
||||
type = "testdata";
|
||||
access = "proxy";
|
||||
uid = "test_datasource";
|
||||
}];
|
||||
|
||||
dashboards = [{ options.path = "/var/lib/grafana/dashboards"; }];
|
||||
|
||||
notifiers = [{
|
||||
uid = "test_notifiers";
|
||||
name = "Test Notifiers";
|
||||
type = "email";
|
||||
settings = {
|
||||
singleEmail = true;
|
||||
addresses = "test@test.com";
|
||||
};
|
||||
}];
|
||||
};
|
||||
};
|
||||
|
||||
provisionNix = {
|
||||
services.grafana.provision = {
|
||||
datasources.settings = {
|
||||
apiVersion = 1;
|
||||
datasources = [{
|
||||
name = "Test Datasource";
|
||||
type = "testdata";
|
||||
access = "proxy";
|
||||
uid = "test_datasource";
|
||||
}];
|
||||
};
|
||||
|
||||
dashboards.settings = {
|
||||
apiVersion = 1;
|
||||
providers = [{
|
||||
name = "default";
|
||||
options.path = "/var/lib/grafana/dashboards";
|
||||
}];
|
||||
};
|
||||
|
||||
alerting = {
|
||||
rules.settings = {
|
||||
groups = [{
|
||||
name = "test_rule_group";
|
||||
folder = "test_folder";
|
||||
interval = "60s";
|
||||
rules = [{
|
||||
uid = "test_rule";
|
||||
title = "Test Rule";
|
||||
condition = "A";
|
||||
data = [{
|
||||
refId = "A";
|
||||
datasourceUid = "-100";
|
||||
model = {
|
||||
conditions = [{
|
||||
evaluator = {
|
||||
params = [ 3 ];
|
||||
type = "git";
|
||||
};
|
||||
operator.type = "and";
|
||||
query.params = [ "A" ];
|
||||
reducer.type = "last";
|
||||
type = "query";
|
||||
}];
|
||||
datasource = {
|
||||
type = "__expr__";
|
||||
uid = "-100";
|
||||
};
|
||||
expression = "1==0";
|
||||
intervalMs = 1000;
|
||||
maxDataPoints = 43200;
|
||||
refId = "A";
|
||||
type = "math";
|
||||
};
|
||||
}];
|
||||
for = "60s";
|
||||
}];
|
||||
}];
|
||||
};
|
||||
|
||||
contactPoints.settings = {
|
||||
contactPoints = [{
|
||||
name = "Test Contact Point";
|
||||
receivers = [{
|
||||
uid = "test_contact_point";
|
||||
type = "prometheus-alertmanager";
|
||||
settings.url = "http://localhost:9000";
|
||||
}];
|
||||
}];
|
||||
};
|
||||
|
||||
policies.settings = {
|
||||
policies = [{
|
||||
receiver = "Test Contact Point";
|
||||
}];
|
||||
};
|
||||
|
||||
templates.settings = {
|
||||
templates = [{
|
||||
name = "Test Template";
|
||||
template = "Test message";
|
||||
}];
|
||||
};
|
||||
|
||||
muteTimings.settings = {
|
||||
muteTimes = [{
|
||||
name = "Test Mute Timing";
|
||||
}];
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
provisionYaml = {
|
||||
services.grafana.provision = {
|
||||
datasources.path = ./datasources.yaml;
|
||||
dashboards.path = ./dashboards.yaml;
|
||||
alerting = {
|
||||
rules.path = ./rules.yaml;
|
||||
contactPoints.path = ./contact-points.yaml;
|
||||
policies.path = ./policies.yaml;
|
||||
templates.path = ./templates.yaml;
|
||||
muteTimings.path = ./mute-timings.yaml;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
nodes = builtins.mapAttrs (_: val: mkMerge [ val baseGrafanaConf ]) extraNodeConfs;
|
||||
in {
|
||||
name = "grafana-provision";
|
||||
|
||||
meta = with maintainers; {
|
||||
maintainers = [ kfears willibutz ];
|
||||
};
|
||||
|
||||
inherit nodes;
|
||||
|
||||
testScript = ''
|
||||
start_all()
|
||||
|
||||
nodeOld = ("Nix (old format)", provisionOld)
|
||||
nodeNix = ("Nix (new format)", provisionNix)
|
||||
nodeYaml = ("Nix (YAML)", provisionYaml)
|
||||
|
||||
for nodeInfo in [nodeOld, nodeNix, nodeYaml]:
|
||||
with subtest(f"Should start provision node: {nodeInfo[0]}"):
|
||||
nodeInfo[1].wait_for_unit("grafana.service")
|
||||
nodeInfo[1].wait_for_open_port(3000)
|
||||
|
||||
with subtest(f"Successful datasource provision with {nodeInfo[0]}"):
|
||||
nodeInfo[1].succeed(
|
||||
"curl -sSfN -u testadmin:snakeoilpwd http://127.0.0.1:3000/api/datasources/uid/test_datasource | grep Test\ Datasource"
|
||||
)
|
||||
|
||||
with subtest(f"Successful dashboard provision with {nodeInfo[0]}"):
|
||||
nodeInfo[1].succeed(
|
||||
"curl -sSfN -u testadmin:snakeoilpwd http://127.0.0.1:3000/api/dashboards/uid/test_dashboard | grep Test\ Dashboard"
|
||||
)
|
||||
|
||||
|
||||
|
||||
with subtest(f"Successful notifiers provision with {nodeOld[0]}"):
|
||||
nodeOld[1].succeed(
|
||||
"curl -sSfN -u testadmin:snakeoilpwd http://127.0.0.1:3000/api/alert-notifications/uid/test_notifiers | grep Test\ Notifiers"
|
||||
)
|
||||
|
||||
|
||||
|
||||
for nodeInfo in [nodeNix, nodeYaml]:
|
||||
with subtest(f"Successful rule provision with {nodeInfo[0]}"):
|
||||
nodeInfo[1].succeed(
|
||||
"curl -sSfN -u testadmin:snakeoilpwd http://127.0.0.1:3000/api/v1/provisioning/alert-rules/test_rule | grep Test\ Rule"
|
||||
)
|
||||
|
||||
with subtest(f"Successful contact point provision with {nodeInfo[0]}"):
|
||||
nodeInfo[1].succeed(
|
||||
"curl -sSfN -u testadmin:snakeoilpwd http://127.0.0.1:3000/api/v1/provisioning/contact-points | grep Test\ Contact\ Point"
|
||||
)
|
||||
|
||||
with subtest(f"Successful policy provision with {nodeInfo[0]}"):
|
||||
nodeInfo[1].succeed(
|
||||
"curl -sSfN -u testadmin:snakeoilpwd http://127.0.0.1:3000/api/v1/provisioning/policies | grep Test\ Contact\ Point"
|
||||
)
|
||||
|
||||
with subtest(f"Successful template provision with {nodeInfo[0]}"):
|
||||
nodeInfo[1].succeed(
|
||||
"curl -sSfN -u testadmin:snakeoilpwd http://127.0.0.1:3000/api/v1/provisioning/templates | grep Test\ Template"
|
||||
)
|
||||
|
||||
with subtest("Successful mute timings provision with {nodeInfo[0]}"):
|
||||
nodeInfo[1].succeed(
|
||||
"curl -sSfN -u testadmin:snakeoilpwd http://127.0.0.1:3000/api/v1/provisioning/mute-timings | grep Test\ Mute\ Timing"
|
||||
)
|
||||
'';
|
||||
})
|
4
nixos/tests/grafana/provision/mute-timings.yaml
Normal file
4
nixos/tests/grafana/provision/mute-timings.yaml
Normal file
|
@ -0,0 +1,4 @@
|
|||
apiVersion: 1
|
||||
|
||||
muteTimes:
|
||||
- name: "Test Mute Timing"
|
4
nixos/tests/grafana/provision/policies.yaml
Normal file
4
nixos/tests/grafana/provision/policies.yaml
Normal file
|
@ -0,0 +1,4 @@
|
|||
apiVersion: 1
|
||||
|
||||
policies:
|
||||
- receiver: "Test Contact Point"
|
36
nixos/tests/grafana/provision/rules.yaml
Normal file
36
nixos/tests/grafana/provision/rules.yaml
Normal file
|
@ -0,0 +1,36 @@
|
|||
apiVersion: 1
|
||||
|
||||
groups:
|
||||
- name: "test_rule_group"
|
||||
folder: "test_group"
|
||||
interval: 60s
|
||||
rules:
|
||||
- uid: "test_rule"
|
||||
title: "Test Rule"
|
||||
condition: A
|
||||
data:
|
||||
- refId: A
|
||||
datasourceUid: '-100'
|
||||
model:
|
||||
conditions:
|
||||
- evaluator:
|
||||
params:
|
||||
- 3
|
||||
type: gt
|
||||
operator:
|
||||
type: and
|
||||
query:
|
||||
params:
|
||||
- A
|
||||
reducer:
|
||||
type: last
|
||||
type: query
|
||||
datasource:
|
||||
type: __expr__
|
||||
uid: '-100'
|
||||
expression: 1==0
|
||||
intervalMs: 1000
|
||||
maxDataPoints: 43200
|
||||
refId: A
|
||||
type: math
|
||||
for: 60s
|
5
nixos/tests/grafana/provision/templates.yaml
Normal file
5
nixos/tests/grafana/provision/templates.yaml
Normal file
|
@ -0,0 +1,5 @@
|
|||
apiVersion: 1
|
||||
|
||||
templates:
|
||||
- name: "Test Template"
|
||||
template: "Test message"
|
47
nixos/tests/grafana/provision/test_dashboard.json
Normal file
47
nixos/tests/grafana/provision/test_dashboard.json
Normal file
|
@ -0,0 +1,47 @@
|
|||
{
|
||||
"annotations": {
|
||||
"list": [
|
||||
{
|
||||
"builtIn": 1,
|
||||
"datasource": {
|
||||
"type": "grafana",
|
||||
"uid": "-- Grafana --"
|
||||
},
|
||||
"enable": true,
|
||||
"hide": true,
|
||||
"iconColor": "rgba(0, 211, 255, 1)",
|
||||
"name": "Annotations & Alerts",
|
||||
"target": {
|
||||
"limit": 100,
|
||||
"matchAny": false,
|
||||
"tags": [],
|
||||
"type": "dashboard"
|
||||
},
|
||||
"type": "dashboard"
|
||||
}
|
||||
]
|
||||
},
|
||||
"editable": true,
|
||||
"fiscalYearStartMonth": 0,
|
||||
"graphTooltip": 0,
|
||||
"id": 28,
|
||||
"links": [],
|
||||
"liveNow": false,
|
||||
"panels": [],
|
||||
"schemaVersion": 37,
|
||||
"style": "dark",
|
||||
"tags": [],
|
||||
"templating": {
|
||||
"list": []
|
||||
},
|
||||
"time": {
|
||||
"from": "now-6h",
|
||||
"to": "now"
|
||||
},
|
||||
"timepicker": {},
|
||||
"timezone": "",
|
||||
"title": "Test Dashboard",
|
||||
"uid": "test_dashboard",
|
||||
"version": 1,
|
||||
"weekStart": ""
|
||||
}
|
Loading…
Reference in a new issue