forked from DGNum/infrastructure
feat(compute01): Deploy librenms on nms.dgnum.eu
This commit is contained in:
parent
69ecadbbd1
commit
42e1d6dcd7
7 changed files with 853 additions and 0 deletions
|
@ -13,6 +13,7 @@ lib.extra.mkConfig {
|
||||||
"hedgedoc"
|
"hedgedoc"
|
||||||
"k-radius"
|
"k-radius"
|
||||||
"kanidm"
|
"kanidm"
|
||||||
|
"librenms"
|
||||||
"mastodon"
|
"mastodon"
|
||||||
"nextcloud"
|
"nextcloud"
|
||||||
"outline"
|
"outline"
|
||||||
|
|
41
machines/compute01/librenms/default.nix
Normal file
41
machines/compute01/librenms/default.nix
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
{ 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-2RgtMXQp4fTE+WloO36rtfytO4Sh2q0plt8WkWxEGHI=";
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
hostname = host;
|
||||||
|
|
||||||
|
settings = { };
|
||||||
|
|
||||||
|
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" ];
|
||||||
|
}
|
101
machines/compute01/librenms/kanidm.patch
Normal file
101
machines/compute01/librenms/kanidm.patch
Normal file
|
@ -0,0 +1,101 @@
|
||||||
|
diff --git a/composer.json b/composer.json
|
||||||
|
index 13571c07c..dbe810a57 100644
|
||||||
|
--- a/composer.json
|
||||||
|
+++ b/composer.json
|
||||||
|
@@ -11,6 +11,12 @@
|
||||||
|
"snmp",
|
||||||
|
"distributed"
|
||||||
|
],
|
||||||
|
+ "repositories": [
|
||||||
|
+ {
|
||||||
|
+ "type": "vcs",
|
||||||
|
+ "url": "https://github.com/Tom-Hubrecht/Kanidm"
|
||||||
|
+ }
|
||||||
|
+ ],
|
||||||
|
"homepage": "https://www.librenms.org/",
|
||||||
|
"license": "GPL-3.0-or-later",
|
||||||
|
"require": {
|
||||||
|
@@ -49,6 +55,7 @@
|
||||||
|
"phpmailer/phpmailer": "~6.0",
|
||||||
|
"predis/predis": "^2.0",
|
||||||
|
"silber/bouncer": "^1.0",
|
||||||
|
+ "socialiteproviders/kanidm": "^0.1.4",
|
||||||
|
"socialiteproviders/manager": "^4.3",
|
||||||
|
"spatie/laravel-ignition": "^2.0",
|
||||||
|
"symfony/yaml": "^6.2",
|
||||||
|
diff --git a/composer.lock b/composer.lock
|
||||||
|
index b26090101..aa1fd3cef 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": "21dbcfec63eafb1ae9172473314a57f8",
|
||||||
|
+ "content-hash": "16c250180b65a1f71acd5653914d7037",
|
||||||
|
"packages": [
|
||||||
|
{
|
||||||
|
"name": "amenadiel/jpgraph",
|
||||||
|
@@ -5244,6 +5244,55 @@
|
||||||
|
},
|
||||||
|
"time": "2023-02-10T16:47:25+00:00"
|
||||||
|
},
|
||||||
|
+ {
|
||||||
|
+ "name": "socialiteproviders/kanidm",
|
||||||
|
+ "version": "v0.1.4",
|
||||||
|
+ "source": {
|
||||||
|
+ "type": "git",
|
||||||
|
+ "url": "https://github.com/Tom-Hubrecht/Kanidm.git",
|
||||||
|
+ "reference": "b87d75b8342e00c46ef1c29c42e92b629bb206b1"
|
||||||
|
+ },
|
||||||
|
+ "dist": {
|
||||||
|
+ "type": "zip",
|
||||||
|
+ "url": "https://api.github.com/repos/Tom-Hubrecht/Kanidm/zipball/b87d75b8342e00c46ef1c29c42e92b629bb206b1",
|
||||||
|
+ "reference": "b87d75b8342e00c46ef1c29c42e92b629bb206b1",
|
||||||
|
+ "shasum": ""
|
||||||
|
+ },
|
||||||
|
+ "require": {
|
||||||
|
+ "ext-json": "*",
|
||||||
|
+ "php": "^8.0",
|
||||||
|
+ "socialiteproviders/manager": "^4.3"
|
||||||
|
+ },
|
||||||
|
+ "type": "library",
|
||||||
|
+ "autoload": {
|
||||||
|
+ "psr-4": {
|
||||||
|
+ "SocialiteProviders\\Kanidm\\": ""
|
||||||
|
+ }
|
||||||
|
+ },
|
||||||
|
+ "license": [
|
||||||
|
+ "MIT"
|
||||||
|
+ ],
|
||||||
|
+ "authors": [
|
||||||
|
+ {
|
||||||
|
+ "name": "Tom Hubrecht",
|
||||||
|
+ "email": "tom@hubrecht.ovh"
|
||||||
|
+ }
|
||||||
|
+ ],
|
||||||
|
+ "description": "Kanidm OAuth2 Provider for Laravel Socialite",
|
||||||
|
+ "keywords": [
|
||||||
|
+ "kanidm",
|
||||||
|
+ "laravel",
|
||||||
|
+ "oauth",
|
||||||
|
+ "provider",
|
||||||
|
+ "socialite"
|
||||||
|
+ ],
|
||||||
|
+ "support": {
|
||||||
|
+ "issues": "https://github.com/socialiteproviders/providers/issues",
|
||||||
|
+ "source": "https://github.com/socialiteproviders/providers",
|
||||||
|
+ "docs": "https://socialiteproviders.com/kanidm"
|
||||||
|
+ },
|
||||||
|
+ "time": "2024-02-18T14:12:08+00:00"
|
||||||
|
+ },
|
||||||
|
{
|
||||||
|
"name": "socialiteproviders/manager",
|
||||||
|
"version": "v4.3.0",
|
||||||
|
@@ -13357,5 +13406,5 @@
|
||||||
|
"ext-zlib": "*"
|
||||||
|
},
|
||||||
|
"platform-dev": [],
|
||||||
|
- "plugin-api-version": "2.3.0"
|
||||||
|
+ "plugin-api-version": "2.6.0"
|
||||||
|
}
|
684
machines/compute01/librenms/module.nix
Normal file
684
machines/compute01/librenms/module.nix
Normal file
|
@ -0,0 +1,684 @@
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
}
|
24
machines/compute01/secrets/librenms-database_password_file
Normal file
24
machines/compute01/secrets/librenms-database_password_file
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
age-encryption.org/v1
|
||||||
|
-> ssh-ed25519 tDqJRg F6kru2M2ZD++ylqZ5oRwHa+zz/vO+y0ixCB7oNGt3no
|
||||||
|
jzeyn2DIiRMS6pUyAxOFmsawWhXCPWJxAE73HNpfjMI
|
||||||
|
-> ssh-ed25519 jIXfPA lH3MYyh0uy32pAwTWeMRM1X8ThIGccfH4CGUNeO/ezY
|
||||||
|
R4D0dxxPsgrC63gTTae4uLJ8J5Kf4ZetIn4Yx4RVo+0
|
||||||
|
-> ssh-ed25519 QlRB9Q tOTcm1/j5R7lq6jWTXS/WuQBWps2pmI0i+tzwqvvQkQ
|
||||||
|
n/+GFXwdAwVvPv6wEOBRwDzQBG8vKooCWIUPBRsxE/c
|
||||||
|
-> ssh-ed25519 r+nK/Q ZTzwGvZEnw578JC8ROqVaG2ejCpHSkbhuLZLu8sxMWk
|
||||||
|
0pWfDKzeLPpUd2+RdkXOvMhQaAXK7AHgOMOkPcjQP9E
|
||||||
|
-> ssh-rsa krWCLQ
|
||||||
|
RIkTbc41aHXyybIJw3mMww5b46pb5rhjEvV8w+cU4vb7xaPt9fYTxPQa8eUZ28md
|
||||||
|
dwp11I2XQ/ujt/ECzXcgXboOVvd1GVgjNzJQhgXVJ96AC9Q/Jh8VXLW0/gxNvVjA
|
||||||
|
L54RWgQUo7EuFcFfxQksfblXIo4lNrDwu+5R/YkWs9NRMAgTDJYL13s4oUKykQ1F
|
||||||
|
SmZ0wJc+h42xH/+RZtq4Y65twbLkMzfM6BcwX+veR+AEI1FOtaACUmShePFyHdqT
|
||||||
|
uMdr6u9mxdS3zvB3WYLkVGpOSgkiFlsE7M7gXz8qFMMcd2aDs/Kb3oZ+nijRM9s1
|
||||||
|
HUt9MzwAPRUHN/egcmQ0QQ
|
||||||
|
-> ssh-ed25519 /vwQcQ EvwZHCvEyMoMAupu0K3a8HJq22L+v9w4Slvf40mpaz4
|
||||||
|
1n9tK86NsSv63llpifEEovq6MJSCbvaPX0SK7sxh1TA
|
||||||
|
-> ssh-ed25519 0R97PA r8hpgykfbDR5sUbHFyWqELUQ87k1oQrACo3iHqwmWFg
|
||||||
|
56Yg1iRQKxa57+eAekHj8faRX/FbSrtmII79HlJjoxs
|
||||||
|
-> ssh-ed25519 JGx7Ng ELVGzyFAxq1tUzmMGp8TMD1nk24KHTpGf0QhVw7MWm0
|
||||||
|
3FfQf6psLRkz2j80CUHS3DKcPhQ3ObK0VZ+ZW3x0YxY
|
||||||
|
--- a9E7zbh0zWgapnThLpfI6nlQU8feDbz3WX/52I5zi0E
|
||||||
|
&vcGô•ÈÛŒ•Pš ëÚ}cH· êl/¾n°×%Þ‹ä¥Â †ÍÌ‚ÀŽ-¦eqkà³÷Ã<C3B7>‹
|
BIN
machines/compute01/secrets/librenms-environment_file
Normal file
BIN
machines/compute01/secrets/librenms-environment_file
Normal file
Binary file not shown.
|
@ -6,6 +6,8 @@ in
|
||||||
lib.setDefault { inherit publicKeys; } [
|
lib.setDefault { inherit publicKeys; } [
|
||||||
"ds_fr-secret_file"
|
"ds_fr-secret_file"
|
||||||
"hedgedoc-environment_file"
|
"hedgedoc-environment_file"
|
||||||
|
"librenms-database_password_file"
|
||||||
|
"librenms-environment_file"
|
||||||
"mastodon-extra_env_file"
|
"mastodon-extra_env_file"
|
||||||
"nextcloud-adminpass_file"
|
"nextcloud-adminpass_file"
|
||||||
"nextcloud-s3_secret_file"
|
"nextcloud-s3_secret_file"
|
||||||
|
|
Loading…
Reference in a new issue