WIP: nixos-25.05 #500
22 changed files with 18 additions and 1082 deletions
2
REUSE.toml
generated
2
REUSE.toml
generated
|
@ -20,7 +20,7 @@ precedence = "closest"
|
||||||
[[annotations]]
|
[[annotations]]
|
||||||
SPDX-FileCopyrightText = "2024 Tom Hubrecht <tom.hubrecht@dgnum.eu>"
|
SPDX-FileCopyrightText = "2024 Tom Hubrecht <tom.hubrecht@dgnum.eu>"
|
||||||
SPDX-License-Identifier = "EUPL-1.2"
|
SPDX-License-Identifier = "EUPL-1.2"
|
||||||
path = ["machines/nixos/compute01/ds-fr/01-smtp-tls.patch", "machines/nixos/compute01/librenms/kanidm.patch", "machines/nixos/compute01/stirling-pdf/*.patch", "machines/nixos/vault01/k-radius/packages/01-python_path.patch", "machines/nixos/vault01/k-radius/packages/02-remove-noisy-logs.patch", "machines/nixos/vault01/k-radius/packages/03-set-log-level.patch", "machines/nixos/web01/crabfit/*.patch", "machines/nixos/web02/cas-eleves/01-pytest-cas.patch", "patches/lix/01-disable-installChecks.patch", "patches/lix/02-fetchGit-locked.patch", "patches/nixpkgs/01-pretalx-environment-file.patch", "patches/nixpkgs/03-crabfit-karla.patch", "patches/nixpkgs/05-netbird-relay.patch", "patches/cas-eleves/01-ldap-settings.patch"]
|
path = ["machines/nixos/compute01/ds-fr/01-smtp-tls.patch", "machines/nixos/compute01/stirling-pdf/*.patch", "machines/nixos/vault01/k-radius/packages/01-python_path.patch", "machines/nixos/vault01/k-radius/packages/02-remove-noisy-logs.patch", "machines/nixos/vault01/k-radius/packages/03-set-log-level.patch", "machines/nixos/web01/crabfit/*.patch", "machines/nixos/web02/cas-eleves/01-pytest-cas.patch", "patches/lix/01-disable-installChecks.patch", "patches/lix/02-fetchGit-locked.patch", "patches/nixpkgs/01-pretalx-environment-file.patch", "patches/nixpkgs/03-crabfit-karla.patch", "patches/nixpkgs/05-netbird-relay.patch", "patches/cas-eleves/01-ldap-settings.patch"]
|
||||||
precedence = "closest"
|
precedence = "closest"
|
||||||
|
|
||||||
[[annotations]]
|
[[annotations]]
|
||||||
|
|
|
@ -113,7 +113,6 @@ let
|
||||||
{
|
{
|
||||||
path = [
|
path = [
|
||||||
"machines/nixos/compute01/ds-fr/01-smtp-tls.patch"
|
"machines/nixos/compute01/ds-fr/01-smtp-tls.patch"
|
||||||
"machines/nixos/compute01/librenms/kanidm.patch"
|
|
||||||
"machines/nixos/compute01/stirling-pdf/*.patch"
|
"machines/nixos/compute01/stirling-pdf/*.patch"
|
||||||
"machines/nixos/vault01/k-radius/packages/01-python_path.patch"
|
"machines/nixos/vault01/k-radius/packages/01-python_path.patch"
|
||||||
"machines/nixos/vault01/k-radius/packages/02-remove-noisy-logs.patch"
|
"machines/nixos/vault01/k-radius/packages/02-remove-noisy-logs.patch"
|
||||||
|
|
|
@ -24,7 +24,6 @@ lib.extra.mkConfig {
|
||||||
"grafana"
|
"grafana"
|
||||||
"hedgedoc"
|
"hedgedoc"
|
||||||
"kanidm"
|
"kanidm"
|
||||||
"librenms"
|
|
||||||
"mastodon"
|
"mastodon"
|
||||||
# "netbox"
|
# "netbox"
|
||||||
"nextcloud"
|
"nextcloud"
|
||||||
|
@ -38,7 +37,6 @@ lib.extra.mkConfig {
|
||||||
"rstudio-server"
|
"rstudio-server"
|
||||||
# "satosa"
|
# "satosa"
|
||||||
"signal-irc-bridge"
|
"signal-irc-bridge"
|
||||||
"signald"
|
|
||||||
"stirling-pdf"
|
"stirling-pdf"
|
||||||
"takumi"
|
"takumi"
|
||||||
"telegraf"
|
"telegraf"
|
||||||
|
|
|
@ -83,7 +83,7 @@ in
|
||||||
groups =
|
groups =
|
||||||
{
|
{
|
||||||
grp_active.members = catAttrs "username" (attrValues meta.organization.members);
|
grp_active.members = catAttrs "username" (attrValues meta.organization.members);
|
||||||
grp-ext_cri.memberless = true;
|
grp-ext_cri.overwriteMembers = false;
|
||||||
}
|
}
|
||||||
// (mapAttrs' (
|
// (mapAttrs' (
|
||||||
name: members: nameValuePair "grp_${name}" { members = builtins.map usernameFor members; }
|
name: members: nameValuePair "grp_${name}" { members = builtins.map usernameFor members; }
|
||||||
|
@ -108,21 +108,6 @@ in
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
|
||||||
dgn_librenms = {
|
|
||||||
allowInsecureClientDisablePkce = true;
|
|
||||||
displayName = "LibreNMS [Network]";
|
|
||||||
enableLegacyCrypto = true;
|
|
||||||
originLanding = "https://nms.dgnum.eu";
|
|
||||||
originUrl = "https://nms.dgnum.eu/auth/kanidm/callback";
|
|
||||||
preferShortUsername = true;
|
|
||||||
|
|
||||||
scopeMaps.grp_active = [
|
|
||||||
"openid"
|
|
||||||
"profile"
|
|
||||||
"email"
|
|
||||||
];
|
|
||||||
};
|
|
||||||
|
|
||||||
dgn_netbird = {
|
dgn_netbird = {
|
||||||
displayName = "Netbird [VPN]";
|
displayName = "Netbird [VPN]";
|
||||||
enableLocalhostRedirects = true;
|
enableLocalhostRedirects = true;
|
||||||
|
|
|
@ -1,55 +0,0 @@
|
||||||
# SPDX-FileCopyrightText: 2024 Tom Hubrecht <tom.hubrecht@dgnum.eu>
|
|
||||||
#
|
|
||||||
# SPDX-License-Identifier: EUPL-1.2
|
|
||||||
|
|
||||||
{ config, pkgs, ... }:
|
|
||||||
|
|
||||||
let
|
|
||||||
host = "nms.dgnum.eu";
|
|
||||||
in
|
|
||||||
|
|
||||||
{
|
|
||||||
imports = [ ./module.nix ];
|
|
||||||
|
|
||||||
services.librenms = {
|
|
||||||
enable = true;
|
|
||||||
|
|
||||||
package =
|
|
||||||
(pkgs.librenms.override { inherit (config.services.librenms) dataDir logDir; }).overrideAttrs
|
|
||||||
(old: {
|
|
||||||
patches = (old.patches or [ ]) ++ [ ./kanidm.patch ];
|
|
||||||
vendorHash = "sha256-J/whSL1keEZKkfOtHpkJ2vSrN/s+DpUGb6RBXpQZQXg=";
|
|
||||||
});
|
|
||||||
|
|
||||||
hostname = host;
|
|
||||||
|
|
||||||
settings = {
|
|
||||||
auth.socialite = {
|
|
||||||
configs.kanidm = {
|
|
||||||
listener = "\\SocialiteProviders\\Kanidm\\KanidmExtendSocialite";
|
|
||||||
client_id = "$KANIDM_CLIENT_ID";
|
|
||||||
client_secret = "$KANIDM_CLIENT_SECRET";
|
|
||||||
redirect = "$KANIDM_REDIRECT_URI";
|
|
||||||
base_url = "$KANIDM_BASE_URL";
|
|
||||||
};
|
|
||||||
default_role = "normal";
|
|
||||||
register = true;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
database = {
|
|
||||||
createLocally = true;
|
|
||||||
passwordFile = config.age.secrets."librenms-database_password_file".path;
|
|
||||||
};
|
|
||||||
|
|
||||||
environmentFile = config.age.secrets."librenms-environment_file".path;
|
|
||||||
|
|
||||||
nginx = {
|
|
||||||
serverName = host;
|
|
||||||
enableACME = true;
|
|
||||||
forceSSL = true;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
age-secrets.autoMatch = [ "librenms" ];
|
|
||||||
}
|
|
|
@ -1,90 +0,0 @@
|
||||||
diff --git a/composer.json b/composer.json
|
|
||||||
index af8168f4c..1775f150e 100644
|
|
||||||
--- a/composer.json
|
|
||||||
+++ b/composer.json
|
|
||||||
@@ -54,6 +54,7 @@
|
|
||||||
"phpmailer/phpmailer": "~6.0",
|
|
||||||
"predis/predis": "^2.0",
|
|
||||||
"silber/bouncer": "^1.0",
|
|
||||||
+ "socialiteproviders/kanidm": "^5.0",
|
|
||||||
"socialiteproviders/manager": "^4.3",
|
|
||||||
"spatie/laravel-ignition": "^2.0",
|
|
||||||
"symfony/yaml": "^6.2",
|
|
||||||
diff --git a/composer.lock b/composer.lock
|
|
||||||
index 3d89a1530..a00c5f307 100644
|
|
||||||
--- a/composer.lock
|
|
||||||
+++ b/composer.lock
|
|
||||||
@@ -4,7 +4,7 @@
|
|
||||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
|
||||||
"This file is @generated automatically"
|
|
||||||
],
|
|
||||||
- "content-hash": "fee5d24447dced4397e26066f8c9ee59",
|
|
||||||
+ "content-hash": "b9316a47587c8e6f6b0adbe3d54777f3",
|
|
||||||
"packages": [
|
|
||||||
{
|
|
||||||
"name": "amenadiel/jpgraph",
|
|
||||||
@@ -5906,6 +5906,56 @@
|
|
||||||
},
|
|
||||||
"time": "2023-02-10T16:47:25+00:00"
|
|
||||||
},
|
|
||||||
+ {
|
|
||||||
+ "name": "socialiteproviders/kanidm",
|
|
||||||
+ "version": "5.0.0",
|
|
||||||
+ "source": {
|
|
||||||
+ "type": "git",
|
|
||||||
+ "url": "https://github.com/SocialiteProviders/Kanidm.git",
|
|
||||||
+ "reference": "111ad45941e7150e3219ddfdeb8159f758bde2fd"
|
|
||||||
+ },
|
|
||||||
+ "dist": {
|
|
||||||
+ "type": "zip",
|
|
||||||
+ "url": "https://api.github.com/repos/SocialiteProviders/Kanidm/zipball/111ad45941e7150e3219ddfdeb8159f758bde2fd",
|
|
||||||
+ "reference": "111ad45941e7150e3219ddfdeb8159f758bde2fd",
|
|
||||||
+ "shasum": ""
|
|
||||||
+ },
|
|
||||||
+ "require": {
|
|
||||||
+ "ext-json": "*",
|
|
||||||
+ "php": "^8.0",
|
|
||||||
+ "socialiteproviders/manager": "^4.4"
|
|
||||||
+ },
|
|
||||||
+ "type": "library",
|
|
||||||
+ "autoload": {
|
|
||||||
+ "psr-4": {
|
|
||||||
+ "SocialiteProviders\\Kanidm\\": ""
|
|
||||||
+ }
|
|
||||||
+ },
|
|
||||||
+ "notification-url": "https://packagist.org/downloads/",
|
|
||||||
+ "license": [
|
|
||||||
+ "MIT"
|
|
||||||
+ ],
|
|
||||||
+ "authors": [
|
|
||||||
+ {
|
|
||||||
+ "name": "Tom Hubrecht",
|
|
||||||
+ "email": "tom@hubrecht.ovh"
|
|
||||||
+ }
|
|
||||||
+ ],
|
|
||||||
+ "description": "Kanidm OAuth2 Provider for Laravel Socialite",
|
|
||||||
+ "keywords": [
|
|
||||||
+ "kanidm",
|
|
||||||
+ "laravel",
|
|
||||||
+ "oauth",
|
|
||||||
+ "provider",
|
|
||||||
+ "socialite"
|
|
||||||
+ ],
|
|
||||||
+ "support": {
|
|
||||||
+ "docs": "https://socialiteproviders.com/kanidm",
|
|
||||||
+ "issues": "https://github.com/socialiteproviders/providers/issues",
|
|
||||||
+ "source": "https://github.com/socialiteproviders/providers"
|
|
||||||
+ },
|
|
||||||
+ "time": "2024-02-19T19:49:21+00:00"
|
|
||||||
+ },
|
|
||||||
{
|
|
||||||
"name": "socialiteproviders/manager",
|
|
||||||
"version": "v4.6.0",
|
|
||||||
index 3d89a1530..a00c5f307 100644
|
|
||||||
--- a/app/Providers/EventServiceProvider.php
|
|
||||||
+++ b/app/Providers/EventServiceProvider.php
|
|
||||||
@@ -33,3 +33,4 @@
|
|
||||||
\SocialiteProviders\Manager\SocialiteWasCalled::class => [
|
|
||||||
+ \SocialiteProviders\Kanidm\KanidmExtendSocialite::class.'@handle',
|
|
||||||
\App\Listeners\SocialiteWasCalledListener::class,
|
|
||||||
],
|
|
|
@ -1,687 +0,0 @@
|
||||||
# SPDX-FileCopyrightText: 2024 Tom Hubrecht <tom.hubrecht@dgnum.eu>
|
|
||||||
#
|
|
||||||
# SPDX-License-Identifier: EUPL-1.2
|
|
||||||
|
|
||||||
{
|
|
||||||
config,
|
|
||||||
lib,
|
|
||||||
pkgs,
|
|
||||||
modulesPath,
|
|
||||||
...
|
|
||||||
}:
|
|
||||||
|
|
||||||
let
|
|
||||||
inherit (lib)
|
|
||||||
literalExpression
|
|
||||||
mkEnableOption
|
|
||||||
mkOption
|
|
||||||
recursiveUpdate
|
|
||||||
types
|
|
||||||
;
|
|
||||||
|
|
||||||
cfg = config.services.librenms;
|
|
||||||
settingsFormat = pkgs.formats.json { };
|
|
||||||
configJson = settingsFormat.generate "librenms-config.json" cfg.settings;
|
|
||||||
|
|
||||||
inherit (cfg) package;
|
|
||||||
|
|
||||||
phpOptions = ''
|
|
||||||
log_errors = on
|
|
||||||
post_max_size = 100M
|
|
||||||
upload_max_filesize = 100M
|
|
||||||
date.timezone = "${config.time.timeZone}"
|
|
||||||
'';
|
|
||||||
|
|
||||||
phpIni =
|
|
||||||
pkgs.runCommand "php.ini"
|
|
||||||
{
|
|
||||||
inherit (package) phpPackage;
|
|
||||||
inherit phpOptions;
|
|
||||||
preferLocalBuild = true;
|
|
||||||
passAsFile = [ "phpOptions" ];
|
|
||||||
}
|
|
||||||
''
|
|
||||||
cat $phpPackage/etc/php.ini $phpOptionsPath > $out
|
|
||||||
'';
|
|
||||||
|
|
||||||
artisanWrapper = pkgs.writeShellScriptBin "librenms-artisan" ''
|
|
||||||
cd ${package}
|
|
||||||
sudo=exec
|
|
||||||
if [[ "$USER" != ${cfg.user} ]]; then
|
|
||||||
sudo='exec /run/wrappers/bin/sudo -u ${cfg.user}'
|
|
||||||
fi
|
|
||||||
$sudo ${package}/artisan $*
|
|
||||||
'';
|
|
||||||
|
|
||||||
lnmsWrapper = pkgs.writeShellScriptBin "lnms" ''
|
|
||||||
cd ${package}
|
|
||||||
exec ${package}/lnms $*
|
|
||||||
'';
|
|
||||||
|
|
||||||
configFile = pkgs.writeText "config.php" ''
|
|
||||||
<?php
|
|
||||||
$new_config = json_decode(file_get_contents("${cfg.dataDir}/config.json"), true);
|
|
||||||
$config = ($config == null) ? $new_config : array_merge($config, $new_config);
|
|
||||||
|
|
||||||
${lib.optionalString (cfg.extraConfig != null) cfg.extraConfig}
|
|
||||||
'';
|
|
||||||
in
|
|
||||||
{
|
|
||||||
disabledModules = [ "services/monitoring/librenms.nix" ];
|
|
||||||
|
|
||||||
options.services.librenms = {
|
|
||||||
enable = mkEnableOption "LibreNMS network monitoring system";
|
|
||||||
|
|
||||||
package = mkOption {
|
|
||||||
type = types.package;
|
|
||||||
default = pkgs.librenms.override { inherit (cfg) dataDir logDir; };
|
|
||||||
description = "Librenms package to use.";
|
|
||||||
};
|
|
||||||
|
|
||||||
user = mkOption {
|
|
||||||
type = types.str;
|
|
||||||
default = "librenms";
|
|
||||||
description = ''
|
|
||||||
Name of the LibreNMS user.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
group = mkOption {
|
|
||||||
type = types.str;
|
|
||||||
default = "librenms";
|
|
||||||
description = ''
|
|
||||||
Name of the LibreNMS group.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
hostname = mkOption {
|
|
||||||
type = types.str;
|
|
||||||
default = config.networking.fqdnOrHostName;
|
|
||||||
defaultText = literalExpression "config.networking.fqdnOrHostName";
|
|
||||||
description = ''
|
|
||||||
The hostname to serve LibreNMS on.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
pollerThreads = mkOption {
|
|
||||||
type = types.int;
|
|
||||||
default = 16;
|
|
||||||
description = ''
|
|
||||||
Amount of threads of the cron-poller.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
enableOneMinutePolling = mkOption {
|
|
||||||
type = types.bool;
|
|
||||||
default = false;
|
|
||||||
description = ''
|
|
||||||
Enables the [1-Minute Polling](https://docs.librenms.org/Support/1-Minute-Polling/).
|
|
||||||
Changing this option will automatically convert your existing rrd files.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
useDistributedPollers = mkOption {
|
|
||||||
type = types.bool;
|
|
||||||
default = false;
|
|
||||||
description = ''
|
|
||||||
Enables (distributed pollers)[https://docs.librenms.org/Extensions/Distributed-Poller/]
|
|
||||||
for this LibreNMS instance. This will enable a local `rrdcached` and `memcached` server.
|
|
||||||
|
|
||||||
To use this feature, make sure to configure your firewall that the distributed pollers
|
|
||||||
can reach the local `mysql`, `rrdcached` and `memcached` ports.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
distributedPoller = {
|
|
||||||
enable = mkOption {
|
|
||||||
type = types.bool;
|
|
||||||
default = false;
|
|
||||||
description = ''
|
|
||||||
Configure this LibreNMS instance as a (distributed poller)[https://docs.librenms.org/Extensions/Distributed-Poller/].
|
|
||||||
This will disable all web features and just configure the poller features.
|
|
||||||
Use the `mysql` database of your main LibreNMS instance in the database settings.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
name = mkOption {
|
|
||||||
type = types.nullOr types.str;
|
|
||||||
default = null;
|
|
||||||
description = ''
|
|
||||||
Custom name of this poller.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
group = mkOption {
|
|
||||||
type = types.str;
|
|
||||||
default = "0";
|
|
||||||
example = "1,2";
|
|
||||||
description = ''
|
|
||||||
Group(s) of this poller.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
distributedBilling = mkOption {
|
|
||||||
type = types.bool;
|
|
||||||
default = false;
|
|
||||||
description = ''
|
|
||||||
Enable distributed billing on this poller.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
memcachedHost = mkOption {
|
|
||||||
type = types.str;
|
|
||||||
description = ''
|
|
||||||
Hostname or IP of the `memcached` server.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
memcachedPort = mkOption {
|
|
||||||
type = types.port;
|
|
||||||
default = 11211;
|
|
||||||
description = ''
|
|
||||||
Port of the `memcached` server.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
rrdcachedHost = mkOption {
|
|
||||||
type = types.str;
|
|
||||||
description = ''
|
|
||||||
Hostname or IP of the `rrdcached` server.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
rrdcachedPort = mkOption {
|
|
||||||
type = types.port;
|
|
||||||
default = 42217;
|
|
||||||
description = ''
|
|
||||||
Port of the `memcached` server.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
poolConfig = mkOption {
|
|
||||||
type =
|
|
||||||
with types;
|
|
||||||
attrsOf (oneOf [
|
|
||||||
str
|
|
||||||
int
|
|
||||||
bool
|
|
||||||
]);
|
|
||||||
default = {
|
|
||||||
"pm" = "dynamic";
|
|
||||||
"pm.max_children" = 32;
|
|
||||||
"pm.start_servers" = 2;
|
|
||||||
"pm.min_spare_servers" = 2;
|
|
||||||
"pm.max_spare_servers" = 4;
|
|
||||||
"pm.max_requests" = 500;
|
|
||||||
};
|
|
||||||
description = ''
|
|
||||||
Options for the LibreNMS PHP pool. See the documentation on `php-fpm.conf`
|
|
||||||
for details on configuration directives.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
nginx = mkOption {
|
|
||||||
type = types.submodule (
|
|
||||||
recursiveUpdate (import "${modulesPath}/services/web-servers/nginx/vhost-options.nix" {
|
|
||||||
inherit config lib;
|
|
||||||
}) { }
|
|
||||||
);
|
|
||||||
default = { };
|
|
||||||
example = literalExpression ''
|
|
||||||
{
|
|
||||||
serverAliases = [
|
|
||||||
"librenms.''${config.networking.domain}"
|
|
||||||
];
|
|
||||||
# To enable encryption and let let's encrypt take care of certificate
|
|
||||||
forceSSL = true;
|
|
||||||
enableACME = true;
|
|
||||||
# To set the LibreNMS virtualHost as the default virtualHost;
|
|
||||||
default = true;
|
|
||||||
}
|
|
||||||
'';
|
|
||||||
description = ''
|
|
||||||
With this option, you can customize the nginx virtualHost settings.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
dataDir = mkOption {
|
|
||||||
type = types.path;
|
|
||||||
default = "/var/lib/librenms";
|
|
||||||
description = ''
|
|
||||||
Path of the LibreNMS state directory.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
logDir = mkOption {
|
|
||||||
type = types.path;
|
|
||||||
default = "/var/log/librenms";
|
|
||||||
description = ''
|
|
||||||
Path of the LibreNMS logging directory.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
database = {
|
|
||||||
createLocally = mkOption {
|
|
||||||
type = types.bool;
|
|
||||||
default = false;
|
|
||||||
description = ''
|
|
||||||
Whether to create a local database automatically.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
host = mkOption {
|
|
||||||
default = "localhost";
|
|
||||||
description = ''
|
|
||||||
Hostname or IP of the MySQL/MariaDB server.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
port = mkOption {
|
|
||||||
type = types.port;
|
|
||||||
default = 3306;
|
|
||||||
description = ''
|
|
||||||
Port of the MySQL/MariaDB server.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
database = mkOption {
|
|
||||||
type = types.str;
|
|
||||||
default = "librenms";
|
|
||||||
description = ''
|
|
||||||
Name of the database on the MySQL/MariaDB server.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
username = mkOption {
|
|
||||||
type = types.str;
|
|
||||||
default = "librenms";
|
|
||||||
description = ''
|
|
||||||
Name of the user on the MySQL/MariaDB server.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
passwordFile = mkOption {
|
|
||||||
type = types.path;
|
|
||||||
example = "/run/secrets/mysql.pass";
|
|
||||||
description = ''
|
|
||||||
A file containing the password for the user of the MySQL/MariaDB server.
|
|
||||||
Must be readable for the LibreNMS user.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
environmentFile = mkOption {
|
|
||||||
type = types.nullOr types.str;
|
|
||||||
default = null;
|
|
||||||
description = ''
|
|
||||||
File containing env-vars to be substituted into the final config. Useful for secrets.
|
|
||||||
Does not apply to settings defined in `extraConfig`.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
settings = mkOption {
|
|
||||||
type = types.submodule {
|
|
||||||
freeformType = settingsFormat.type;
|
|
||||||
options = { };
|
|
||||||
};
|
|
||||||
description = ''
|
|
||||||
Attrset of the LibreNMS configuration.
|
|
||||||
See https://docs.librenms.org/Support/Configuration/ for reference.
|
|
||||||
All possible options are listed [here](https://github.com/librenms/librenms/blob/master/misc/config_definitions.json).
|
|
||||||
See https://docs.librenms.org/Extensions/Authentication/ for setting other authentication methods.
|
|
||||||
'';
|
|
||||||
default = { };
|
|
||||||
example = {
|
|
||||||
base_url = "/librenms/";
|
|
||||||
top_devices = true;
|
|
||||||
top_ports = false;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
extraConfig = mkOption {
|
|
||||||
type = types.nullOr types.str;
|
|
||||||
default = null;
|
|
||||||
description = ''
|
|
||||||
Additional config for LibreNMS that will be appended to the `config.php`. See
|
|
||||||
https://github.com/librenms/librenms/blob/master/misc/config_definitions.json
|
|
||||||
for possible options. Useful if you want to use PHP-Functions in your config.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
config = lib.mkIf cfg.enable {
|
|
||||||
assertions = [
|
|
||||||
{
|
|
||||||
assertion = config.time.timeZone != null;
|
|
||||||
message = "You must set `time.timeZone` to use the LibreNMS module.";
|
|
||||||
}
|
|
||||||
{
|
|
||||||
assertion = cfg.database.createLocally -> cfg.database.host == "localhost";
|
|
||||||
message = ''The database host must be "localhost" if services.librenms.database.createLocally is set to true.'';
|
|
||||||
}
|
|
||||||
{
|
|
||||||
assertion = !(cfg.useDistributedPollers && cfg.distributedPoller.enable);
|
|
||||||
message = "The LibreNMS instance can't be a distributed poller and a full instance at the same time.";
|
|
||||||
}
|
|
||||||
];
|
|
||||||
|
|
||||||
users.users.${cfg.user} = {
|
|
||||||
group = "${cfg.group}";
|
|
||||||
isSystemUser = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
users.groups.${cfg.group} = { };
|
|
||||||
|
|
||||||
services = {
|
|
||||||
librenms.settings =
|
|
||||||
{
|
|
||||||
# basic configs
|
|
||||||
"user" = cfg.user;
|
|
||||||
"own_hostname" = cfg.hostname;
|
|
||||||
"base_url" = lib.mkDefault "/";
|
|
||||||
"auth_mechanism" = lib.mkDefault "mysql";
|
|
||||||
|
|
||||||
# disable auto update function (won't work with NixOS)
|
|
||||||
"update" = false;
|
|
||||||
|
|
||||||
# enable fast ping by default
|
|
||||||
"ping_rrd_step" = 60;
|
|
||||||
|
|
||||||
# one minute polling
|
|
||||||
"rrd.step" = if cfg.enableOneMinutePolling then 60 else 300;
|
|
||||||
"rrd.heartbeat" = if cfg.enableOneMinutePolling then 120 else 600;
|
|
||||||
}
|
|
||||||
// (lib.optionalAttrs cfg.distributedPoller.enable {
|
|
||||||
"distributed_poller" = true;
|
|
||||||
"distributed_poller_name" = lib.mkIf (
|
|
||||||
cfg.distributedPoller.name != null
|
|
||||||
) cfg.distributedPoller.name;
|
|
||||||
"distributed_poller_group" = cfg.distributedPoller.group;
|
|
||||||
"distributed_billing" = cfg.distributedPoller.distributedBilling;
|
|
||||||
"distributed_poller_memcached_host" = cfg.distributedPoller.memcachedHost;
|
|
||||||
"distributed_poller_memcached_port" = cfg.distributedPoller.memcachedPort;
|
|
||||||
"rrdcached" =
|
|
||||||
"${cfg.distributedPoller.rrdcachedHost}:${toString cfg.distributedPoller.rrdcachedPort}";
|
|
||||||
})
|
|
||||||
// (lib.optionalAttrs cfg.useDistributedPollers {
|
|
||||||
"distributed_poller" = true;
|
|
||||||
# still enable a local poller with distributed polling
|
|
||||||
"distributed_poller_group" = lib.mkDefault "0";
|
|
||||||
"distributed_billing" = lib.mkDefault true;
|
|
||||||
"distributed_poller_memcached_host" = "localhost";
|
|
||||||
"distributed_poller_memcached_port" = 11211;
|
|
||||||
"rrdcached" = "localhost:42217";
|
|
||||||
});
|
|
||||||
|
|
||||||
memcached = lib.mkIf cfg.useDistributedPollers {
|
|
||||||
enable = true;
|
|
||||||
listen = "0.0.0.0";
|
|
||||||
};
|
|
||||||
|
|
||||||
mysql = lib.mkIf cfg.database.createLocally {
|
|
||||||
enable = true;
|
|
||||||
package = lib.mkDefault pkgs.mariadb;
|
|
||||||
settings.mysqld = {
|
|
||||||
innodb_file_per_table = 1;
|
|
||||||
lower_case_table_names = 0;
|
|
||||||
} // (lib.optionalAttrs cfg.useDistributedPollers { bind-address = "0.0.0.0"; });
|
|
||||||
ensureDatabases = [ cfg.database.database ];
|
|
||||||
ensureUsers = [
|
|
||||||
{
|
|
||||||
name = cfg.database.username;
|
|
||||||
ensurePermissions = {
|
|
||||||
"${cfg.database.database}.*" = "ALL PRIVILEGES";
|
|
||||||
};
|
|
||||||
}
|
|
||||||
];
|
|
||||||
initialScript = lib.mkIf cfg.useDistributedPollers (
|
|
||||||
pkgs.writeText "mysql-librenms-init" ''
|
|
||||||
CREATE USER IF NOT EXISTS '${cfg.database.username}'@'%';
|
|
||||||
GRANT ALL PRIVILEGES ON ${cfg.database.database}.* TO '${cfg.database.username}'@'%';
|
|
||||||
''
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
nginx = lib.mkIf (!cfg.distributedPoller.enable) {
|
|
||||||
enable = true;
|
|
||||||
virtualHosts."${cfg.hostname}" = lib.mkMerge [
|
|
||||||
cfg.nginx
|
|
||||||
{
|
|
||||||
root = lib.mkForce "${package}/html";
|
|
||||||
locations."/" = {
|
|
||||||
index = "index.php";
|
|
||||||
tryFiles = "$uri $uri/ /index.php?$query_string";
|
|
||||||
};
|
|
||||||
locations."~ .php$".extraConfig = ''
|
|
||||||
fastcgi_pass unix:${config.services.phpfpm.pools."librenms".socket};
|
|
||||||
fastcgi_split_path_info ^(.+\.php)(/.+)$;
|
|
||||||
'';
|
|
||||||
}
|
|
||||||
];
|
|
||||||
};
|
|
||||||
|
|
||||||
phpfpm.pools.librenms = lib.mkIf (!cfg.distributedPoller.enable) {
|
|
||||||
inherit (cfg) group user;
|
|
||||||
inherit (package) phpPackage;
|
|
||||||
inherit phpOptions;
|
|
||||||
settings = {
|
|
||||||
"listen.mode" = "0660";
|
|
||||||
"listen.owner" = config.services.nginx.user;
|
|
||||||
"listen.group" = config.services.nginx.group;
|
|
||||||
} // cfg.poolConfig;
|
|
||||||
};
|
|
||||||
|
|
||||||
logrotate = {
|
|
||||||
enable = true;
|
|
||||||
settings."${cfg.logDir}/librenms.log" = {
|
|
||||||
su = "${cfg.user} ${cfg.group}";
|
|
||||||
create = "0640 ${cfg.user} ${cfg.group}";
|
|
||||||
rotate = 6;
|
|
||||||
frequency = "weekly";
|
|
||||||
compress = true;
|
|
||||||
delaycompress = true;
|
|
||||||
missingok = true;
|
|
||||||
notifempty = true;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
cron = {
|
|
||||||
enable = true;
|
|
||||||
systemCronJobs =
|
|
||||||
let
|
|
||||||
env = "PHPRC=${phpIni}";
|
|
||||||
in
|
|
||||||
[
|
|
||||||
# based on crontab provided by LibreNMS
|
|
||||||
"33 */6 * * * ${cfg.user} ${env} ${package}/cronic ${package}/discovery-wrapper.py 1"
|
|
||||||
"*/5 * * * * ${cfg.user} ${env} ${package}/discovery.php -h new >> /dev/null 2>&1"
|
|
||||||
|
|
||||||
"${
|
|
||||||
if cfg.enableOneMinutePolling then "*" else "*/5"
|
|
||||||
} * * * * ${cfg.user} ${env} ${package}/cronic ${package}/poller-wrapper.py ${toString cfg.pollerThreads}"
|
|
||||||
"* * * * * ${cfg.user} ${env} ${package}/alerts.php >> /dev/null 2>&1"
|
|
||||||
|
|
||||||
"*/5 * * * * ${cfg.user} ${env} ${package}/poll-billing.php >> /dev/null 2>&1"
|
|
||||||
"01 * * * * ${cfg.user} ${env} ${package}/billing-calculate.php >> /dev/null 2>&1"
|
|
||||||
"*/5 * * * * ${cfg.user} ${env} ${package}/check-services.php >> /dev/null 2>&1"
|
|
||||||
|
|
||||||
# extra: fast ping
|
|
||||||
"* * * * * ${cfg.user} ${env} ${package}/ping.php >> /dev/null 2>&1"
|
|
||||||
|
|
||||||
# daily.sh tasks are split to exclude update
|
|
||||||
"19 0 * * * ${cfg.user} ${env} ${package}/daily.sh cleanup >> /dev/null 2>&1"
|
|
||||||
"19 0 * * * ${cfg.user} ${env} ${package}/daily.sh notifications >> /dev/null 2>&1"
|
|
||||||
"19 0 * * * ${cfg.user} ${env} ${package}/daily.sh peeringdb >> /dev/null 2>&1"
|
|
||||||
"19 0 * * * ${cfg.user} ${env} ${package}/daily.sh mac_oui >> /dev/null 2>&1"
|
|
||||||
];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
systemd = {
|
|
||||||
services = {
|
|
||||||
rrdcached = lib.mkIf cfg.useDistributedPollers {
|
|
||||||
description = "rrdcached";
|
|
||||||
after = [ "librenms-setup.service" ];
|
|
||||||
wantedBy = [ "multi-user.target" ];
|
|
||||||
serviceConfig = {
|
|
||||||
Type = "forking";
|
|
||||||
User = cfg.user;
|
|
||||||
Group = cfg.group;
|
|
||||||
LimitNOFILE = 16384;
|
|
||||||
RuntimeDirectory = "rrdcached";
|
|
||||||
PidFile = "/run/rrdcached/rrdcached.pid";
|
|
||||||
# rrdcached params from https://docs.librenms.org/Extensions/Distributed-Poller/#config-sample
|
|
||||||
ExecStart = "${pkgs.rrdtool}/bin/rrdcached -l 0:42217 -R -j ${cfg.dataDir}/rrdcached-journal/ -F -b ${cfg.dataDir}/rrd -B -w 1800 -z 900 -p /run/rrdcached/rrdcached.pid";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
librenms-scheduler = {
|
|
||||||
description = "LibreNMS Scheduler";
|
|
||||||
path = [ pkgs.unixtools.whereis ];
|
|
||||||
serviceConfig = {
|
|
||||||
Type = "oneshot";
|
|
||||||
WorkingDirectory = package;
|
|
||||||
User = cfg.user;
|
|
||||||
Group = cfg.group;
|
|
||||||
ExecStart = "${artisanWrapper}/bin/librenms-artisan schedule:run";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
librenms-setup = {
|
|
||||||
description = "Preparation tasks for LibreNMS";
|
|
||||||
before = [ "phpfpm-librenms.service" ];
|
|
||||||
after = [
|
|
||||||
"systemd-tmpfiles-setup.service"
|
|
||||||
] ++ (lib.optional (cfg.database.host == "localhost") "mysql.service");
|
|
||||||
wantedBy = [ "multi-user.target" ];
|
|
||||||
restartTriggers = [
|
|
||||||
package
|
|
||||||
configFile
|
|
||||||
];
|
|
||||||
path = [
|
|
||||||
pkgs.mariadb
|
|
||||||
pkgs.unixtools.whereis
|
|
||||||
pkgs.gnused
|
|
||||||
];
|
|
||||||
serviceConfig = {
|
|
||||||
Type = "oneshot";
|
|
||||||
RemainAfterExit = true;
|
|
||||||
EnvironmentFile = lib.mkIf (cfg.environmentFile != null) [ cfg.environmentFile ];
|
|
||||||
User = cfg.user;
|
|
||||||
Group = cfg.group;
|
|
||||||
ExecStartPre = lib.mkIf cfg.database.createLocally [
|
|
||||||
"!${pkgs.writeShellScript "librenms-db-init" ''
|
|
||||||
DB_PASSWORD=$(cat ${cfg.database.passwordFile} | tr -d '\n')
|
|
||||||
echo "ALTER USER '${cfg.database.username}'@'localhost' IDENTIFIED BY '$DB_PASSWORD';" | ${pkgs.mariadb}/bin/mysql
|
|
||||||
${lib.optionalString cfg.useDistributedPollers ''
|
|
||||||
echo "ALTER USER '${cfg.database.username}'@'%' IDENTIFIED BY '$DB_PASSWORD';" | ${pkgs.mariadb}/bin/mysql
|
|
||||||
''}
|
|
||||||
''}"
|
|
||||||
];
|
|
||||||
};
|
|
||||||
script = ''
|
|
||||||
set -euo pipefail
|
|
||||||
|
|
||||||
# config setup
|
|
||||||
ln -sf ${configFile} ${cfg.dataDir}/config.php
|
|
||||||
${pkgs.envsubst}/bin/envsubst -i ${configJson} -o ${cfg.dataDir}/config.json
|
|
||||||
export PHPRC=${phpIni}
|
|
||||||
|
|
||||||
if [[ ! -s ${cfg.dataDir}/.env ]]; then
|
|
||||||
# init .env file
|
|
||||||
echo "APP_KEY=" > ${cfg.dataDir}/.env
|
|
||||||
${artisanWrapper}/bin/librenms-artisan key:generate --ansi
|
|
||||||
${artisanWrapper}/bin/librenms-artisan webpush:vapid
|
|
||||||
echo "" >> ${cfg.dataDir}/.env
|
|
||||||
echo -n "NODE_ID=" >> ${cfg.dataDir}/.env
|
|
||||||
${package.phpPackage}/bin/php -r "echo uniqid();" >> ${cfg.dataDir}/.env
|
|
||||||
echo "" >> ${cfg.dataDir}/.env
|
|
||||||
else
|
|
||||||
# .env file already exists --> only update database and cache config
|
|
||||||
${pkgs.gnused}/bin/sed -i /^DB_/d ${cfg.dataDir}/.env
|
|
||||||
${pkgs.gnused}/bin/sed -i /^CACHE_DRIVER/d ${cfg.dataDir}/.env
|
|
||||||
fi
|
|
||||||
${lib.optionalString (cfg.useDistributedPollers || cfg.distributedPoller.enable) ''
|
|
||||||
echo "CACHE_DRIVER=memcached" >> ${cfg.dataDir}/.env
|
|
||||||
''}
|
|
||||||
echo "DB_HOST=${cfg.database.host}" >> ${cfg.dataDir}/.env
|
|
||||||
echo "DB_PORT=${toString cfg.database.port}" >> ${cfg.dataDir}/.env
|
|
||||||
echo "DB_DATABASE=${cfg.database.database}" >> ${cfg.dataDir}/.env
|
|
||||||
echo "DB_USERNAME=${cfg.database.username}" >> ${cfg.dataDir}/.env
|
|
||||||
echo -n "DB_PASSWORD=" >> ${cfg.dataDir}/.env
|
|
||||||
cat ${cfg.database.passwordFile} >> ${cfg.dataDir}/.env
|
|
||||||
|
|
||||||
# clear cache after update
|
|
||||||
OLD_VERSION=$(cat ${cfg.dataDir}/version)
|
|
||||||
if [[ $OLD_VERSION != "${package.version}" ]]; then
|
|
||||||
rm -r ${cfg.dataDir}/cache/*
|
|
||||||
echo "${package.version}" > ${cfg.dataDir}/version
|
|
||||||
fi
|
|
||||||
|
|
||||||
# convert rrd files when the oneMinutePolling option is changed
|
|
||||||
OLD_ENABLED=$(cat ${cfg.dataDir}/one_minute_enabled)
|
|
||||||
if [[ $OLD_ENABLED != "${lib.boolToString cfg.enableOneMinutePolling}" ]]; then
|
|
||||||
${package}/scripts/rrdstep.php -h all
|
|
||||||
echo "${lib.boolToString cfg.enableOneMinutePolling}" > ${cfg.dataDir}/one_minute_enabled
|
|
||||||
fi
|
|
||||||
|
|
||||||
# migrate db
|
|
||||||
${artisanWrapper}/bin/librenms-artisan migrate --force --no-interaction
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
timers.librenms-scheduler = {
|
|
||||||
description = "LibreNMS Scheduler";
|
|
||||||
wantedBy = [ "timers.target" ];
|
|
||||||
timerConfig = {
|
|
||||||
OnCalendar = "minutely";
|
|
||||||
AccuracySec = "1second";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
tmpfiles.rules =
|
|
||||||
[
|
|
||||||
"d ${cfg.logDir} 0750 ${cfg.user} ${cfg.group} - -"
|
|
||||||
"f ${cfg.logDir}/librenms.log 0640 ${cfg.user} ${cfg.group} - -"
|
|
||||||
"d ${cfg.dataDir} 0750 ${cfg.user} ${cfg.group} - -"
|
|
||||||
"f ${cfg.dataDir}/.env 0600 ${cfg.user} ${cfg.group} - -"
|
|
||||||
"f ${cfg.dataDir}/version 0600 ${cfg.user} ${cfg.group} - -"
|
|
||||||
"f ${cfg.dataDir}/one_minute_enabled 0600 ${cfg.user} ${cfg.group} - -"
|
|
||||||
"f ${cfg.dataDir}/config.json 0600 ${cfg.user} ${cfg.group} - -"
|
|
||||||
"d ${cfg.dataDir}/storage 0700 ${cfg.user} ${cfg.group} - -"
|
|
||||||
"d ${cfg.dataDir}/storage/app 0700 ${cfg.user} ${cfg.group} - -"
|
|
||||||
"d ${cfg.dataDir}/storage/debugbar 0700 ${cfg.user} ${cfg.group} - -"
|
|
||||||
"d ${cfg.dataDir}/storage/framework 0700 ${cfg.user} ${cfg.group} - -"
|
|
||||||
"d ${cfg.dataDir}/storage/framework/cache 0700 ${cfg.user} ${cfg.group} - -"
|
|
||||||
"d ${cfg.dataDir}/storage/framework/sessions 0700 ${cfg.user} ${cfg.group} - -"
|
|
||||||
"d ${cfg.dataDir}/storage/framework/views 0700 ${cfg.user} ${cfg.group} - -"
|
|
||||||
"d ${cfg.dataDir}/storage/logs 0700 ${cfg.user} ${cfg.group} - -"
|
|
||||||
"d ${cfg.dataDir}/rrd 0700 ${cfg.user} ${cfg.group} - -"
|
|
||||||
"d ${cfg.dataDir}/cache 0700 ${cfg.user} ${cfg.group} - -"
|
|
||||||
]
|
|
||||||
++ lib.optionals cfg.useDistributedPollers [
|
|
||||||
"d ${cfg.dataDir}/rrdcached-journal 0700 ${cfg.user} ${cfg.group} - -"
|
|
||||||
];
|
|
||||||
};
|
|
||||||
|
|
||||||
programs.mtr.enable = true;
|
|
||||||
|
|
||||||
security.wrappers = {
|
|
||||||
fping = {
|
|
||||||
setuid = true;
|
|
||||||
owner = "root";
|
|
||||||
group = "root";
|
|
||||||
source = "${pkgs.fping}/bin/fping";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
environment.systemPackages = [
|
|
||||||
artisanWrapper
|
|
||||||
lnmsWrapper
|
|
||||||
];
|
|
||||||
};
|
|
||||||
|
|
||||||
meta.maintainers = lib.teams.wdz.members;
|
|
||||||
}
|
|
|
@ -33,13 +33,6 @@ in
|
||||||
|
|
||||||
secretKeybaseFile = config.age.secrets."plausible-secret_key_base_file".path;
|
secretKeybaseFile = config.age.secrets."plausible-secret_key_base_file".path;
|
||||||
};
|
};
|
||||||
|
|
||||||
adminUser = {
|
|
||||||
passwordFile = config.age.secrets."plausible-admin_user_password_file".path;
|
|
||||||
email = "tom.hubrecht@dgnum.eu";
|
|
||||||
name = "thubrecht";
|
|
||||||
activate = true;
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
dgn-web.simpleProxies.plausible = {
|
dgn-web.simpleProxies.plausible = {
|
||||||
|
|
|
@ -1,29 +0,0 @@
|
||||||
age-encryption.org/v1
|
|
||||||
-> ssh-ed25519 jIXfPA UxfxSZSNMeVYMYCahDmlrf3mdMpyFzcj+81nBBCECgk
|
|
||||||
lYiIx4BvqqB1CfM/Y+Y1LRZBDzGkRKdfa0HLfPCzQUE
|
|
||||||
-> ssh-ed25519 QlRB9Q I13TmGvHd/x40ML386PyWmdd/ub3Q69MqPi1GzEwgVI
|
|
||||||
8ym5O+kh3JBJ91vizO8jODFN9M2OAUIOijmI5QKzguQ
|
|
||||||
-> ssh-ed25519 r+nK/Q RPDuBopRVTVPKRqZgEh2XfchP9XCPjzhuW+hu2LCbBk
|
|
||||||
BYZJvcH3BQGh9CSkvREz1JzyksVN8TSuilW2ww2kXho
|
|
||||||
-> ssh-rsa krWCLQ
|
|
||||||
jFEaahbYnGF9WTvaW5FmBIrhNwt/ZiaQv04VZHQnOhJRCmJViExZl2+yCqHlK4nF
|
|
||||||
X5qbe51FwJX1VyF4x74tVdTb3PR1hx1JdncEXUdr2/8DSsddAGTowQl2RA8GBpd4
|
|
||||||
K2YiRjMPTvShmfXZUncqR8UOB97FIOMMMjXZmDN+T2D4xZ522g7mvPLq/a9T9iB6
|
|
||||||
cvcwu4PVvTTO+oM7hWj3KYM1aMtRlNscgPaJSvZ5f3MOAEo4qdDlERC473jc/0ez
|
|
||||||
yRNz1B4AjO4YWWXmLgPrh2n+kCkv4ZI5nUHgO8kCNuHLD8bX5eeQCn1fx6F2bWuE
|
|
||||||
f5c9CI4X69z0HQDZWVSwcw
|
|
||||||
-> ssh-ed25519 /vwQcQ 9iCDJiFcwJ/2GZ1fP0BiUUDfSb8ByldRGMUMNxp1gTE
|
|
||||||
khKANSZ8UIF9jCm32Y2Pn0e04Qr42eKPfTOPTQdnKEs
|
|
||||||
-> ssh-ed25519 0R97PA qacag6Tw7RwyACjvRUQU25252nDQxDxepGuUg4e82QY
|
|
||||||
UAYVIwprsmpC7GYPZNlLAKjLQkbZ1DmXy5fdGyL3az4
|
|
||||||
-> ssh-ed25519 JGx7Ng Q6GFfKxfoI4rD1smg3NwD9Q8IqP9dFCmhBIcompCW2c
|
|
||||||
B+S+wCC7oe8CXH1/7n45U2XssrzB1xHYuJX0BPQa4tY
|
|
||||||
-> ssh-ed25519 bUjjig ZIXCFGNK5HSrVCzXw+d89RtmVYkricFsN4ITXhZYnAI
|
|
||||||
AryndaatuETXTDqFO+PgjU6X9N56DgfhTtZA660I9zI
|
|
||||||
-> ssh-ed25519 tDqJRg YyWweqs0fGEtC/t/lW2Mf8uSby7lg/p00tz51qchz2o
|
|
||||||
8bVaNX8O4+GOTvj+DVINnbQdLo0Os5nVwYygobJqLbI
|
|
||||||
-> .-grease
|
|
||||||
+TO+CNhkq/HSoBucxW7tIR6mZW6vKF/Zb1zhIBB8juSR0Tu8yw0JArAmWR5dJIRH
|
|
||||||
fDlE8JfUaY67j/KXN3ZhNvtVxzzmpK1HBG8Oii8brlVCSR6dDSLxqCHXQJo
|
|
||||||
--- 0CxvM54IJkhoH/NGTqvbcnwBi7k9txCFSFyoEk15eeM
|
|
||||||
D<EFBFBD>À/¡ö‘l,_öÌ(4 §{÷,^ò§ƒYª'ŠâB†«U»M±à‡^¤î2ßy‰n{Ü£ëßË
|
|
Binary file not shown.
Binary file not shown.
|
@ -18,8 +18,6 @@
|
||||||
"grafana-oauth_client_secret_file"
|
"grafana-oauth_client_secret_file"
|
||||||
"grafana-smtp_password_file"
|
"grafana-smtp_password_file"
|
||||||
"hedgedoc-environment_file"
|
"hedgedoc-environment_file"
|
||||||
"librenms-database_password_file"
|
|
||||||
"librenms-environment_file"
|
|
||||||
"mastodon-extra_env_file"
|
"mastodon-extra_env_file"
|
||||||
"mastodon-smtp-password"
|
"mastodon-smtp-password"
|
||||||
"netbox-environment_file"
|
"netbox-environment_file"
|
||||||
|
@ -29,7 +27,6 @@
|
||||||
"outline-oidc_client_secret_file"
|
"outline-oidc_client_secret_file"
|
||||||
"outline-smtp_password_file"
|
"outline-smtp_password_file"
|
||||||
"outline-storage_secret_key_file"
|
"outline-storage_secret_key_file"
|
||||||
"plausible-admin_user_password_file"
|
|
||||||
"plausible-secret_key_base_file"
|
"plausible-secret_key_base_file"
|
||||||
"plausible-smtp_password_file"
|
"plausible-smtp_password_file"
|
||||||
"pretalx-environment_file"
|
"pretalx-environment_file"
|
||||||
|
|
|
@ -1,13 +0,0 @@
|
||||||
# SPDX-FileCopyrightText: 2024 Ryan Lahfa <ryan.lahfa@dgnum.eu>
|
|
||||||
#
|
|
||||||
# SPDX-License-Identifier: EUPL-1.2
|
|
||||||
|
|
||||||
{ pkgs, ... }:
|
|
||||||
{
|
|
||||||
# Ask Ryan for administration
|
|
||||||
# as he's using one of his N phone numbers for the registration.
|
|
||||||
services.signald = {
|
|
||||||
enable = true;
|
|
||||||
};
|
|
||||||
environment.systemPackages = [ pkgs.signaldctl ];
|
|
||||||
}
|
|
|
@ -16,7 +16,7 @@ lib.extra.mkConfig {
|
||||||
"microvm-router01"
|
"microvm-router01"
|
||||||
"nvidia-tesla-k80"
|
"nvidia-tesla-k80"
|
||||||
"ollama"
|
"ollama"
|
||||||
"whisper"
|
# "whisper"
|
||||||
"proxmox"
|
"proxmox"
|
||||||
"networking"
|
"networking"
|
||||||
];
|
];
|
||||||
|
|
|
@ -17,7 +17,7 @@ in
|
||||||
services = {
|
services = {
|
||||||
netbox = {
|
netbox = {
|
||||||
enable = true;
|
enable = true;
|
||||||
package = pkgs.netbox_4_1;
|
package = pkgs.netbox_4_2;
|
||||||
secretKeyFile = "/dev/null";
|
secretKeyFile = "/dev/null";
|
||||||
listenAddress = "127.0.0.1";
|
listenAddress = "127.0.0.1";
|
||||||
plugins = p: [ p.netbox-qrcode ];
|
plugins = p: [ p.netbox-qrcode ];
|
||||||
|
|
|
@ -19,7 +19,6 @@
|
||||||
|
|
||||||
overlays.nix-pkgs = [
|
overlays.nix-pkgs = [
|
||||||
# Required packages
|
# Required packages
|
||||||
"django-allauth"
|
|
||||||
"django-allauth-ens"
|
"django-allauth-ens"
|
||||||
"django-wiki"
|
"django-wiki"
|
||||||
"loadcredential"
|
"loadcredential"
|
||||||
|
|
|
@ -82,7 +82,6 @@ let
|
||||||
"gist" # Opengist
|
"gist" # Opengist
|
||||||
"grafana" # Grafana
|
"grafana" # Grafana
|
||||||
"netbox-v2" # Netbox
|
"netbox-v2" # Netbox
|
||||||
"nms" # LibreNMS
|
|
||||||
"pads" # Hedgedoc
|
"pads" # Hedgedoc
|
||||||
"pass" # Vaultwarden
|
"pass" # Vaultwarden
|
||||||
"pdf" # Stirling PDF
|
"pdf" # Stirling PDF
|
||||||
|
|
|
@ -76,7 +76,7 @@
|
||||||
stateVersion = "24.11";
|
stateVersion = "24.11";
|
||||||
|
|
||||||
nixpkgs = {
|
nixpkgs = {
|
||||||
version = "24.11";
|
version = "25.05";
|
||||||
system = "nixos";
|
system = "nixos";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -121,7 +121,7 @@
|
||||||
];
|
];
|
||||||
|
|
||||||
nixpkgs = {
|
nixpkgs = {
|
||||||
version = "24.11";
|
version = "25.05";
|
||||||
system = "nixos";
|
system = "nixos";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
@ -139,7 +139,7 @@
|
||||||
stateVersion = "24.05";
|
stateVersion = "24.05";
|
||||||
|
|
||||||
nixpkgs = {
|
nixpkgs = {
|
||||||
version = "24.11";
|
version = "25.05";
|
||||||
system = "nixos";
|
system = "nixos";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
@ -157,7 +157,7 @@
|
||||||
stateVersion = "24.05";
|
stateVersion = "24.05";
|
||||||
|
|
||||||
nixpkgs = {
|
nixpkgs = {
|
||||||
version = "24.11";
|
version = "25.05";
|
||||||
system = "nixos";
|
system = "nixos";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
@ -170,7 +170,7 @@
|
||||||
stateVersion = "24.11";
|
stateVersion = "24.11";
|
||||||
|
|
||||||
nixpkgs = {
|
nixpkgs = {
|
||||||
version = "24.11";
|
version = "25.05";
|
||||||
system = "nixos";
|
system = "nixos";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -191,7 +191,7 @@
|
||||||
stateVersion = "24.11";
|
stateVersion = "24.11";
|
||||||
|
|
||||||
nixpkgs = {
|
nixpkgs = {
|
||||||
version = "24.11";
|
version = "25.05";
|
||||||
system = "nixos";
|
system = "nixos";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -214,7 +214,7 @@
|
||||||
sshKeys = [ "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFLF0mxSGitsDE3/YXfrHNjtOMUt4HT2MbryyUKPLSBI" ];
|
sshKeys = [ "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFLF0mxSGitsDE3/YXfrHNjtOMUt4HT2MbryyUKPLSBI" ];
|
||||||
|
|
||||||
nixpkgs = {
|
nixpkgs = {
|
||||||
version = "24.11";
|
version = "25.05";
|
||||||
system = "nixos";
|
system = "nixos";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -237,7 +237,7 @@
|
||||||
stateVersion = "24.11";
|
stateVersion = "24.11";
|
||||||
|
|
||||||
nixpkgs = {
|
nixpkgs = {
|
||||||
version = "24.11";
|
version = "unstable";
|
||||||
system = "nixos";
|
system = "nixos";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
@ -270,7 +270,7 @@
|
||||||
vm-cluster = "Hyperviseur Luj";
|
vm-cluster = "Hyperviseur Luj";
|
||||||
|
|
||||||
nixpkgs = {
|
nixpkgs = {
|
||||||
version = "24.11";
|
version = "25.05";
|
||||||
system = "nixos";
|
system = "nixos";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -289,7 +289,7 @@
|
||||||
stateVersion = "23.11";
|
stateVersion = "23.11";
|
||||||
|
|
||||||
nixpkgs = {
|
nixpkgs = {
|
||||||
version = "24.11";
|
version = "25.05";
|
||||||
system = "nixos";
|
system = "nixos";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -313,7 +313,7 @@
|
||||||
deployment.targetHost = "tower01.dgnum";
|
deployment.targetHost = "tower01.dgnum";
|
||||||
|
|
||||||
nixpkgs = {
|
nixpkgs = {
|
||||||
version = "24.11";
|
version = "25.05";
|
||||||
system = "nixos";
|
system = "nixos";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -351,7 +351,7 @@
|
||||||
vm-cluster = "Hyperviseur NPS";
|
vm-cluster = "Hyperviseur NPS";
|
||||||
|
|
||||||
nixpkgs = {
|
nixpkgs = {
|
||||||
version = "24.11";
|
version = "25.05";
|
||||||
system = "nixos";
|
system = "nixos";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
@ -367,7 +367,7 @@
|
||||||
vm-cluster = "Hyperviseur NPS";
|
vm-cluster = "Hyperviseur NPS";
|
||||||
|
|
||||||
nixpkgs = {
|
nixpkgs = {
|
||||||
version = "24.11";
|
version = "25.05";
|
||||||
system = "nixos";
|
system = "nixos";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
@ -383,7 +383,7 @@
|
||||||
vm-cluster = "Hyperviseur NPS";
|
vm-cluster = "Hyperviseur NPS";
|
||||||
|
|
||||||
nixpkgs = {
|
nixpkgs = {
|
||||||
version = "24.11";
|
version = "25.05";
|
||||||
system = "nixos";
|
system = "nixos";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -91,7 +91,6 @@ in
|
||||||
zfs = {
|
zfs = {
|
||||||
forceImportRoot = false;
|
forceImportRoot = false;
|
||||||
extraPools = cfg.zfsPools;
|
extraPools = cfg.zfsPools;
|
||||||
package = pkgs.zfs_2_1;
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
})
|
})
|
||||||
|
|
|
@ -26,10 +26,6 @@ with {
|
||||||
|
|
||||||
# pretalx env file option
|
# pretalx env file option
|
||||||
(local ./nixpkgs/01-pretalx-environment-file.patch)
|
(local ./nixpkgs/01-pretalx-environment-file.patch)
|
||||||
|
|
||||||
# Kanidm memberless groups provisionning
|
|
||||||
(local ./nixpkgs/07-25.05-kanidm-groups-module.patch)
|
|
||||||
(local ./nixpkgs/08-25.05-kanidm-groups-pkgs.patch)
|
|
||||||
];
|
];
|
||||||
|
|
||||||
"nixos-24.11" = [
|
"nixos-24.11" = [
|
||||||
|
|
|
@ -1,51 +0,0 @@
|
||||||
diff --git a/nixos/modules/services/security/kanidm.nix b/nixos/modules/services/security/kanidm.nix
|
|
||||||
index ab85eed34eea..48722af7332a 100644
|
|
||||||
--- a/nixos/modules/services/security/kanidm.nix
|
|
||||||
+++ b/nixos/modules/services/security/kanidm.nix
|
|
||||||
@@ -140,6 +140,9 @@ let
|
|
||||||
|
|
||||||
filterPresent = filterAttrs (_: v: v.present);
|
|
||||||
|
|
||||||
+ filterMemberless = filterAttrs (_: v: v.present && v.memberless);
|
|
||||||
+ filterMemberful = filterAttrs (_: v: v.present && !v.memberless);
|
|
||||||
+
|
|
||||||
provisionStateJson = pkgs.writeText "provision-state.json" (
|
|
||||||
builtins.toJSON { inherit (cfg.provision) groups persons systems; }
|
|
||||||
);
|
|
||||||
@@ -465,6 +468,12 @@ in
|
|
||||||
apply = unique;
|
|
||||||
default = [ ];
|
|
||||||
};
|
|
||||||
+
|
|
||||||
+ memberless = mkOption {
|
|
||||||
+ description = "Whether this group is considered memberless, i.e. the list of members is managed imperatively.";
|
|
||||||
+ type = types.bool;
|
|
||||||
+ default = false;
|
|
||||||
+ };
|
|
||||||
};
|
|
||||||
config.members = concatLists (
|
|
||||||
flip mapAttrsToList cfg.provision.persons (
|
|
||||||
@@ -791,12 +800,22 @@ in
|
|
||||||
person: personCfg:
|
|
||||||
assertGroupsKnown "services.kanidm.provision.persons.${person}.groups" personCfg.groups
|
|
||||||
))
|
|
||||||
++ (optionals (cfg.provision.extraJsonFile == null) (
|
|
||||||
- flip mapAttrsToList (filterPresent cfg.provision.groups) (
|
|
||||||
+ flip mapAttrsToList (filterMemberful cfg.provision.groups) (
|
|
||||||
group: groupCfg:
|
|
||||||
assertEntitiesKnown "services.kanidm.provision.groups.${group}.members" groupCfg.members
|
|
||||||
)
|
|
||||||
))
|
|
||||||
+ ++ (optionals (cfg.provision.extraJsonFile == null) (
|
|
||||||
+ flip lib.mapAttrsToList (filterMemberless cfg.provision.groups) (
|
|
||||||
+ group: groupCfg: {
|
|
||||||
+ assertion = cfg.provision.enable -> groupCfg.members == [ ];
|
|
||||||
+ message = ''
|
|
||||||
+ services.kanidm.groups.${group} is declared as memberless but contains members: ${toString groupCfg.members}
|
|
||||||
+ '';
|
|
||||||
+ }
|
|
||||||
+ )
|
|
||||||
+ ))
|
|
||||||
++ concatLists (
|
|
||||||
flip mapAttrsToList (filterPresent cfg.provision.systems.oauth2) (
|
|
||||||
oauth2: oauth2Cfg:
|
|
|
@ -1,104 +0,0 @@
|
||||||
diff --git a/pkgs/by-name/ka/kanidm-provision/01-memberless.patch b/pkgs/by-name/ka/kanidm-provision/01-memberless.patch
|
|
||||||
new file mode 100644
|
|
||||||
index 000000000000..b501a3f16828
|
|
||||||
--- /dev/null
|
|
||||||
+++ b/pkgs/by-name/ka/kanidm-provision/01-memberless.patch
|
|
||||||
@@ -0,0 +1,85 @@
|
|
||||||
+From ab3fa7d59b76658ba98ccf50c2910329896dab6f Mon Sep 17 00:00:00 2001
|
|
||||||
+From: Tom Hubrecht <tom@hubrecht.ovh>
|
|
||||||
+Date: Tue, 4 Feb 2025 14:32:43 +0100
|
|
||||||
+Subject: [PATCH] feat: Allow declaring memberless groups
|
|
||||||
+
|
|
||||||
+When a group is "memberless", then the list of members is left intact,
|
|
||||||
+which allows managing it imperatively.
|
|
||||||
+---
|
|
||||||
+ src/main.rs | 2 +-
|
|
||||||
+ src/state.rs | 2 ++
|
|
||||||
+ tests/kanidm.nix | 18 +++++++++++++++++-
|
|
||||||
+ 3 files changed, 20 insertions(+), 2 deletions(-)
|
|
||||||
+
|
|
||||||
+diff --git a/src/main.rs b/src/main.rs
|
|
||||||
+index 206a86a..6e48f59 100644
|
|
||||||
+--- a/src/main.rs
|
|
||||||
++++ b/src/main.rs
|
|
||||||
+@@ -406,7 +406,7 @@ fn main() -> Result<()> {
|
|
||||||
+ // Sync group members
|
|
||||||
+ log_status("Syncing group members");
|
|
||||||
+ for (name, group) in &state.groups {
|
|
||||||
+- if group.present {
|
|
||||||
++ if group.present && !group.memberless {
|
|
||||||
+ update_attrs!(kanidm_client, ENDPOINT_GROUP, &existing_groups, &name, [
|
|
||||||
+ "member": group.members.clone(),
|
|
||||||
+ ]);
|
|
||||||
+diff --git a/src/state.rs b/src/state.rs
|
|
||||||
+index 206c6f4..a8bfba2 100644
|
|
||||||
+--- a/src/state.rs
|
|
||||||
++++ b/src/state.rs
|
|
||||||
+@@ -10,6 +10,8 @@ pub struct Group {
|
|
||||||
+ #[serde(default = "default_true")]
|
|
||||||
+ pub present: bool,
|
|
||||||
+ pub members: Vec<String>,
|
|
||||||
++ #[serde(default = "default_false")]
|
|
||||||
++ pub memberless: bool,
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ #[derive(Debug, Deserialize)]
|
|
||||||
+diff --git a/tests/kanidm.nix b/tests/kanidm.nix
|
|
||||||
+index a28beae..cb20257 100644
|
|
||||||
+--- a/tests/kanidm.nix
|
|
||||||
++++ b/tests/kanidm.nix
|
|
||||||
+@@ -91,6 +91,8 @@ let
|
|
||||||
+ };
|
|
||||||
+
|
|
||||||
+ filterPresent = lib.filterAttrs (_: v: v.present);
|
|
||||||
++ filterMemberless = lib.filterAttrs (_: v: v.present && v.memberless);
|
|
||||||
++ filterMemberful = lib.filterAttrs (_: v: v.present && !v.memberless);
|
|
||||||
+
|
|
||||||
+ provisionStateJson = pkgs.writeText "provision-state.json" (
|
|
||||||
+ builtins.toJSON { inherit (cfg.provision) groups persons systems; }
|
|
||||||
+@@ -391,6 +393,12 @@ in
|
|
||||||
+ apply = lib.unique;
|
|
||||||
+ default = [ ];
|
|
||||||
+ };
|
|
||||||
++
|
|
||||||
++ memberless = lib.mkOption {
|
|
||||||
++ description = "Whether this group is considered memberless, i.e. the list of members is managed imperatively.";
|
|
||||||
++ type = lib.types.bool;
|
|
||||||
++ default = false;
|
|
||||||
++ };
|
|
||||||
+ };
|
|
||||||
+ config.members = lib.concatLists (
|
|
||||||
+ lib.flip lib.mapAttrsToList cfg.provision.persons (
|
|
||||||
+@@ -708,10 +716,18 @@ in
|
|
||||||
+ person: personCfg:
|
|
||||||
+ assertGroupsKnown "services.kanidm.provision.persons.${person}.groups" personCfg.groups
|
|
||||||
+ )
|
|
||||||
+- ++ lib.flip lib.mapAttrsToList (filterPresent cfg.provision.groups) (
|
|
||||||
++ ++ lib.flip lib.mapAttrsToList (filterMemberful cfg.provision.groups) (
|
|
||||||
+ group: groupCfg:
|
|
||||||
+ assertEntitiesKnown "services.kanidm.provision.groups.${group}.members" groupCfg.members
|
|
||||||
+ )
|
|
||||||
++ ++ lib.flip lib.mapAttrsToList (filterMemberless cfg.provision.groups) (
|
|
||||||
++ group: groupCfg: {
|
|
||||||
++ assertion = cfg.provision.enable -> groupCfg.members == [ ];
|
|
||||||
++ message = ''
|
|
||||||
++ services.kanidm.groups.${group} is declared as memberless but contains members: ${toString groupCfg.members}
|
|
||||||
++ '';
|
|
||||||
++ }
|
|
||||||
++ )
|
|
||||||
+ ++ lib.concatLists (
|
|
||||||
+ lib.flip lib.mapAttrsToList (filterPresent cfg.provision.systems.oauth2) (
|
|
||||||
+ oauth2: oauth2Cfg:
|
|
||||||
diff --git a/pkgs/by-name/ka/kanidm-provision/package.nix b/pkgs/by-name/ka/kanidm-provision/package.nix
|
|
||||||
index 63d7e85ba8a8..5ebd69cb91ee 100644
|
|
||||||
--- a/pkgs/by-name/ka/kanidm-provision/package.nix
|
|
||||||
+++ b/pkgs/by-name/ka/kanidm-provision/package.nix
|
|
||||||
@@ -18,4 +18,8 @@ rustPlatform.buildRustPackage rec {
|
|
||||||
hash = "sha256-m3bF4wFPVRc2E+E/pZc3js9T4rYbTejo/FFpysytWKw=";
|
|
||||||
};
|
|
||||||
|
|
||||||
+ patches = [
|
|
||||||
+ ./01-memberless.patch
|
|
||||||
+ ];
|
|
||||||
+
|
|
||||||
useFetchCargoVendor = true;
|
|
Loading…
Add table
Add a link
Reference in a new issue