lol

Merge: nixos/victoriametrics: check config, more tests & update desc (#353950)

authored by

Maximilian Bosch and committed by
GitHub
4220a62d 1531bada

+351 -59
+9 -1
nixos/modules/services/databases/victoriametrics.nix
··· 31 31 in 32 32 { 33 33 options.services.victoriametrics = { 34 - enable = mkEnableOption "VictoriaMetrics is a fast, cost-effective and scalable monitoring solution and time series database."; 34 + enable = lib.mkOption { 35 + type = lib.types.bool; 36 + default = false; 37 + description = '' 38 + Whether to enable VictoriaMetrics in single-node mode. 39 + 40 + VictoriaMetrics is a fast, cost-effective and scalable monitoring solution and time series database. 41 + ''; 42 + }; 35 43 package = mkPackageOption pkgs "victoriametrics" { }; 36 44 37 45 listenAddress = mkOption {
+40 -15
nixos/modules/services/monitoring/vmagent.nix
··· 2 2 3 3 let 4 4 cfg = config.services.vmagent; 5 - settingsFormat = pkgs.formats.json { }; 5 + settingsFormat = pkgs.formats.yaml {}; 6 + 7 + startCLIList = 8 + [ 9 + "${cfg.package}/bin/vmagent" 10 + ] 11 + ++ lib.optionals (cfg.remoteWrite.url != null) [ 12 + "-remoteWrite.url=${cfg.remoteWrite.url}" 13 + "-remoteWrite.tmpDataPath=%C/vmagent/remote_write_tmp" 14 + ] 15 + ++ lib.optional ( 16 + cfg.remoteWrite.basicAuthUsername != null 17 + ) "-remoteWrite.basicAuth.username=${cfg.remoteWrite.basicAuthUsername}" 18 + ++ lib.optional ( 19 + cfg.remoteWrite.basicAuthPasswordFile != null 20 + ) "-remoteWrite.basicAuth.passwordFile=\${CREDENTIALS_DIRECTORY}/remote_write_basic_auth_password" 21 + ++ cfg.extraArgs; 22 + prometheusConfigYml = checkedConfig ( 23 + settingsFormat.generate "prometheusConfig.yaml" cfg.prometheusConfig 24 + ); 25 + 26 + checkedConfig = file: 27 + pkgs.runCommand "checked-config" {nativeBuildInputs = [cfg.package];} '' 28 + ln -s ${file} $out 29 + ${lib.escapeShellArgs startCLIList} -promscrape.config=${file} -dryRun 30 + ''; 6 31 in { 7 32 imports = [ 8 33 (lib.mkRemovedOptionModule [ "services" "vmagent" "dataDir" ] "dataDir has been deprecated in favor of systemd provided CacheDirectory") ··· 12 37 ]; 13 38 14 39 options.services.vmagent = { 15 - enable = lib.mkEnableOption "vmagent"; 40 + enable = lib.mkOption { 41 + type = lib.types.bool; 42 + default = false; 43 + description = '' 44 + Whether to enable VictoriaMetrics's `vmagent`. 45 + 46 + `vmagent` efficiently scrape metrics from Prometheus-compatible exporters 47 + ''; 48 + }; 16 49 17 50 package = lib.mkPackageOption pkgs "vmagent" { }; 18 51 ··· 69 102 config = lib.mkIf cfg.enable { 70 103 networking.firewall.allowedTCPPorts = lib.mkIf cfg.openFirewall [ 8429 ]; 71 104 72 - systemd.services.vmagent = let 73 - prometheusConfig = settingsFormat.generate "prometheusConfig.yaml" cfg.prometheusConfig; 74 - startCommandLine = lib.concatStringsSep " " ([ 75 - "${cfg.package}/bin/vmagent" 76 - "-promscrape.config=${prometheusConfig}" 77 - ] ++ cfg.extraArgs 78 - ++ lib.optionals (cfg.remoteWrite.url != null) [ 79 - "-remoteWrite.url=${cfg.remoteWrite.url}" 80 - "-remoteWrite.tmpDataPath=%C/vmagent/remote_write_tmp" 81 - ] ++ lib.optional (cfg.remoteWrite.basicAuthUsername != null) "-remoteWrite.basicAuth.username=${cfg.remoteWrite.basicAuthUsername}" 82 - ++ lib.optional (cfg.remoteWrite.basicAuthPasswordFile != null) "-remoteWrite.basicAuth.passwordFile=\${CREDENTIALS_DIRECTORY}/remote_write_basic_auth_password"); 83 - in { 105 + systemd.services.vmagent = { 84 106 wantedBy = [ "multi-user.target" ]; 85 107 after = [ "network.target" ]; 86 108 description = "vmagent system service"; ··· 91 113 Type = "simple"; 92 114 Restart = "on-failure"; 93 115 CacheDirectory = "vmagent"; 94 - ExecStart = startCommandLine; 116 + ExecStart = lib.escapeShellArgs ( 117 + startCLIList 118 + ++ lib.optionals (cfg.prometheusConfig != null) ["-promscrape.config=${prometheusConfigYml}"] 119 + ); 95 120 LoadCredential = lib.optional (cfg.remoteWrite.basicAuthPasswordFile != null) [ 96 121 "remote_write_basic_auth_password:${cfg.remoteWrite.basicAuthPasswordFile}" 97 122 ];
+9 -1
nixos/modules/services/monitoring/vmalert.nix
··· 20 20 { 21 21 # interface 22 22 options.services.vmalert = { 23 - enable = mkEnableOption "vmalert"; 23 + enable = lib.mkOption { 24 + type = lib.types.bool; 25 + default = false; 26 + description = '' 27 + Wether to enable VictoriaMetrics's `vmalert`. 28 + 29 + `vmalert` evaluates alerting and recording rules against a data source, sends notifications via Alertmanager. 30 + ''; 31 + }; 24 32 25 33 package = mkPackageOption pkgs "victoriametrics" { }; 26 34
+1 -1
nixos/tests/all-tests.nix
··· 1106 1106 vaultwarden = discoverTests (import ./vaultwarden.nix); 1107 1107 vector = handleTest ./vector {}; 1108 1108 vengi-tools = handleTest ./vengi-tools.nix {}; 1109 - victoriametrics = handleTest ./victoriametrics.nix {}; 1109 + victoriametrics = handleTest ./victoriametrics {}; 1110 1110 vikunja = handleTest ./vikunja.nix {}; 1111 1111 virtualbox = handleTestOn ["x86_64-linux"] ./virtualbox.nix {}; 1112 1112 vscode-remote-ssh = handleTestOn ["x86_64-linux"] ./vscode-remote-ssh.nix {};
-41
nixos/tests/victoriametrics.nix
··· 1 - # This test runs victoriametrics and checks if victoriametrics is able to write points and run simple query 2 - 3 - import ./make-test-python.nix ( 4 - { pkgs, ... }: 5 - { 6 - name = "victoriametrics"; 7 - meta = with pkgs.lib.maintainers; { 8 - maintainers = [ 9 - yorickvp 10 - ryan4yin 11 - ]; 12 - }; 13 - 14 - nodes = { 15 - one = 16 - { ... }: 17 - { 18 - services.victoriametrics.enable = true; 19 - }; 20 - }; 21 - 22 - testScript = '' 23 - start_all() 24 - 25 - one.wait_for_unit("victoriametrics.service") 26 - 27 - # write some points and run simple query 28 - out = one.succeed( 29 - "curl -f -d 'measurement,tag1=value1,tag2=value2 field1=123,field2=1.23' -X POST 'http://localhost:8428/write'" 30 - ) 31 - cmd = ( 32 - """curl -f -s -G 'http://localhost:8428/api/v1/export' -d 'match={__name__!=""}'""" 33 - ) 34 - # data takes a while to appear 35 - one.wait_until_succeeds(f"[[ $({cmd} | wc -l) -ne 0 ]]") 36 - out = one.succeed(cmd) 37 - assert '"values":[123]' in out 38 - assert '"values":[1.23]' in out 39 - ''; 40 - } 41 - )
+10
nixos/tests/victoriametrics/default.nix
··· 1 + { 2 + system ? builtins.currentSystem, 3 + config ? { }, 4 + pkgs ? import ../../.. { inherit system config; }, 5 + }: 6 + 7 + { 8 + remote-write = import ./remote-write.nix { inherit system pkgs; }; 9 + vmalert = import ./vmalert.nix { inherit system pkgs; }; 10 + }
+103
nixos/tests/victoriametrics/remote-write.nix
··· 1 + # Primarily reference the implementation of <nixos/tests/prometheus/remote-write.nix> 2 + import ../make-test-python.nix ( 3 + { 4 + lib, 5 + pkgs, 6 + ... 7 + }: 8 + let 9 + username = "vmtest"; 10 + password = "fsddfy8233rb"; # random string 11 + passwordFile = pkgs.writeText "password-file" password; 12 + in 13 + { 14 + name = "victoriametrics-remote-write"; 15 + meta = with pkgs.lib.maintainers; { 16 + maintainers = [ 17 + yorickvp 18 + ryan4yin 19 + ]; 20 + }; 21 + 22 + nodes = { 23 + victoriametrics = 24 + { 25 + config, 26 + pkgs, 27 + ... 28 + }: 29 + { 30 + environment.systemPackages = [ pkgs.jq ]; 31 + networking.firewall.allowedTCPPorts = [ 8428 ]; 32 + services.victoriametrics = { 33 + enable = true; 34 + extraOptions = [ 35 + "-httpAuth.username=${username}" 36 + "-httpAuth.password=file://${toString passwordFile}" 37 + ]; 38 + }; 39 + }; 40 + 41 + vmagent = 42 + { 43 + config, 44 + pkgs, 45 + ... 46 + }: 47 + { 48 + environment.systemPackages = [ pkgs.jq ]; 49 + services.vmagent = { 50 + enable = true; 51 + remoteWrite = { 52 + url = "http://victoriametrics:8428/api/v1/write"; 53 + basicAuthUsername = username; 54 + basicAuthPasswordFile = toString passwordFile; 55 + }; 56 + 57 + prometheusConfig = { 58 + global = { 59 + scrape_interval = "2s"; 60 + }; 61 + scrape_configs = [ 62 + { 63 + job_name = "node"; 64 + static_configs = [ 65 + { 66 + targets = [ 67 + "node:${toString config.services.prometheus.exporters.node.port}" 68 + ]; 69 + } 70 + ]; 71 + } 72 + ]; 73 + }; 74 + }; 75 + }; 76 + 77 + node = 78 + { ... }: 79 + { 80 + services.prometheus.exporters.node = { 81 + enable = true; 82 + openFirewall = true; 83 + }; 84 + }; 85 + }; 86 + 87 + testScript = '' 88 + node.wait_for_unit("prometheus-node-exporter") 89 + node.wait_for_open_port(9100) 90 + 91 + victoriametrics.wait_for_unit("victoriametrics") 92 + victoriametrics.wait_for_open_port(8428) 93 + 94 + vmagent.wait_for_unit("vmagent") 95 + 96 + # check remote write 97 + victoriametrics.wait_until_succeeds( 98 + "curl --user '${username}:${password}' -sf 'http://localhost:8428/api/v1/query?query=node_exporter_build_info\{instance=\"node:9100\"\}' | " 99 + + "jq '.data.result[0].value[1]' | grep '\"1\"'" 100 + ) 101 + ''; 102 + } 103 + )
+179
nixos/tests/victoriametrics/vmalert.nix
··· 1 + # Primarily reference the implementation of <nixos/tests/prometheus/alertmanager.nix> 2 + import ../make-test-python.nix ( 3 + { 4 + lib, 5 + pkgs, 6 + ... 7 + }: 8 + { 9 + name = "victoriametrics-vmalert"; 10 + meta = with pkgs.lib.maintainers; { 11 + maintainers = [ 12 + yorickvp 13 + ryan4yin 14 + ]; 15 + }; 16 + 17 + nodes = { 18 + victoriametrics = 19 + { 20 + config, 21 + pkgs, 22 + ... 23 + }: 24 + { 25 + environment.systemPackages = [ pkgs.jq ]; 26 + networking.firewall.allowedTCPPorts = [ 8428 ]; 27 + services.victoriametrics = { 28 + enable = true; 29 + prometheusConfig = { 30 + global = { 31 + scrape_interval = "2s"; 32 + }; 33 + scrape_configs = [ 34 + { 35 + job_name = "alertmanager"; 36 + static_configs = [ 37 + { 38 + targets = [ 39 + "alertmanager:${toString config.services.prometheus.alertmanager.port}" 40 + ]; 41 + } 42 + ]; 43 + } 44 + { 45 + job_name = "node"; 46 + static_configs = [ 47 + { 48 + targets = [ 49 + "node:${toString config.services.prometheus.exporters.node.port}" 50 + ]; 51 + } 52 + ]; 53 + } 54 + ]; 55 + }; 56 + }; 57 + 58 + services.vmalert = { 59 + enable = true; 60 + settings = { 61 + "datasource.url" = "http://localhost:8428"; # victoriametrics' api 62 + "notifier.url" = [ 63 + "http://alertmanager:${toString config.services.prometheus.alertmanager.port}" 64 + ]; # alertmanager's api 65 + rule = [ 66 + (pkgs.writeText "instance-down.yml" '' 67 + groups: 68 + - name: test 69 + rules: 70 + - alert: InstanceDown 71 + expr: up == 0 72 + for: 5s 73 + labels: 74 + severity: page 75 + annotations: 76 + summary: "Instance {{ $labels.instance }} down" 77 + '') 78 + ]; 79 + }; 80 + }; 81 + }; 82 + 83 + alertmanager = 84 + { 85 + config, 86 + pkgs, 87 + ... 88 + }: 89 + { 90 + services.prometheus.alertmanager = { 91 + enable = true; 92 + openFirewall = true; 93 + 94 + configuration = { 95 + global = { 96 + resolve_timeout = "1m"; 97 + }; 98 + 99 + route = { 100 + # Root route node 101 + receiver = "test"; 102 + group_by = [ "..." ]; 103 + continue = false; 104 + group_wait = "1s"; 105 + group_interval = "15s"; 106 + repeat_interval = "24h"; 107 + }; 108 + 109 + receivers = [ 110 + { 111 + name = "test"; 112 + webhook_configs = [ 113 + { 114 + url = "http://logger:6725"; 115 + send_resolved = true; 116 + max_alerts = 0; 117 + } 118 + ]; 119 + } 120 + ]; 121 + }; 122 + }; 123 + }; 124 + 125 + logger = 126 + { 127 + config, 128 + pkgs, 129 + ... 130 + }: 131 + { 132 + networking.firewall.allowedTCPPorts = [ 6725 ]; 133 + 134 + services.prometheus.alertmanagerWebhookLogger.enable = true; 135 + }; 136 + }; 137 + 138 + testScript = '' 139 + alertmanager.wait_for_unit("alertmanager") 140 + alertmanager.wait_for_open_port(9093) 141 + alertmanager.wait_until_succeeds("curl -s http://127.0.0.1:9093/-/ready") 142 + 143 + logger.wait_for_unit("alertmanager-webhook-logger") 144 + logger.wait_for_open_port(6725) 145 + 146 + victoriametrics.wait_for_unit("victoriametrics") 147 + victoriametrics.wait_for_unit("vmalert") 148 + victoriametrics.wait_for_open_port(8428) 149 + 150 + victoriametrics.wait_until_succeeds( 151 + "curl -sf 'http://127.0.0.1:8428/api/v1/query?query=count(up\{job=\"alertmanager\"\}==1)' | " 152 + + "jq '.data.result[0].value[1]' | grep '\"1\"'" 153 + ) 154 + 155 + victoriametrics.wait_until_succeeds( 156 + "curl -sf 'http://127.0.0.1:8428/api/v1/query?query=sum(alertmanager_build_info)%20by%20(version)' | " 157 + + "jq '.data.result[0].metric.version' | grep '\"${pkgs.prometheus-alertmanager.version}\"'" 158 + ) 159 + 160 + victoriametrics.wait_until_succeeds( 161 + "curl -sf 'http://127.0.0.1:8428/api/v1/query?query=count(up\{job=\"node\"\}!=1)' | " 162 + + "jq '.data.result[0].value[1]' | grep '\"1\"'" 163 + ) 164 + 165 + victoriametrics.wait_until_succeeds( 166 + "curl -sf 'http://127.0.0.1:8428/api/v1/query?query=alertmanager_notifications_total\{integration=\"webhook\"\}' | " 167 + + "jq '.data.result[0].value[1]' | grep -v '\"0\"'" 168 + ) 169 + 170 + logger.wait_until_succeeds( 171 + "journalctl -o cat -u alertmanager-webhook-logger.service | grep '\"alertname\":\"InstanceDown\"'" 172 + ) 173 + 174 + logger.log(logger.succeed("systemd-analyze security alertmanager-webhook-logger.service | grep -v '✓'")) 175 + 176 + alertmanager.log(alertmanager.succeed("systemd-analyze security alertmanager.service | grep -v '✓'")) 177 + ''; 178 + } 179 + )