Merge pull request #263335 from anthonyroussel/nixos-goss

nixos/goss: init
This commit is contained in:
Peder Bergebakken Sundt 2023-10-28 06:36:43 +02:00 committed by GitHub
commit dc42e2603b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 214 additions and 7 deletions

View File

@ -86,6 +86,8 @@
- [pgBouncer](https://www.pgbouncer.org), a PostgreSQL connection pooler. Available as [services.pgbouncer](#opt-services.pgbouncer.enable).
- [Goss](https://goss.rocks/), a YAML based serverspec alternative tool for validating a server's configuration. Available as [services.goss](#opt-services.goss.enable).
- [trust-dns](https://trust-dns.org/), a Rust based DNS server built to be safe and secure from the ground up. Available as [services.trust-dns](#opt-services.trust-dns.enable).
- [osquery](https://www.osquery.io/), a SQL powered operating system instrumentation, monitoring, and analytics.

View File

@ -773,6 +773,7 @@
./services/monitoring/datadog-agent.nix
./services/monitoring/do-agent.nix
./services/monitoring/fusion-inventory.nix
./services/monitoring/goss.nix
./services/monitoring/grafana-agent.nix
./services/monitoring/grafana-image-renderer.nix
./services/monitoring/grafana-reporter.nix

View File

@ -0,0 +1,44 @@
# Goss {#module-services-goss}
[goss](https://goss.rocks/) is a YAML based serverspec alternative tool
for validating a server's configuration.
## Basic Usage {#module-services-goss-basic-usage}
A minimal configuration looks like this:
```
{
services.goss = {
enable = true;
environment = {
GOSS_FMT = "json";
GOSS_LOGLEVEL = "TRACE";
};
settings = {
addr."tcp://localhost:8080" = {
reachable = true;
local-address = "127.0.0.1";
};
command."check-goss-version" = {
exec = "${lib.getExe pkgs.goss} --version";
exit-status = 0;
};
dns.localhost.resolvable = true;
file."/nix" = {
filetype = "directory";
exists = true;
};
group.root.exists = true;
kernel-param."kernel.ostype".value = "Linux";
service.goss = {
enabled = true;
running = true;
};
user.root.exists = true;
};
};
}
```

View File

@ -0,0 +1,86 @@
{ config, lib, pkgs, ... }:
let
cfg = config.services.goss;
settingsFormat = pkgs.formats.yaml { };
configFile = settingsFormat.generate "goss.yaml" cfg.settings;
in {
meta = {
doc = ./goss.md;
maintainers = [ lib.maintainers.anthonyroussel ];
};
options = {
services.goss = {
enable = lib.mkEnableOption (lib.mdDoc "Goss daemon");
package = lib.mkPackageOptionMD pkgs "goss" { };
environment = lib.mkOption {
type = lib.types.attrsOf lib.types.str;
default = { };
example = {
GOSS_FMT = "json";
GOSS_LOGLEVEL = "FATAL";
GOSS_LISTEN = ":8080";
};
description = lib.mdDoc ''
Environment variables to set for the goss service.
See <https://github.com/goss-org/goss/blob/master/docs/manual.md>
'';
};
settings = lib.mkOption {
type = lib.types.submodule { freeformType = settingsFormat.type; };
default = { };
example = {
addr."tcp://localhost:8080" = {
reachable = true;
local-address = "127.0.0.1";
};
service.goss = {
enabled = true;
running = true;
};
};
description = lib.mdDoc ''
The global options in `config` file in yaml format.
Refer to <https://github.com/goss-org/goss/blob/master/docs/goss-json-schema.yaml> for schema.
'';
};
};
};
config = lib.mkIf cfg.enable {
environment.systemPackages = [ cfg.package ];
systemd.services.goss = {
description = "Goss - Quick and Easy server validation";
unitConfig.Documentation = "https://github.com/goss-org/goss/blob/master/docs/manual.md";
after = [ "network-online.target" ];
wantedBy = [ "multi-user.target" ];
wants = [ "network-online.target" ];
environment = {
GOSS_FILE = configFile;
} // cfg.environment;
reloadTriggers = [ configFile ];
serviceConfig = {
DynamicUser = true;
ExecReload = "${pkgs.coreutils}/bin/kill -HUP $MAINPID";
ExecStart = "${cfg.package}/bin/goss serve";
Group = "goss";
Restart = "on-failure";
RestartSec = 5;
User = "goss";
};
};
};
}

View File

@ -329,6 +329,7 @@ in {
gollum = handleTest ./gollum.nix {};
gonic = handleTest ./gonic.nix {};
google-oslogin = handleTest ./google-oslogin {};
goss = handleTest ./goss.nix {};
gotify-server = handleTest ./gotify-server.nix {};
gotosocial = runTest ./web-apps/gotosocial.nix;
grafana = handleTest ./grafana {};

53
nixos/tests/goss.nix Normal file
View File

@ -0,0 +1,53 @@
import ./make-test-python.nix ({ pkgs, lib, ... }: {
name = "goss";
meta.maintainers = [ lib.maintainers.anthonyroussel ];
nodes.machine = {
environment.systemPackages = [ pkgs.jq ];
services.goss = {
enable = true;
environment = {
GOSS_FMT = "json";
};
settings = {
addr."tcp://localhost:8080" = {
reachable = true;
local-address = "127.0.0.1";
};
command."check-goss-version" = {
exec = "${lib.getExe pkgs.goss} --version";
exit-status = 0;
};
dns.localhost.resolvable = true;
file."/nix" = {
filetype = "directory";
exists = true;
};
group.root.exists = true;
kernel-param."kernel.ostype".value = "Linux";
service.goss = {
enabled = true;
running = true;
};
user.root.exists = true;
};
};
};
testScript = ''
import json
machine.wait_for_unit("goss.service")
machine.wait_for_open_port(8080)
with subtest("returns health status"):
result = json.loads(machine.succeed("curl -sS http://localhost:8080/healthz"))
assert len(result["results"]) == 10, f".results should be an array of 10 items, was {result['results']!r}"
assert result["summary"]["failed-count"] == 0, f".summary.failed-count should be zero, was {result['summary']['failed-count']}"
assert result["summary"]["test-count"] == 10, f".summary.test-count should be 10, was {result['summary']['test-count']}"
'';
})

View File

@ -1,8 +1,14 @@
{ buildGoModule
{ bash
, buildGoModule
, fetchFromGitHub
, getent
, goss
, nix-update-script
, lib
, makeWrapper
, nix-update-script
, nixosTests
, stdenv
, systemd
, testers
}:
@ -26,17 +32,30 @@ buildGoModule rec {
"-s" "-w" "-X main.version=v${version}"
];
nativeBuildInputs = [ makeWrapper ];
checkFlags = [
# Prometheus tests are skipped upstream
# See https://github.com/goss-org/goss/blob/master/ci/go-test.sh
"-skip" "^TestPrometheus"
];
postInstall = let
runtimeDependencies = [ bash getent ]
++ lib.optionals stdenv.isLinux [ systemd ];
in ''
wrapProgram $out/bin/goss \
--prefix PATH : "${lib.makeBinPath runtimeDependencies}"
'';
passthru = {
tests.version = testers.testVersion {
command = "goss --version";
package = goss;
version = "v${version}";
tests = {
inherit (nixosTests) goss;
version = testers.testVersion {
command = "goss --version";
package = goss;
version = "v${version}";
};
};
updateScript = nix-update-script { };
};
@ -51,7 +70,8 @@ buildGoModule rec {
Once the test suite is written they can be executed, waited-on, or served as a health endpoint.
'';
license = licenses.asl20;
platforms = platforms.linux ++ platforms.darwin;
mainProgram = "goss";
maintainers = with maintainers; [ hyzual jk anthonyroussel ];
platforms = platforms.linux ++ platforms.darwin;
};
}