feat(shell): Add pre-commit hooks and reformat the repo

This commit is contained in:
Tom Hubrecht 2024-02-02 10:51:31 +01:00
parent 988c44d461
commit 5e3819c9b2
91 changed files with 3772 additions and 2282 deletions

1
.pre-commit-config.yaml Symbolic link
View file

@ -0,0 +1 @@
/nix/store/sbc33iwjwgwj0cklac3qjffvi93i723k-pre-commit-config.json

93
default.nix Normal file
View file

@ -0,0 +1,93 @@
/* Copyright :
- Maurice Debray <maurice.debray@dgnum.eu> 2023
- Tom Hubrecht <tom.hubrecht@dgnum.eu> 2023
Ce logiciel est un programme informatique servant à déployer des
configurations de serveurs via NixOS.
Ce logiciel est régi par la licence CeCILL soumise au droit français et
respectant les principes de diffusion des logiciels libres. Vous pouvez
utiliser, modifier et/ou redistribuer ce programme sous les conditions
de la licence CeCILL telle que diffusée par le CEA, le CNRS et l'INRIA
sur le site "http://www.cecill.info".
En contrepartie de l'accessibilité au code source et des droits de copie,
de modification et de redistribution accordés par cette licence, il n'est
offert aux utilisateurs qu'une garantie limitée. Pour les mêmes raisons,
seule une responsabilité restreinte pèse sur l'auteur du programme, le
titulaire des droits patrimoniaux et les concédants successifs.
A cet égard l'attention de l'utilisateur est attirée sur les risques
associés au chargement, à l'utilisation, à la modification et/ou au
développement et à la reproduction du logiciel par l'utilisateur étant
donné sa spécificité de logiciel libre, qui peut le rendre complexe à
manipuler et qui le réserve donc à des développeurs et des professionnels
avertis possédant des connaissances informatiques approfondies. Les
utilisateurs sont donc invités à charger et tester l'adéquation du
logiciel à leurs besoins dans des conditions permettant d'assurer la
sécurité de leurs systèmes et ou de leurs données et, plus généralement,
à l'utiliser et l'exploiter dans les mêmes conditions de sécurité.
Le fait que vous puissiez accéder à cet en-tête signifie que vous avez
pris connaissance de la licence CeCILL, et que vous en avez accepté les
termes.
*/
let
sources = import ./npins;
pkgs = import sources.nixpkgs { };
pre-commit-check = (import sources.pre-commit-hooks).run {
src = ./.;
hooks = {
# Nix Hooks
statix.enable = true;
deadnix.enable = true;
rfc101 = {
enable = true;
name = "RFC-101 formatting";
entry = "${pkgs.lib.getExe pkgs.nixfmt-rfc-style}";
files = "\\.nix$";
};
# Misc Hooks
commitizen.enable = true;
};
};
in
{
shells = {
default = pkgs.mkShell {
name = "dgnum-infra";
packages =
(
with pkgs;
[
npins
colmena
nixos-generators
]
++ (builtins.map (p: callPackage p { }) [ (sources.disko + "/package.nix") ])
)
++ (import ./scripts { inherit pkgs; });
shellHook = ''
${pre-commit-check.shellHook}
'';
preferLocalBuild = true;
};
pre-commit = pkgs.mkShell {
name = "pre-commit-shell";
shellHook = ''
${pre-commit-check.shellHook}
'';
};
};
}

View file

@ -1,4 +1,5 @@
{ config, pkgs, ... }: { { config, pkgs, ... }:
{
imports = [ ./secrets ]; imports = [ ./secrets ];
services = { services = {
@ -8,8 +9,7 @@
listenAddress = "127.0.0.1"; listenAddress = "127.0.0.1";
settings = { settings = {
ALLOWED_HOSTS = [ "netbox.dgnum.sinavir.fr" ]; ALLOWED_HOSTS = [ "netbox.dgnum.sinavir.fr" ];
REMOTE_AUTH_BACKEND = REMOTE_AUTH_BACKEND = "social_core.backends.open_id_connect.OpenIdConnectAuth";
"social_core.backends.open_id_connect.OpenIdConnectAuth";
}; };
extraConfig = '' extraConfig = ''
@ -27,12 +27,8 @@
enableACME = true; enableACME = true;
forceSSL = true; forceSSL = true;
locations."/".proxyPass = locations."/".proxyPass = "http://${config.services.netbox.listenAddress}:${builtins.toString config.services.netbox.port}";
"http://${config.services.netbox.listenAddress}:${ locations."/static/".alias = "${config.services.netbox.dataDir}/static/";
builtins.toString config.services.netbox.port
}";
locations."/static/".alias =
"${config.services.netbox.dataDir}/static/";
}; };
}; };
@ -50,5 +46,8 @@
}; };
users.users.nginx.extraGroups = [ "netbox" ]; users.users.nginx.extraGroups = [ "netbox" ];
networking.firewall.allowedTCPPorts = [ 443 80 ]; networking.firewall.allowedTCPPorts = [
443
80
];
} }

View file

@ -6,10 +6,15 @@ let
inherit ((import ../../../meta).members) groups; inherit ((import ../../../meta).members) groups;
publicKeys = lib.splitString "\n" publicKeys =
(builtins.readFile (./maurice.keys)) # maurice servers' keys lib.splitString "\n" (builtins.readFile (./maurice.keys)) # maurice servers' keys
++ nix-lib.getAllKeys (groups.netbox ++ groups.root); ++ nix-lib.getAllKeys (groups.netbox ++ groups.root);
in { in
"netbox.age" = { inherit publicKeys; }; {
"netbox_env.age" = { inherit publicKeys; }; "netbox.age" = {
inherit publicKeys;
};
"netbox_env.age" = {
inherit publicKeys;
};
} }

View file

@ -6,8 +6,7 @@ let
patch = import sources.nix-patches { patchFile = ./patches; }; patch = import sources.nix-patches { patchFile = ./patches; };
mkNode = node: mkNode = node: _: {
{ name, nodes, pkgs, ... }: {
# Import the base configuration for each node # Import the base configuration for each node
imports = builtins.map (lib.mkRel ./machines/${node}) [ imports = builtins.map (lib.mkRel ./machines/${node}) [
"_configuration.nix" "_configuration.nix"
@ -28,10 +27,13 @@ let
nixpkgs.config.allowUnfree = true; nixpkgs.config.allowUnfree = true;
# Use the stateVersion declared in the metadata # Use the stateVersion declared in the metadata
system = { inherit (metadata.nodes.${node}) stateVersion; }; system = {
inherit (metadata.nodes.${node}) stateVersion;
};
}; };
mkNixpkgs = node: mkNixpkgs =
node:
patch.mkNixpkgsSrc rec { patch.mkNixpkgsSrc rec {
src = sources.${version}; src = sources.${version};
version = "nixos-${metadata.nodes.${node}.nixpkgs}"; version = "nixos-${metadata.nodes.${node}.nixpkgs}";
@ -42,9 +44,12 @@ let
### ###
# Function to create arguments based on the node # Function to create arguments based on the node
# #
mkArgs = node: mkArgs =
let lib' = (mkNixpkgs' node).lib; node:
in { let
lib' = (mkNixpkgs' node).lib;
in
{
lib = import sources.nix-lib { lib = import sources.nix-lib {
lib = lib'; lib = lib';
keysRoot = ./keys; keysRoot = ./keys;
@ -52,8 +57,8 @@ let
}; };
nodes = builtins.attrNames metadata.nodes; nodes = builtins.attrNames metadata.nodes;
in
in { {
meta = { meta = {
nodeNixpkgs = lib.mapSingleFuse mkNixpkgs' nodes; nodeNixpkgs = lib.mapSingleFuse mkNixpkgs' nodes;
@ -65,8 +70,9 @@ in {
nodeSpecialArgs = lib.mapSingleFuse mkArgs nodes; nodeSpecialArgs = lib.mapSingleFuse mkArgs nodes;
}; };
defaults = { pkgs, ... }: { defaults = _: {
# Import the default modules # Import the default modules
imports = [ ./modules ]; imports = [ ./modules ];
}; };
} // (lib.mapSingleFuse mkNode nodes) }
// (lib.mapSingleFuse mkNode nodes)

View file

@ -34,5 +34,6 @@ in
}; };
users.users.root.openssh.authorizedKeys.keyFiles = users.users.root.openssh.authorizedKeys.keyFiles =
builtins.map (m: dgn-lib.mkRel ../keys "${m}.keys") dgn-members; builtins.map (m: dgn-lib.mkRel ../keys "${m}.keys")
dgn-members;
} }

View file

@ -2,4 +2,7 @@ let
inherit (import ../npins) nixpkgs; inherit (import ../npins) nixpkgs;
in in
(import nixpkgs { }).srcOnly { name = "nixpkgs-for-iso"; src = nixpkgs; } (import nixpkgs { }).srcOnly {
name = "nixpkgs-for-iso";
src = nixpkgs;
}

View file

@ -3,20 +3,24 @@ _:
let let
sources = import ../npins; sources = import ../npins;
nix-lib = (import sources.nix-lib { nix-lib =
(import sources.nix-lib {
inherit ((import sources.nixpkgs { })) lib; inherit ((import sources.nixpkgs { })) lib;
keysRoot = ../keys; keysRoot = ../keys;
}).extra; }).extra;
in
in nix-lib // (with nix-lib; { nix-lib
// (with nix-lib; {
# Get publickeys associated to a node # Get publickeys associated to a node
getNodeKeys = node: getNodeKeys =
node:
let let
meta = import ../meta; meta = import ../meta;
names = names =
builtins.foldl' (names: group: names ++ meta.members.groups.${group}) builtins.foldl' (names: group: names ++ meta.members.groups.${group})
(meta.nodes.${node}.admins ++ [ "/machines/${node}" ]) (meta.nodes.${node}.admins ++ [ "/machines/${node}" ])
(meta.nodes.${node}.adminGroups ++ [ "root" ]); (meta.nodes.${node}.adminGroups ++ [ "root" ]);
in getAllKeys names; in
getAllKeys names;
}) })

View file

@ -29,6 +29,5 @@
fsType = "vfat"; fsType = "vfat";
}; };
swapDevices = swapDevices = [ { device = "/dev/disk/by-uuid/30547280-00e9-4ee1-8a07-d116590d9fbf"; } ];
[{ device = "/dev/disk/by-uuid/30547280-00e9-4ee1-8a07-d116590d9fbf"; }];
} }

View file

@ -1,7 +1,9 @@
{ config, ... }: { config, ... }:
let host = "demarches.dgnum.eu"; let
in { host = "demarches.dgnum.eu";
in
{
imports = [ ./module.nix ]; imports = [ ./module.nix ];
services.demarches-simplifiees = { services.demarches-simplifiees = {
@ -62,5 +64,7 @@ in {
}; };
}; };
age-secrets.matches."^ds_fr-.*$" = { owner = "ds-fr"; }; age-secrets.matches."^ds_fr-.*$" = {
owner = "ds-fr";
};
} }

View file

@ -31,15 +31,26 @@
# The fact that you are presently reading this means that you have had # The fact that you are presently reading this means that you have had
# knowledge of the CeCILL license and that you accept its terms. # knowledge of the CeCILL license and that you accept its terms.
{ config, lib, pkgs, ... }: {
config,
lib,
pkgs,
...
}:
let let
inherit (lib) inherit (lib)
mdDoc mkDefault mkEnableOption mkIf mkOption mdDoc
mkDefault
mkEnableOption
mkIf
mkOption
optional optionalString optional
optionalString
types; types
;
cfg = config.services.demarches-simplifiees; cfg = config.services.demarches-simplifiees;
@ -64,16 +75,14 @@ let
$SUDO ${cfg.package}/bin/$BIN "$@" $SUDO ${cfg.package}/bin/$BIN "$@"
''; '';
in
in { {
options.services.demarches-simplifiees = { options.services.demarches-simplifiees = {
enable = mkEnableOption "demarches-simplifiees."; enable = mkEnableOption "demarches-simplifiees.";
package = mkOption { package = mkOption {
type = types.package; type = types.package;
default = pkgs.callPackage ./package { default = pkgs.callPackage ./package { inherit (cfg) initialDeploymentDate dataDir logDir; };
inherit (cfg) initialDeploymentDate dataDir logDir;
};
}; };
user = mkOption { user = mkOption {
@ -127,15 +136,17 @@ in {
description = "Demarches Simplifiees setup"; description = "Demarches Simplifiees setup";
wantedBy = [ "multi-user.target" ]; wantedBy = [ "multi-user.target" ];
path = [ pkgs.bash ds-fr ]; path = [
pkgs.bash
ds-fr
];
after = [ "postgresql.service" ]; after = [ "postgresql.service" ];
serviceConfig = { serviceConfig = {
Type = "oneshot"; Type = "oneshot";
User = cfg.user; User = cfg.user;
Group = cfg.group; Group = cfg.group;
EnvironmentFile = [ env ] EnvironmentFile = [ env ] ++ (optional (cfg.secretFile != null) cfg.secretFile);
++ (optional (cfg.secretFile != null) cfg.secretFile);
StateDirectory = mkIf (cfg.dataDir == "/var/lib/ds-fr") "ds-fr"; StateDirectory = mkIf (cfg.dataDir == "/var/lib/ds-fr") "ds-fr";
LogsDirectory = mkIf (cfg.logDir == "/var/log/ds-fr") "ds-fr"; LogsDirectory = mkIf (cfg.logDir == "/var/log/ds-fr") "ds-fr";
}; };
@ -155,14 +166,19 @@ in {
ds-fr-work = { ds-fr-work = {
description = "Demarches Simplifiees work service"; description = "Demarches Simplifiees work service";
wantedBy = [ "multi-user.target" "ds-fr.service" ]; wantedBy = [
after = [ "network.target" "ds-fr-setup.service" ]; "multi-user.target"
"ds-fr.service"
];
after = [
"network.target"
"ds-fr-setup.service"
];
requires = [ "ds-fr-setup.service" ]; requires = [ "ds-fr-setup.service" ];
serviceConfig = { serviceConfig = {
ExecStart = "${ds-fr}/bin/ds-fr rails jobs:work"; ExecStart = "${ds-fr}/bin/ds-fr rails jobs:work";
EnvironmentFile = [ env ] EnvironmentFile = [ env ] ++ (optional (cfg.secretFile != null) cfg.secretFile);
++ (optional (cfg.secretFile != null) cfg.secretFile);
User = cfg.user; User = cfg.user;
Group = cfg.group; Group = cfg.group;
StateDirectory = mkIf (cfg.dataDir == "/var/lib/ds-fr") "ds-fr"; StateDirectory = mkIf (cfg.dataDir == "/var/lib/ds-fr") "ds-fr";
@ -174,15 +190,17 @@ in {
description = "Demarches Simplifiees web service"; description = "Demarches Simplifiees web service";
wantedBy = [ "multi-user.target" ]; wantedBy = [ "multi-user.target" ];
after = [ "network.target" "ds-fr-setup.service" ]; after = [
"network.target"
"ds-fr-setup.service"
];
requires = [ "ds-fr-setup.service" ]; requires = [ "ds-fr-setup.service" ];
path = [ pkgs.imagemagick ]; path = [ pkgs.imagemagick ];
serviceConfig = { serviceConfig = {
ExecStart = "${ds-fr}/bin/ds-fr rails server"; ExecStart = "${ds-fr}/bin/ds-fr rails server";
Environment = [ "RAILS_QUEUE_ADAPTER=delayed_job" ]; Environment = [ "RAILS_QUEUE_ADAPTER=delayed_job" ];
EnvironmentFile = [ env ] EnvironmentFile = [ env ] ++ (optional (cfg.secretFile != null) cfg.secretFile);
++ (optional (cfg.secretFile != null) cfg.secretFile);
User = cfg.user; User = cfg.user;
Group = cfg.group; Group = cfg.group;
StateDirectory = mkIf (cfg.dataDir == "/var/lib/ds-fr") "ds-fr"; StateDirectory = mkIf (cfg.dataDir == "/var/lib/ds-fr") "ds-fr";
@ -192,7 +210,8 @@ in {
}; };
services = { services = {
demarches-simplifiees.settings = (builtins.mapAttrs (_: mkDefault) { demarches-simplifiees.settings =
(builtins.mapAttrs (_: mkDefault) {
RAILS_ENV = "production"; RAILS_ENV = "production";
RAILS_ROOT = builtins.toString cfg.package; RAILS_ROOT = builtins.toString cfg.package;
@ -346,7 +365,8 @@ in {
# Siret number used for API Entreprise, by default we use SIRET from dinum # Siret number used for API Entreprise, by default we use SIRET from dinum
API_ENTREPRISE_DEFAULT_SIRET = "put_your_own_siret"; API_ENTREPRISE_DEFAULT_SIRET = "put_your_own_siret";
}) // { })
// {
# Database credentials # Database credentials
DB_DATABASE = "ds-fr"; DB_DATABASE = "ds-fr";
DB_USERNAME = cfg.user; DB_USERNAME = cfg.user;
@ -368,8 +388,7 @@ in {
ensureDBOwnership = true; ensureDBOwnership = true;
}; };
extraPlugins = with config.services.postgresql.package.pkgs; extraPlugins = with config.services.postgresql.package.pkgs; [ postgis ];
[ postgis ];
}; };
nginx = { nginx = {
@ -381,7 +400,9 @@ in {
root = "${cfg.package}/public/"; root = "${cfg.package}/public/";
locations."/".tryFiles = "$uri @proxy"; locations."/".tryFiles = "$uri @proxy";
locations."@proxy" = { proxyPass = "http://127.0.0.1:3000"; }; locations."@proxy" = {
proxyPass = "http://127.0.0.1:3000";
};
}; };
}; };
}; };

View file

@ -1,6 +1,18 @@
{ lib, stdenv, fetchFromGitHub, git, fetchYarnDeps, yarn, fixup_yarn_lock, imagemagick {
, nodejs, ruby_3_2, bundlerEnv, logDir ? "/var/log/ds-fr" lib,
, dataDir ? "/var/lib/ds-fr", initialDeploymentDate ? "17941030" }: stdenv,
fetchFromGitHub,
git,
fetchYarnDeps,
yarn,
fixup_yarn_lock,
nodejs,
ruby_3_2,
bundlerEnv,
logDir ? "/var/log/ds-fr",
dataDir ? "/var/lib/ds-fr",
initialDeploymentDate ? "17941030",
}:
let let
pname = "ds-fr"; pname = "ds-fr";
@ -43,7 +55,12 @@ let
}; };
buildInputs = [ rubyEnv ]; buildInputs = [ rubyEnv ];
nativeBuildInputs = [ fixup_yarn_lock nodejs yarn rubyEnv.wrappedRuby ]; nativeBuildInputs = [
fixup_yarn_lock
nodejs
yarn
rubyEnv.wrappedRuby
];
RAILS_ENV = "production"; RAILS_ENV = "production";
NODE_ENV = "dev"; NODE_ENV = "dev";
@ -53,8 +70,9 @@ let
./patches/build.patch ./patches/build.patch
]; ];
postPatch = builtins.concatStringsSep "\n" postPatch = builtins.concatStringsSep "\n" (
(builtins.map (p: "${git}/bin/git apply -p1 < ${p}") dgn-patches); builtins.map (p: "${git}/bin/git apply -p1 < ${p}") dgn-patches
);
OTP_SECRET_KEY = "precompile_placeholder"; OTP_SECRET_KEY = "precompile_placeholder";
SECRET_KEY_BASE = "precompile_placeholder"; SECRET_KEY_BASE = "precompile_placeholder";
@ -82,8 +100,8 @@ let
}; };
dgn-patches = import ./dgnum.nix { }; dgn-patches = import ./dgnum.nix { };
in
in stdenv.mkDerivation { stdenv.mkDerivation {
name = "demarches-simplifiees.fr-${version}"; name = "demarches-simplifiees.fr-${version}";
inherit src; inherit src;
@ -98,8 +116,9 @@ in stdenv.mkDerivation {
./patches/secrets-fc.patch ./patches/secrets-fc.patch
]; ];
postPatch = builtins.concatStringsSep "\n" postPatch = builtins.concatStringsSep "\n" (
(builtins.map (p: "${git}/bin/git apply -p1 < ${p}") dgn-patches); builtins.map (p: "${git}/bin/git apply -p1 < ${p}") dgn-patches
);
buildPhase = '' buildPhase = ''
rm -rf public rm -rf public
@ -132,8 +151,7 @@ in stdenv.mkDerivation {
meta = with lib; { meta = with lib; {
description = "Dématérialiser et simplifier les démarches administratives"; description = "Dématérialiser et simplifier les démarches administratives";
homepage = homepage = "https://github.com/demarches-simplifiees/demarches-simplifiees.fr";
"https://github.com/demarches-simplifiees/demarches-simplifiees.fr";
license = licenses.agpl3Only; license = licenses.agpl3Only;
maintainers = with maintainers; [ thubrecht ]; maintainers = with maintainers; [ thubrecht ];
}; };

View file

@ -1,6 +1,5 @@
_: _:
builtins.map (id: builtins.map
builtins.fetchurl (id: builtins.fetchurl "https://git.dgnum.eu/DGNum/demarches-normaliennes/commit/${id}.patch")
"https://git.dgnum.eu/DGNum/demarches-normaliennes/commit/${id}.patch")
[ "0b9b32483a700ad3060b3d4ef723d5f40c290c62" ] [ "0b9b32483a700ad3060b3d4ef723d5f40c290c62" ]

File diff suppressed because it is too large Load diff

View file

@ -3,7 +3,8 @@
let let
host = "pads.dgnum.eu"; host = "pads.dgnum.eu";
port = 3007; port = 3007;
in { in
{
services = { services = {
hedgedoc = { hedgedoc = {
enable = true; enable = true;
@ -43,13 +44,17 @@ in {
ensureDatabases = [ "hedgedoc" ]; ensureDatabases = [ "hedgedoc" ];
ensureUsers = [{ ensureUsers = [
{
name = "hedgedoc"; name = "hedgedoc";
ensureDBOwnership = true; ensureDBOwnership = true;
}]; }
];
}; };
}; };
systemd.services.hedgedoc.serviceConfig.StateDirectory = systemd.services.hedgedoc.serviceConfig.StateDirectory = lib.mkForce [
lib.mkForce [ "hedgedoc" "hedgedoc/uploads" ]; "hedgedoc"
"hedgedoc/uploads"
];
} }

View file

@ -40,22 +40,23 @@
}; };
authTokenFile = config.age.secrets."radius-auth_token_file".path; authTokenFile = config.age.secrets."radius-auth_token_file".path;
privateKeyPasswordFile = privateKeyPasswordFile = config.age.secrets."radius-private_key_password_file".path;
config.age.secrets."radius-private_key_password_file".path;
certs = builtins.listToAttrs (builtins.map (name: certs = builtins.listToAttrs (
lib.nameValuePair name builtins.map (name: lib.nameValuePair name config.age.secrets."radius-${name}_pem_file".path) [
config.age.secrets."radius-${name}_pem_file".path) [
"ca" "ca"
"cert" "cert"
"dh" "dh"
"key" "key"
]); ]
);
radiusClients = { }; radiusClients = { };
}; };
age-secrets.matches."^radius-.*$" = { owner = "radius"; }; age-secrets.matches."^radius-.*$" = {
owner = "radius";
};
networking.firewall.allowedTCPPorts = [ 1812 ]; networking.firewall.allowedTCPPorts = [ 1812 ];
networking.firewall.allowedUDPPorts = [ 1812 ]; networking.firewall.allowedUDPPorts = [ 1812 ];

View file

@ -1,17 +1,27 @@
{ config, lib, pkgs, ... }: {
config,
lib,
pkgs,
...
}:
let let
inherit (lib) mkEnableOption mkIf mkOption types; inherit (lib)
mkEnableOption
mkIf
mkOption
types
;
settingsFormat = pkgs.formats.toml { }; settingsFormat = pkgs.formats.toml { };
py-pkgs = import ./packages/python { inherit pkgs; }; py-pkgs = import ./packages/python { inherit pkgs; };
pykanidm = pykanidm = pkgs.callPackage ./packages/pykanidm.nix { inherit (py-pkgs) pydantic; };
pkgs.callPackage ./packages/pykanidm.nix { inherit (py-pkgs) pydantic; };
rlm_python = pkgs.callPackage ./packages/rlm_python.nix { inherit pykanidm; }; rlm_python = pkgs.callPackage ./packages/rlm_python.nix { inherit pykanidm; };
cfg = config.services.k-radius; cfg = config.services.k-radius;
in { in
{
options.services.k-radius = { options.services.k-radius = {
enable = mkEnableOption "a freeradius service linked to kanidm."; enable = mkEnableOption "a freeradius service linked to kanidm.";
@ -19,17 +29,17 @@ in {
freeradius = mkOption { freeradius = mkOption {
type = types.package; type = types.package;
default = pkgs.freeradius.overrideAttrs (old: { default = pkgs.freeradius.overrideAttrs (
buildInputs = (old.buildInputs or [ ]) old: {
++ [ (pkgs.python3.withPackages (ps: [ ps.kanidm ])) ]; buildInputs = (old.buildInputs or [ ]) ++ [ (pkgs.python3.withPackages (ps: [ ps.kanidm ])) ];
}); }
);
}; };
configDir = mkOption { configDir = mkOption {
type = types.path; type = types.path;
default = "/var/lib/radius/raddb"; default = "/var/lib/radius/raddb";
description = description = "The path of the freeradius server configuration directory.";
"The path of the freeradius server configuration directory.";
}; };
authTokenFile = mkOption { authTokenFile = mkOption {
@ -38,12 +48,14 @@ in {
}; };
radiusClients = mkOption { radiusClients = mkOption {
type = types.attrsOf (types.submodule { type = types.attrsOf (
types.submodule {
options = { options = {
secret = mkOption { type = types.path; }; secret = mkOption { type = types.path; };
ipaddr = mkOption { type = types.str; }; ipaddr = mkOption { type = types.str; };
}; };
}); }
);
default = { }; default = { };
description = "A mapping of clients and their authentication tokens."; description = "A mapping of clients and their authentication tokens.";
}; };
@ -55,8 +67,7 @@ in {
}; };
dh = mkOption { dh = mkOption {
type = types.str; type = types.str;
description = description = "The output of `openssl dhparam -in ca.pem -out dh.pem 2048`.";
"The output of `openssl dhparam -in ca.pem -out dh.pem 2048`.";
}; };
cert = mkOption { cert = mkOption {
type = types.str; type = types.str;
@ -113,9 +124,13 @@ in {
# write the clients configuration # write the clients configuration
rm ${cfg.configDir}/clients.conf && touch ${cfg.configDir}/clients.conf rm ${cfg.configDir}/clients.conf && touch ${cfg.configDir}/clients.conf
${builtins.concatStringsSep "\n" (builtins.attrValues (builtins.mapAttrs ${builtins.concatStringsSep "\n" (
(name: builtins.attrValues (
{ secret, ipaddr }: '' builtins.mapAttrs
(
name:
{ secret, ipaddr }:
''
cat <<EOF >> ${cfg.configDir}/client.conf cat <<EOF >> ${cfg.configDir}/client.conf
client ${name} { client ${name} {
ipaddr = ${ipaddr} ipaddr = ${ipaddr}
@ -123,16 +138,18 @@ in {
proto = * proto = *
} }
EOF EOF
'') cfg.radiusClients))} ''
)
cfg.radiusClients
)
)}
# Copy the kanidm configuration # Copy the kanidm configuration
cat <<EOF > /var/lib/radius/kanidm.toml cat <<EOF > /var/lib/radius/kanidm.toml
auth_token = "$(cat "${cfg.authTokenFile}")" auth_token = "$(cat "${cfg.authTokenFile}")"
EOF EOF
cat ${ cat ${settingsFormat.generate "kanidm.toml" cfg.settings} >> /var/lib/radius/kanidm.toml
settingsFormat.generate "kanidm.toml" cfg.settings
} >> /var/lib/radius/kanidm.toml
chmod u+w /var/lib/radius/kanidm.toml chmod u+w /var/lib/radius/kanidm.toml
# Copy the certificates to the correct directory # Copy the certificates to the correct directory
@ -154,11 +171,13 @@ in {
# ${pkgs.freeradius}/bin/radiusd -C -d ${cfg.configDir} -l stdout # ${pkgs.freeradius}/bin/radiusd -C -d ${cfg.configDir} -l stdout
''; '';
path = [ pkgs.openssl pkgs.gnused ]; path = [
pkgs.openssl
pkgs.gnused
];
serviceConfig = { serviceConfig = {
ExecStart = ExecStart = "${cfg.freeradius}/bin/radiusd -f -d ${cfg.configDir} -l stdout";
"${cfg.freeradius}/bin/radiusd -f -d ${cfg.configDir} -l stdout";
ExecReload = [ ExecReload = [
"${cfg.freeradius}/bin/radiusd -C -d ${cfg.configDir} -l stdout" "${cfg.freeradius}/bin/radiusd -C -d ${cfg.configDir} -l stdout"
"${pkgs.coreutils}/bin/kill -HUP $MAINPID" "${pkgs.coreutils}/bin/kill -HUP $MAINPID"

View file

@ -1,25 +1,38 @@
{ lib, fetchFromGitHub, python3, pydantic }: {
lib,
fetchFromGitHub,
python3,
pydantic,
}:
let let
pname = "kanidm"; pname = "kanidm";
version = "0.0.3"; version = "0.0.3";
in python3.pkgs.buildPythonPackage { in
python3.pkgs.buildPythonPackage {
inherit pname version; inherit pname version;
format = "pyproject"; format = "pyproject";
disabled = python3.pythonOlder "3.8"; disabled = python3.pythonOlder "3.8";
src = (fetchFromGitHub { src =
(fetchFromGitHub {
owner = pname; owner = pname;
repo = pname; repo = pname;
# Latest 1.1.0-rc.15 tip # Latest 1.1.0-rc.15 tip
rev = "a5ca8018e3a636dbb0a79b3fd869db059d92979d"; rev = "a5ca8018e3a636dbb0a79b3fd869db059d92979d";
hash = "sha256-PFGoeGn7a/lVR6rOmOKA3ydAoo3/+9RlkwBAKS22Psg="; hash = "sha256-PFGoeGn7a/lVR6rOmOKA3ydAoo3/+9RlkwBAKS22Psg=";
}) + "/pykanidm"; })
+ "/pykanidm";
nativeBuildInputs = with python3.pkgs; [ poetry-core ]; nativeBuildInputs = with python3.pkgs; [ poetry-core ];
propagatedBuildInputs = with python3.pkgs; [ aiohttp pydantic toml (authlib.overridePythonAttrs (_: { doCheck = false; })) ]; propagatedBuildInputs = with python3.pkgs; [
aiohttp
pydantic
toml
(authlib.overridePythonAttrs (_: { doCheck = false; }))
];
doCheck = false; doCheck = false;
@ -29,6 +42,9 @@ in python3.pkgs.buildPythonPackage {
description = "Kanidm client library"; description = "Kanidm client library";
homepage = "https://github.com/kanidm/kanidm/tree/master/pykanidm"; homepage = "https://github.com/kanidm/kanidm/tree/master/pykanidm";
license = licenses.mpl20; license = licenses.mpl20;
maintainers = with maintainers; [ arianvp hexa ]; maintainers = with maintainers; [
arianvp
hexa
];
}; };
} }

View file

@ -5,8 +5,16 @@ let
callPackage = lib.callPackageWith (pkgs // pkgs.python3.pkgs // self); callPackage = lib.callPackageWith (pkgs // pkgs.python3.pkgs // self);
self = builtins.listToAttrs (builtins.map (name: { self = builtins.listToAttrs (
builtins.map
(name: {
inherit name; inherit name;
value = callPackage (./. + "/${name}.nix") { }; value = callPackage (./. + "/${name}.nix") { };
}) [ "pydantic" "pydantic-core" ]); })
in self [
"pydantic"
"pydantic-core"
]
);
in
self

View file

@ -1,17 +1,18 @@
{ stdenv {
, lib stdenv,
, buildPythonPackage lib,
, fetchFromGitHub buildPythonPackage,
, cargo fetchFromGitHub,
, rustPlatform cargo,
, rustc rustPlatform,
, libiconv rustc,
, typing-extensions libiconv,
, pytestCheckHook typing-extensions,
, hypothesis pytestCheckHook,
, pytest-timeout hypothesis,
, pytest-mock pytest-timeout,
, dirty-equals pytest-mock,
dirty-equals,
}: }:
let let
@ -27,9 +28,7 @@ let
hash = "sha256-UguZpA3KEutOgIavjx8Ie//0qJq+4FTZNQTwb/ZIgb8="; hash = "sha256-UguZpA3KEutOgIavjx8Ie//0qJq+4FTZNQTwb/ZIgb8=";
}; };
patches = [ patches = [ ./01-remove-benchmark-flags.patch ];
./01-remove-benchmark-flags.patch
];
cargoDeps = rustPlatform.fetchCargoTarball { cargoDeps = rustPlatform.fetchCargoTarball {
inherit src; inherit src;
@ -45,13 +44,9 @@ let
typing-extensions typing-extensions
]; ];
buildInputs = lib.optionals stdenv.isDarwin [ buildInputs = lib.optionals stdenv.isDarwin [ libiconv ];
libiconv
];
propagatedBuildInputs = [ propagatedBuildInputs = [ typing-extensions ];
typing-extensions
];
pythonImportsCheck = [ "pydantic_core" ]; pythonImportsCheck = [ "pydantic_core" ];
@ -85,4 +80,5 @@ let
maintainers = with maintainers; [ blaggacao ]; maintainers = with maintainers; [ blaggacao ];
}; };
}; };
in pydantic-core in
pydantic-core

View file

@ -1,27 +1,28 @@
{ lib {
, buildPythonPackage lib,
, fetchFromGitHub buildPythonPackage,
, pythonOlder fetchFromGitHub,
pythonOlder,
# build-system # build-system
, hatchling hatchling,
, hatch-fancy-pypi-readme hatch-fancy-pypi-readme,
# native dependencies # native dependencies
, libxcrypt libxcrypt,
# dependencies # dependencies
, annotated-types annotated-types,
, pydantic-core pydantic-core,
, typing-extensions typing-extensions,
# tests # tests
, cloudpickle cloudpickle,
, email-validator email-validator,
, dirty-equals dirty-equals,
, faker faker,
, pytestCheckHook pytestCheckHook,
, pytest-mock pytest-mock,
}: }:
buildPythonPackage rec { buildPythonPackage rec {
@ -38,9 +39,7 @@ buildPythonPackage rec {
hash = "sha256-D0gYcyrKVVDhBgV9sCVTkGq/kFmIoT9l0i5bRM1qxzM="; hash = "sha256-D0gYcyrKVVDhBgV9sCVTkGq/kFmIoT9l0i5bRM1qxzM=";
}; };
buildInputs = lib.optionals (pythonOlder "3.9") [ buildInputs = lib.optionals (pythonOlder "3.9") [ libxcrypt ];
libxcrypt
];
nativeBuildInputs = [ nativeBuildInputs = [
hatch-fancy-pypi-readme hatch-fancy-pypi-readme
@ -54,9 +53,7 @@ buildPythonPackage rec {
]; ];
passthru.optional-dependencies = { passthru.optional-dependencies = {
email = [ email = [ email-validator ];
email-validator
];
}; };
nativeCheckInputs = [ nativeCheckInputs = [
@ -93,4 +90,3 @@ buildPythonPackage rec {
maintainers = with maintainers; [ wd15 ]; maintainers = with maintainers; [ wd15 ];
}; };
} }

View file

@ -1,8 +1,14 @@
{ stdenv, fetchFromGitHub, python3, pykanidm }: {
stdenv,
fetchFromGitHub,
python3,
pykanidm,
}:
let pythonPath = with python3.pkgs; makePythonPath [ pykanidm ]; let
pythonPath = with python3.pkgs; makePythonPath [ pykanidm ];
in stdenv.mkDerivation rec { in
stdenv.mkDerivation rec {
pname = "rlm_python"; pname = "rlm_python";
version = "1.1.0-rc.15"; version = "1.1.0-rc.15";
@ -25,9 +31,15 @@ in stdenv.mkDerivation rec {
cp -R rlm_python/{mods-available,sites-available} $out/etc/raddb/ cp -R rlm_python/{mods-available,sites-available} $out/etc/raddb/
''; '';
phases = [ "unpackPhase" "patchPhase" "installPhase" ]; phases = [
"unpackPhase"
"patchPhase"
"installPhase"
];
passthru = { inherit pythonPath; }; passthru = {
inherit pythonPath;
};
preferLocalBuild = true; preferLocalBuild = true;
} }

View file

@ -5,8 +5,16 @@ let
cert = config.security.acme.certs.${domain}; cert = config.security.acme.certs.${domain};
allowedSubDomains = [ "cloud" "git" "videos" "social" "demarches" "netbird" ]; allowedSubDomains = [
in { "cloud"
"git"
"videos"
"social"
"demarches"
"netbird"
];
in
{
services.kanidm = { services.kanidm = {
enableServer = true; enableServer = true;

View file

@ -7,4 +7,3 @@ lib.setDefault { inherit publicKeys; } [
"kanidm-password_admin" "kanidm-password_admin"
"kanidm-password_idm_admin" "kanidm-password_idm_admin"
] ]

View file

@ -1,7 +1,9 @@
{ config, ... }: { config, ... }:
let host = "social.dgnum.eu"; let
in { host = "social.dgnum.eu";
in
{
services.mastodon = { services.mastodon = {
enable = true; enable = true;
@ -9,7 +11,6 @@ in {
smtp = { smtp = {
# TODO: smtp setup # TODO: smtp setup
fromAddress = "social@services.dgnum.eu"; fromAddress = "social@services.dgnum.eu";
}; };
streamingProcesses = 4; streamingProcesses = 4;
@ -38,5 +39,7 @@ in {
extraEnvFiles = [ config.age.secrets."mastodon-extra_env_file".path ]; extraEnvFiles = [ config.age.secrets."mastodon-extra_env_file".path ];
}; };
age-secrets.matches."^mastodon-.*$" = { owner = "mastodon"; }; age-secrets.matches."^mastodon-.*$" = {
owner = "mastodon";
};
} }

View file

@ -3,7 +3,8 @@
let let
host = "cloud.dgnum.eu"; host = "cloud.dgnum.eu";
nextcloud-occ = "${config.services.nextcloud.occ}/bin/nextcloud-occ"; nextcloud-occ = "${config.services.nextcloud.occ}/bin/nextcloud-occ";
in { in
{
services.nextcloud = { services.nextcloud = {
enable = true; enable = true;
hostName = host; hostName = host;
@ -102,8 +103,7 @@ in {
image = "collabora/code"; image = "collabora/code";
imageFile = pkgs.dockerTools.pullImage { imageFile = pkgs.dockerTools.pullImage {
imageName = "collabora/code"; imageName = "collabora/code";
imageDigest = imageDigest = "sha256:a8cce07c949aa59cea0a7f1f220266a1a6d886c717c3b5005782baf6f384d645";
"sha256:a8cce07c949aa59cea0a7f1f220266a1a6d886c717c3b5005782baf6f384d645";
sha256 = "sha256-lN6skv62x+x7G7SNOUyZ8W6S/uScrkqE1nbBwwSEWXQ="; sha256 = "sha256-lN6skv62x+x7G7SNOUyZ8W6S/uScrkqE1nbBwwSEWXQ=";
}; };
ports = [ "9980:9980" ]; ports = [ "9980:9980" ];
@ -111,7 +111,12 @@ in {
domain = "cloud.dgnum.eu"; domain = "cloud.dgnum.eu";
extra_params = "--o:ssl.enable=false --o:ssl.termination=true --o:remote_font_config.url=https://cloud.dgnum.eu/apps/richdocuments/settings/fonts.json"; extra_params = "--o:ssl.enable=false --o:ssl.termination=true --o:remote_font_config.url=https://cloud.dgnum.eu/apps/richdocuments/settings/fonts.json";
}; };
extraOptions = [ "--cap-add" "MKNOD" "--cap-add" "SYS_ADMIN" ]; extraOptions = [
"--cap-add"
"MKNOD"
"--cap-add"
"SYS_ADMIN"
];
}; };
}; };
@ -180,7 +185,9 @@ in {
description = "Generate preview for nextcloud media."; description = "Generate preview for nextcloud media.";
script = "${nextcloud-occ} preview:pre-generate -vvv"; script = "${nextcloud-occ} preview:pre-generate -vvv";
startAt = "*-*-* 01:00:00 UTC"; startAt = "*-*-* 01:00:00 UTC";
serviceConfig = { Restart = "on-failure"; }; serviceConfig = {
Restart = "on-failure";
};
}; };
nextcloud-cron.path = [ pkgs.perl ]; nextcloud-cron.path = [ pkgs.perl ];
@ -188,9 +195,13 @@ in {
environment.systemPackages = [ pkgs.ffmpeg_6-headless ]; environment.systemPackages = [ pkgs.ffmpeg_6-headless ];
networking.hosts = { "129.199.146.148" = [ "s3.dgnum.eu" ]; }; networking.hosts = {
"129.199.146.148" = [ "s3.dgnum.eu" ];
};
age-secrets.matches."^nextcloud-.*$" = { owner = "nextcloud"; }; age-secrets.matches."^nextcloud-.*$" = {
owner = "nextcloud";
};
system.activationScripts = { system.activationScripts = {
restart-nextcloud.text = '' restart-nextcloud.text = ''

View file

@ -1,7 +1,9 @@
{ config, ... }: { config, ... }:
let host = "docs.dgnum.eu"; let
in { host = "docs.dgnum.eu";
in
{
services.outline = { services.outline = {
enable = true; enable = true;
@ -27,8 +29,7 @@ in {
userinfoUrl = "https://sso.dgnum.eu/oauth2/openid/outline_dgn/userinfo"; userinfoUrl = "https://sso.dgnum.eu/oauth2/openid/outline_dgn/userinfo";
displayName = "DGNum SSO"; displayName = "DGNum SSO";
clientSecretFile = clientSecretFile = config.age.secrets."outline-oidc_client_secret_file".path;
config.age.secrets."outline-oidc_client_secret_file".path;
}; };
defaultLanguage = "fr_FR"; defaultLanguage = "fr_FR";
@ -51,5 +52,7 @@ in {
}; };
}; };
age-secrets.matches."^outline-.*$" = { owner = "outline"; }; age-secrets.matches."^outline-.*$" = {
owner = "outline";
};
} }

View file

@ -1,9 +1,10 @@
{ pkgs, ... }: { pkgs, ... }:
let let
host = "rstudio.dgnum.eu"; # host = "rstudio.dgnum.eu";
port = 19000; port = 19000;
in { in
{
services.rstudio-server = { services.rstudio-server = {
enable = true; enable = true;
rserverExtraConfig = '' rserverExtraConfig = ''
@ -11,14 +12,17 @@ in {
''; '';
package = pkgs.rstudioServerWrapper.override { package = pkgs.rstudioServerWrapper.override {
packages = with pkgs.rPackages; [ ggplot2 rmarkdown dplyr ]; packages = with pkgs.rPackages; [
ggplot2
rmarkdown
dplyr
];
}; };
}; };
users.users.ruser = { users.users.ruser = {
isNormalUser = true; isNormalUser = true;
hashedPassword = hashedPassword = "$6$pTXXVh8NfE.M8VPc$q0fFh3Y7Y0DauLCcZLgJzFciq1wkjoHmO61XpOrZLH3a1M32ZzOMbjx2XMm2QxrUncbx6hGerY/lD8rQ8InS4.";
"$6$pTXXVh8NfE.M8VPc$q0fFh3Y7Y0DauLCcZLgJzFciq1wkjoHmO61XpOrZLH3a1M32ZzOMbjx2XMm2QxrUncbx6hGerY/lD8rQ8InS4.";
}; };
dgn-access-control.users.ruser = [ "jemagius" ]; dgn-access-control.users.ruser = [ "jemagius" ];

View file

@ -1,7 +1,9 @@
{ config, ... }: { config, ... }:
let host = "saml-idp.dgnum.eu"; let
in { host = "saml-idp.dgnum.eu";
in
{
imports = [ ./module.nix ]; imports = [ ./module.nix ];
@ -20,8 +22,7 @@ in {
config = { config = {
endpoints.single_sign_on_service = { endpoints.single_sign_on_service = {
"urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" = "sso/post"; "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" = "sso/post";
"urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" = "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" = "sso/redirect";
"sso/redirect";
}; };
entityid_endpoint = true; entityid_endpoint = true;
enable_metadata_reload = false; enable_metadata_reload = false;
@ -32,11 +33,13 @@ in {
url = "https://dgnum.eu"; url = "https://dgnum.eu";
}; };
contact_person = [{ contact_person = [
{
contact_type = "technical"; contact_type = "technical";
email_address = "mailto:tom.hubrecht@dgnum.eu"; email_address = "mailto:tom.hubrecht@dgnum.eu";
given_name = "Tom Hubrecht"; given_name = "Tom Hubrecht";
}]; }
];
key_file = "/var/lib/satosa/ssl/key.pem"; key_file = "/var/lib/satosa/ssl/key.pem";
cert_file = "/var/lib/satosa/ssl/cert.pem"; cert_file = "/var/lib/satosa/ssl/cert.pem";
@ -50,10 +53,12 @@ in {
endpoints.single_sign_on_service = [ ]; endpoints.single_sign_on_service = [ ];
name = "DGNum proxy IdP"; name = "DGNum proxy IdP";
ui_info = { ui_info = {
display_name = [{ display_name = [
{
lang = "fr"; lang = "fr";
text = "Service de connexion DGNum"; text = "Service de connexion DGNum";
}]; }
];
}; };
name_id_format = [ name_id_format = [
"urn:oasis:names:tc:SAML:2.0:nameid-format:persistent" "urn:oasis:names:tc:SAML:2.0:nameid-format:persistent"
@ -63,9 +68,10 @@ in {
default = { default = {
attribute_restrictions = null; attribute_restrictions = null;
fail_on_missing_requested = false; fail_on_missing_requested = false;
lifetime = { minutes = 15; }; lifetime = {
name_form = minutes = 15;
"urn:oasis:names:tc:SAML:2.0:attrname-format:uri"; };
name_form = "urn:oasis:names:tc:SAML:2.0:attrname-format:uri";
encrypt_assertion = false; encrypt_assertion = false;
encrypted_advice_attributes = false; encrypted_advice_attributes = false;
}; };
@ -121,12 +127,15 @@ in {
module = "satosa.backends.openid_connect.OpenIDConnectBackend"; module = "satosa.backends.openid_connect.OpenIDConnectBackend";
name = "kanidm"; name = "kanidm";
config = { config = {
provider_metadata.issuer = provider_metadata.issuer = "https://sso.dgnum.eu/oauth2/openid/satosa_dgn/";
"https://sso.dgnum.eu/oauth2/openid/satosa_dgn/";
client = { client = {
auth_req_params = { auth_req_params = {
response_type = "code"; response_type = "code";
scope = [ "openid" "profile" "email" ]; scope = [
"openid"
"profile"
"email"
];
}; };
client_metadata = { client_metadata = {
client_id = "satosa_dgn"; client_id = "satosa_dgn";
@ -144,5 +153,7 @@ in {
forceSSL = true; forceSSL = true;
}; };
age-secrets.matches."^satosa-.*$" = { owner = "satosa"; }; age-secrets.matches."^satosa-.*$" = {
owner = "satosa";
};
} }

View file

@ -1,7 +1,18 @@
{ config, lib, pkgs, ... }: {
config,
lib,
pkgs,
...
}:
let let
inherit (lib) mkDefault mkEnableOption mkIf mkOption types; inherit (lib)
mkDefault
mkEnableOption
mkIf
mkOption
types
;
yamlFormat = pkgs.formats.yaml { }; yamlFormat = pkgs.formats.yaml { };
@ -9,12 +20,17 @@ let
cfg = config.services.satosa; cfg = config.services.satosa;
mkYamlFiles = files: mkYamlFiles =
builtins.attrValues files: builtins.attrValues (builtins.mapAttrs (name: yamlFormat.generate "${name}.yaml") files);
(builtins.mapAttrs (name: yamlFormat.generate "${name}.yaml") files);
pyEnv = cfg.package.python.withPackages (ps: [ cfg.package ps.gunicorn ]); pyEnv = cfg.package.python.withPackages (
in { ps: [
cfg.package
ps.gunicorn
]
);
in
{
options.services.satosa = { options.services.satosa = {
enable = mkEnableOption "SATOSA, a SAML and OIDC proxy."; enable = mkEnableOption "SATOSA, a SAML and OIDC proxy.";
@ -88,8 +104,7 @@ in {
MICRO_SERVICES = mkYamlFiles cfg.microServices; MICRO_SERVICES = mkYamlFiles cfg.microServices;
LOGGING = { LOGGING = {
version = 1; version = 1;
formatters.simple.format = formatters.simple.format = "[%(asctime)s] [%(levelname)s] [%(name)s.%(funcName)s] %(message)s";
"[%(asctime)s] [%(levelname)s] [%(name)s.%(funcName)s] %(message)s";
handlers.stdout = { handlers.stdout = {
class = "logging.StreamHandler"; class = "logging.StreamHandler";
stream = "ext://sys.stdout"; stream = "ext://sys.stdout";
@ -171,7 +186,9 @@ in {
TimeoutStopSec = "5"; TimeoutStopSec = "5";
EnvironmentFile = lib.optional (cfg.envFile != null) cfg.envFile; EnvironmentFile = lib.optional (cfg.envFile != null) cfg.envFile;
}; };
environment = { SATOSA_CONFIG = configFile; }; environment = {
SATOSA_CONFIG = configFile;
};
}; };
}; };
@ -179,8 +196,7 @@ in {
enable = true; enable = true;
virtualHosts.${cfg.host} = { virtualHosts.${cfg.host} = {
locations."/".proxyPass = locations."/".proxyPass = "http://127.0.0.1:${builtins.toString cfg.port}";
"http://127.0.0.1:${builtins.toString cfg.port}";
}; };
}; };

View file

@ -1,6 +1,7 @@
{ lib {
, python3 lib,
, fetchPypi python3,
fetchPypi,
}: }:
python3.pkgs.buildPythonPackage rec { python3.pkgs.buildPythonPackage rec {

View file

@ -13,5 +13,5 @@ let
pydantic = callPackage ./pydantic.nix { }; pydantic = callPackage ./pydantic.nix { };
pydantic-core = callPackage ./pydantic-core.nix { }; pydantic-core = callPackage ./pydantic-core.nix { };
}; };
in
in self.satosa self.satosa

View file

@ -1,7 +1,8 @@
{ lib {
, python3 lib,
, fetchPypi python3,
, pydantic-settings fetchPypi,
pydantic-settings,
}: }:
python3.pkgs.buildPythonPackage rec { python3.pkgs.buildPythonPackage rec {

View file

@ -1,9 +1,10 @@
{ lib {
, python3 lib,
, fetchPypi python3,
, cargo fetchPypi,
, rustPlatform cargo,
, rustc rustPlatform,
rustc,
}: }:
python3.pkgs.buildPythonPackage rec { python3.pkgs.buildPythonPackage rec {
@ -31,9 +32,7 @@ python3.pkgs.buildPythonPackage rec {
rustc rustc
]; ];
propagatedBuildInputs = with python3.pkgs; [ propagatedBuildInputs = with python3.pkgs; [ typing-extensions ];
typing-extensions
];
pythonImportsCheck = [ "pydantic_core" ]; pythonImportsCheck = [ "pydantic_core" ];

View file

@ -1,7 +1,8 @@
{ lib {
, python3 lib,
, fetchPypi python3,
, pydantic fetchPypi,
pydantic,
}: }:
python3.pkgs.buildPythonPackage rec { python3.pkgs.buildPythonPackage rec {
@ -15,9 +16,7 @@ python3.pkgs.buildPythonPackage rec {
hash = "sha256-li3DZySVqtaulqQ5D6x+WTWR4URiXlES01n49n+3WUU="; hash = "sha256-li3DZySVqtaulqQ5D6x+WTWR4URiXlES01n49n+3WUU=";
}; };
nativeBuildInputs = [ nativeBuildInputs = [ python3.pkgs.hatchling ];
python3.pkgs.hatchling
];
propagatedBuildInputs = with python3.pkgs; [ propagatedBuildInputs = with python3.pkgs; [
pydantic pydantic

View file

@ -1,7 +1,8 @@
{ lib {
, python3 lib,
, fetchPypi python3,
, pydantic-core fetchPypi,
pydantic-core,
}: }:
python3.pkgs.buildPythonPackage rec { python3.pkgs.buildPythonPackage rec {
@ -26,9 +27,7 @@ python3.pkgs.buildPythonPackage rec {
]; ];
passthru.optional-dependencies = with python3.pkgs; { passthru.optional-dependencies = with python3.pkgs; {
email = [ email = [ email-validator ];
email-validator
];
}; };
pythonImportsCheck = [ "pydantic" ]; pythonImportsCheck = [ "pydantic" ];

View file

@ -1,7 +1,8 @@
{ lib {
, python3 lib,
, fetchPypi python3,
, oic fetchPypi,
oic,
}: }:
python3.pkgs.buildPythonPackage rec { python3.pkgs.buildPythonPackage rec {

View file

@ -1,8 +1,9 @@
{ lib {
, python3 lib,
, fetchPypi python3,
, cookies-samesite-compat fetchPypi,
, pyop cookies-samesite-compat,
pyop,
}: }:
python3.pkgs.buildPythonPackage rec { python3.pkgs.buildPythonPackage rec {
@ -36,15 +37,9 @@ python3.pkgs.buildPythonPackage rec {
]; ];
passthru.optional-dependencies = with python3.pkgs; { passthru.optional-dependencies = with python3.pkgs; {
ldap = [ ldap = [ ldap3 ];
ldap3 pyop_mongo = [ pyop ];
]; pyop_redis = [ pyop ];
pyop_mongo = [
pyop
];
pyop_redis = [
pyop
];
}; };
passthru.python = python3; passthru.python = python3;

View file

@ -1,8 +1,9 @@
{ config, ... }: { config, ... }:
let host = "pass.dgnum.eu"; let
host = "pass.dgnum.eu";
in { in
{
services.vaultwarden = { services.vaultwarden = {
enable = true; enable = true;
@ -62,10 +63,12 @@ in {
ensureDatabases = [ "vaultwarden" ]; ensureDatabases = [ "vaultwarden" ];
ensureUsers = [{ ensureUsers = [
{
name = "vaultwarden"; name = "vaultwarden";
ensureDBOwnership = true; ensureDBOwnership = true;
}]; }
];
}; };
}; };
} }

View file

@ -5,7 +5,8 @@ let
port = 3005; port = 3005;
websocketPort = 6902; websocketPort = 6902;
in { in
{
services.zammad = { services.zammad = {
enable = true; enable = true;
@ -38,8 +39,7 @@ in {
proxyWebsockets = true; proxyWebsockets = true;
}; };
"~ ^/(assets/|robots.txt|humans.txt|favicon.ico|apple-touch-icon.png)".extraConfig = "~ ^/(assets/|robots.txt|humans.txt|favicon.ico|apple-touch-icon.png)".extraConfig = ''
''
expires max; expires max;
''; '';
}; };
@ -51,5 +51,7 @@ in {
}; };
}; };
age-secrets.matches."^zammad-.*$" = { owner = "zammad"; }; age-secrets.matches."^zammad-.*$" = {
owner = "zammad";
};
} }

View file

@ -29,6 +29,5 @@
fsType = "vfat"; fsType = "vfat";
}; };
swapDevices = swapDevices = [ { device = "/dev/disk/by-uuid/65a6f6e4-e996-4718-a4d0-cd0c78dcb15b"; } ];
[{ device = "/dev/disk/by-uuid/65a6f6e4-e996-4718-a4d0-cd0c78dcb15b"; }];
} }

View file

@ -1,8 +1,14 @@
{ config, pkgs, sources, ... }: {
config,
pkgs,
sources,
...
}:
let host = "cachix.dgnum.eu"; let
host = "cachix.dgnum.eu";
in { in
{
services = { services = {
atticd = { atticd = {
enable = true; enable = true;
@ -68,10 +74,12 @@ in {
ensureDatabases = [ "atticd" ]; ensureDatabases = [ "atticd" ];
ensureUsers = [{ ensureUsers = [
{
name = "atticd"; name = "atticd";
ensureDBOwnership = true; ensureDBOwnership = true;
}]; }
];
}; };
}; };
} }

View file

@ -3,18 +3,29 @@
let let
url = "https://git.dgnum.eu"; url = "https://git.dgnum.eu";
mkRunner = { labels, name, token }: { mkRunner =
{
labels,
name,
token,
}:
{
enable = true; enable = true;
inherit name labels token url; inherit
name
labels
token
url
;
settings.container = { settings.container = {
network = "host"; network = "host";
options = "--cpus=4"; options = "--cpus=4";
}; };
}; };
in
in { {
services.forgejo-nix-runners = { services.forgejo-nix-runners = {
enable = true; enable = true;
@ -23,7 +34,11 @@ in {
storePath = "/data/slow/nix"; storePath = "/data/slow/nix";
tokenFile = config.age.secrets."forgejo_runners-token_file".path; tokenFile = config.age.secrets."forgejo_runners-token_file".path;
dependencies = [ pkgs.colmena pkgs.npins pkgs.tea ]; dependencies = [
pkgs.colmena
pkgs.npins
pkgs.tea
];
containerOptions = [ "--cpus=4" ]; containerOptions = [ "--cpus=4" ];

View file

@ -3,7 +3,8 @@
let let
port = 3000; port = 3000;
host = "git.dgnum.eu"; host = "git.dgnum.eu";
in { in
{
services = { services = {
forgejo = { forgejo = {
enable = true; enable = true;
@ -19,7 +20,9 @@ in {
}; };
settings = { settings = {
DEFAULT = { APP_NAME = "Forge git de la DGNum"; }; DEFAULT = {
APP_NAME = "Forge git de la DGNum";
};
server = { server = {
ROOT_URL = "https://${host}/"; ROOT_URL = "https://${host}/";
@ -62,7 +65,9 @@ in {
virtualHosts.${host} = { virtualHosts.${host} = {
enableACME = true; enableACME = true;
forceSSL = true; forceSSL = true;
locations."/" = { proxyPass = "http://127.0.0.1:${toString port}"; }; locations."/" = {
proxyPass = "http://127.0.0.1:${toString port}";
};
}; };
}; };
}; };
@ -77,5 +82,7 @@ in {
users.groups.git = { }; users.groups.git = { };
age-secrets.matches."^forgejo-.*$" = { owner = "git"; }; age-secrets.matches."^forgejo-.*$" = {
owner = "git";
};
} }

View file

@ -8,12 +8,13 @@ let
metadata_dir = "/data/fast/garage/meta"; metadata_dir = "/data/fast/garage/meta";
buckets = [ "peertube-videos-dgnum" ]; buckets = [ "peertube-videos-dgnum" ];
in
in { {
services.garage = { services.garage = {
enable = true; enable = true;
package = pkgs.garage_0_9.overrideAttrs (old: { package = pkgs.garage_0_9.overrideAttrs (
old: {
patches = (old.patches or [ ]) ++ [ patches = (old.patches or [ ]) ++ [
# Allow 0 as a part number marker # Allow 0 as a part number marker
(pkgs.fetchpatch { (pkgs.fetchpatch {
@ -21,7 +22,8 @@ in {
hash = "sha256-28ctLl1qscMRj2JEVnmhuLyK1Avub8QeyfQFxAK0y08="; hash = "sha256-28ctLl1qscMRj2JEVnmhuLyK1Avub8QeyfQFxAK0y08=";
}) })
]; ];
}); }
);
settings = { settings = {
inherit data_dir metadata_dir; inherit data_dir metadata_dir;
@ -56,7 +58,10 @@ in {
systemd.services.garage.serviceConfig = { systemd.services.garage.serviceConfig = {
User = "garage"; User = "garage";
ReadWriteDirectories = [ data_dir metadata_dir ]; ReadWriteDirectories = [
data_dir
metadata_dir
];
}; };
users.users.garage = { users.users.garage = {

View file

@ -1,8 +1,24 @@
{ config, lib, pkgs, ... }: {
config,
lib,
pkgs,
...
}:
let let
inherit (lib) inherit (lib)
filterAttrs literalExpression maintainers mkDefault mkEnableOption mkIf filterAttrs
mkMerge mkOption optionalAttrs optionalString optionals types; literalExpression
maintainers
mkDefault
mkEnableOption
mkIf
mkMerge
mkOption
optionalAttrs
optionalString
optionals
types
;
inherit ((import ./package { inherit pkgs; })) dashboard; inherit ((import ./package { inherit pkgs; })) dashboard;
@ -13,37 +29,33 @@ let
settingsFormat = pkgs.formats.keyValue { }; settingsFormat = pkgs.formats.keyValue { };
managementFormat = pkgs.formats.json { }; managementFormat = pkgs.formats.json { };
settingsFile = settingsFormat.generate "setup.env" (builtins.mapAttrs (_: val: settingsFile = settingsFormat.generate "setup.env" (
if builtins.isList val then builtins.mapAttrs
''"${builtins.concatStringsSep " " val}"'' (_: val: if builtins.isList val then ''"${builtins.concatStringsSep " " val}"'' else val)
else settings
val) settings); );
managementFile = managementFormat.generate "config.json" cfg.managementConfig; managementFile = managementFormat.generate "config.json" cfg.managementConfig;
settings = rec { settings =
rec {
TURN_DOMAIN = cfg.settings.NETBIRD_DOMAIN; TURN_DOMAIN = cfg.settings.NETBIRD_DOMAIN;
TURN_PORT = 3478; TURN_PORT = 3478;
TURN_USER = "netbird"; TURN_USER = "netbird";
TURN_MIN_PORT = 49152; TURN_MIN_PORT = 49152;
TURN_MAX_PORT = 65535; TURN_MAX_PORT = 65535;
TURN_PASSWORD = TURN_PASSWORD = if cfg.secretFiles.TURN_PASSWORD != null then "$TURN_PASSWORD" else null;
if cfg.secretFiles.TURN_PASSWORD != null then "$TURN_PASSWORD" else null; TURN_SECRET = if cfg.secretFiles.TURN_SECRET != null then "$TURN_SECRET" else "secret";
TURN_SECRET =
if cfg.secretFiles.TURN_SECRET != null then "$TURN_SECRET" else "secret";
STUN_USERNAME = ""; STUN_USERNAME = "";
STUN_PASSWORD = STUN_PASSWORD = if cfg.secretFiles.STUN_PASSWORD != null then "$STUN_PASSWORD" else null;
if cfg.secretFiles.STUN_PASSWORD != null then "$STUN_PASSWORD" else null;
NETBIRD_DASHBOARD_ENDPOINT = "https://${cfg.settings.NETBIRD_DOMAIN}:443"; NETBIRD_DASHBOARD_ENDPOINT = "https://${cfg.settings.NETBIRD_DOMAIN}:443";
NETBIRD_MGMT_API_ENDPOINT = "https://${cfg.settings.NETBIRD_DOMAIN}:${ NETBIRD_MGMT_API_ENDPOINT = "https://${cfg.settings.NETBIRD_DOMAIN}:${
builtins.toString builtins.toString cfg.settings.NETBIRD_MGMT_API_PORT or NETBIRD_MGMT_API_PORT
cfg.settings.NETBIRD_MGMT_API_PORT or NETBIRD_MGMT_API_PORT
}"; }";
NETBIRD_SIGNAL_ENDPOINT = "https://${cfg.settings.NETBIRD_DOMAIN}:${ NETBIRD_SIGNAL_ENDPOINT = "https://${cfg.settings.NETBIRD_DOMAIN}:${
builtins.toString builtins.toString cfg.settings.NETBIRD_SIGNAL_PORT or NETBIRD_SIGNAL_PORT
cfg.settings.NETBIRD_SIGNAL_PORT or NETBIRD_SIGNAL_PORT
}"; }";
NETBIRD_SIGNAL_PROTOCOL = "https"; NETBIRD_SIGNAL_PROTOCOL = "https";
@ -51,12 +63,14 @@ let
NETBIRD_AUTH_USER_ID_CLAIM = "sub"; NETBIRD_AUTH_USER_ID_CLAIM = "sub";
NETBIRD_AUTH_CLIENT_SECRET = NETBIRD_AUTH_CLIENT_SECRET =
if cfg.secretFiles.AUTH_CLIENT_SECRET != null then if cfg.secretFiles.AUTH_CLIENT_SECRET != null then "$AUTH_CLIENT_SECRET" else "";
"$AUTH_CLIENT_SECRET" NETBIRD_AUTH_SUPPORTED_SCOPES = [
else "openid"
""; "profile"
NETBIRD_AUTH_SUPPORTED_SCOPES = "email"
[ "openid" "profile" "email" "offline_access" "api" ]; "offline_access"
"api"
];
NETBIRD_AUTH_REDIRECT_URI = ""; NETBIRD_AUTH_REDIRECT_URI = "";
NETBIRD_AUTH_SILENT_REDIRECT_URI = ""; NETBIRD_AUTH_SILENT_REDIRECT_URI = "";
@ -64,8 +78,13 @@ let
NETBIRD_AUTH_DEVICE_AUTH_PROVIDER = "none"; NETBIRD_AUTH_DEVICE_AUTH_PROVIDER = "none";
NETBIRD_AUTH_DEVICE_AUTH_CLIENT_ID = cfg.settings.NETBIRD_AUTH_CLIENT_ID; NETBIRD_AUTH_DEVICE_AUTH_CLIENT_ID = cfg.settings.NETBIRD_AUTH_CLIENT_ID;
NETBIRD_AUTH_DEVICE_AUTH_AUDIENCE = cfg.settings.NETBIRD_AUTH_AUDIENCE; NETBIRD_AUTH_DEVICE_AUTH_AUDIENCE = cfg.settings.NETBIRD_AUTH_AUDIENCE;
NETBIRD_AUTH_DEVICE_AUTH_SCOPE = NETBIRD_AUTH_DEVICE_AUTH_SCOPE = [
[ "openid" "profile" "email" "offline_access" "api" ]; "openid"
"profile"
"email"
"offline_access"
"api"
];
NETBIRD_AUTH_DEVICE_AUTH_USE_ID_TOKEN = false; NETBIRD_AUTH_DEVICE_AUTH_USE_ID_TOKEN = false;
NETBIRD_MGMT_API_PORT = 443; NETBIRD_MGMT_API_PORT = 443;
@ -87,18 +106,23 @@ let
NETBIRD_AUTH_DEVICE_AUTH_ENDPOINT = ""; NETBIRD_AUTH_DEVICE_AUTH_ENDPOINT = "";
NETBIRD_AUTH_PKCE_REDIRECT_URL_PORTS = [ "53000" ]; NETBIRD_AUTH_PKCE_REDIRECT_URL_PORTS = [ "53000" ];
NETBIRD_AUTH_PKCE_REDIRECT_URLS = builtins.map (p: "http://localhost:${p}") NETBIRD_AUTH_PKCE_REDIRECT_URLS =
builtins.map (p: "http://localhost:${p}")
cfg.settings.NETBIRD_AUTH_PKCE_REDIRECT_URL_PORTS or NETBIRD_AUTH_PKCE_REDIRECT_URL_PORTS; cfg.settings.NETBIRD_AUTH_PKCE_REDIRECT_URL_PORTS or NETBIRD_AUTH_PKCE_REDIRECT_URL_PORTS;
} // (optionalAttrs cfg.setupAutoOidc { }
NETBIRD_AUTH_PKCE_AUTHORIZATION_ENDPOINT = // (optionalAttrs cfg.setupAutoOidc {
"$NETBIRD_AUTH_PKCE_AUTHORIZATION_ENDPOINT"; NETBIRD_AUTH_PKCE_AUTHORIZATION_ENDPOINT = "$NETBIRD_AUTH_PKCE_AUTHORIZATION_ENDPOINT";
NETBIRD_AUTH_DEVICE_AUTH_ENDPOINT = "$NETBIRD_AUTH_DEVICE_AUTH_ENDPOINT"; NETBIRD_AUTH_DEVICE_AUTH_ENDPOINT = "$NETBIRD_AUTH_DEVICE_AUTH_ENDPOINT";
NETBIRD_AUTH_TOKEN_ENDPOINT = "$NETBIRD_AUTH_TOKEN_ENDPOINT"; NETBIRD_AUTH_TOKEN_ENDPOINT = "$NETBIRD_AUTH_TOKEN_ENDPOINT";
NETBIRD_AUTH_JWT_CERTS = "$NETBIRD_AUTH_JWT_CERTS"; NETBIRD_AUTH_JWT_CERTS = "$NETBIRD_AUTH_JWT_CERTS";
NETBIRD_AUTH_AUTHORITY = "$NETBIRD_AUTH_AUTHORITY"; NETBIRD_AUTH_AUTHORITY = "$NETBIRD_AUTH_AUTHORITY";
}) // cfg.settings; })
in { // cfg.settings;
meta = { maintainers = with maintainers; [ thubrecht ]; }; in
{
meta = {
maintainers = with maintainers; [ thubrecht ];
};
options.services.netbird-server = { options.services.netbird-server = {
enable = mkEnableOption (lib.mdDoc "netbird management service."); enable = mkEnableOption (lib.mdDoc "netbird management service.");
@ -111,8 +135,19 @@ in {
}; };
settings = mkOption { settings = mkOption {
type = with types; type =
attrsOf (nullOr (oneOf [ (listOf str) bool int float str ])); with types;
attrsOf (
nullOr (
oneOf [
(listOf str)
bool
int
float
str
]
)
);
defaultText = lib.literalExpression '' defaultText = lib.literalExpression ''
{ {
TURN_DOMAIN = cfg.settings.NETBIRD_DOMAIN; TURN_DOMAIN = cfg.settings.NETBIRD_DOMAIN;
@ -195,13 +230,17 @@ in {
}; };
logLevel = mkOption { logLevel = mkOption {
type = types.enum [ "ERROR" "WARN" "INFO" "DEBUG" ]; type = types.enum [
"ERROR"
"WARN"
"INFO"
"DEBUG"
];
default = "INFO"; default = "INFO";
description = lib.mdDoc "Log level of the netbird services."; description = lib.mdDoc "Log level of the netbird services.";
}; };
enableDeviceAuthorizationFlow = enableDeviceAuthorizationFlow = mkEnableOption "device authorization flow for netbird." // {
mkEnableOption "device authorization flow for netbird." // {
default = true; default = true;
}; };
@ -232,8 +271,7 @@ in {
disableAnonymousMetrics = mkOption { disableAnonymousMetrics = mkOption {
type = types.bool; type = types.bool;
default = true; default = true;
description = description = lib.mdDoc "Disables push of anonymous usage metrics to NetBird.";
lib.mdDoc "Disables push of anonymous usage metrics to NetBird.";
}; };
disableSingleAccountMode = mkOption { disableSingleAccountMode = mkOption {
@ -250,38 +288,32 @@ in {
TURN_PASSWORD = mkOption { TURN_PASSWORD = mkOption {
type = with types; nullOr path; type = with types; nullOr path;
default = null; default = null;
description = description = lib.mdDoc "Path to a file containing the secret TURN_PASSWORD.";
lib.mdDoc "Path to a file containing the secret TURN_PASSWORD.";
}; };
TURN_SECRET = mkOption { TURN_SECRET = mkOption {
type = with types; nullOr path; type = with types; nullOr path;
default = null; default = null;
description = description = lib.mdDoc "Path to a file containing the secret TURN_SECRET.";
lib.mdDoc "Path to a file containing the secret TURN_SECRET.";
}; };
STUN_PASSWORD = mkOption { STUN_PASSWORD = mkOption {
type = with types; nullOr path; type = with types; nullOr path;
default = null; default = null;
description = description = lib.mdDoc "Path to a file containing the secret STUN_PASSWORD.";
lib.mdDoc "Path to a file containing the secret STUN_PASSWORD.";
}; };
AUTH_CLIENT_SECRET = mkOption { AUTH_CLIENT_SECRET = mkOption {
type = with types; nullOr path; type = with types; nullOr path;
default = null; default = null;
description = lib.mdDoc description = lib.mdDoc "Path to a file containing the secret NETBIRD_AUTH_CLIENT_SECRET.";
"Path to a file containing the secret NETBIRD_AUTH_CLIENT_SECRET.";
}; };
IDP_MGMT_CLIENT_SECRET = mkOption { IDP_MGMT_CLIENT_SECRET = mkOption {
type = with types; nullOr path; type = with types; nullOr path;
default = cfg.secretFiles.AUTH_CLIENT_SECRET; default = cfg.secretFiles.AUTH_CLIENT_SECRET;
defaultText = defaultText = lib.literalExpression "cfg.secretFiles.AUTH_CLIENT_SECRET;";
lib.literalExpression "cfg.secretFiles.AUTH_CLIENT_SECRET;"; description = lib.mdDoc "Path to a file containing the secret NETBIRD_IDP_MGMT_CLIENT_SECRET.";
description = lib.mdDoc
"Path to a file containing the secret NETBIRD_IDP_MGMT_CLIENT_SECRET.";
}; };
}; };
}; };
@ -289,19 +321,23 @@ in {
config = mkMerge [ config = mkMerge [
(mkIf cfg.enable { (mkIf cfg.enable {
services.netbird-server.managementConfig = with settings; { services.netbird-server.managementConfig = with settings; {
Stuns = mkDefault [{ Stuns = mkDefault [
{
Proto = "udp"; Proto = "udp";
URI = "stun:${TURN_DOMAIN}:${builtins.toString TURN_PORT}"; URI = "stun:${TURN_DOMAIN}:${builtins.toString TURN_PORT}";
Username = STUN_USERNAME; Username = STUN_USERNAME;
Password = STUN_PASSWORD; Password = STUN_PASSWORD;
}]; }
];
TURNConfig = { TURNConfig = {
Turns = [{ Turns = [
{
Proto = "udp"; Proto = "udp";
URI = "turn:${TURN_DOMAIN}:${builtins.toString TURN_PORT}"; URI = "turn:${TURN_DOMAIN}:${builtins.toString TURN_PORT}";
Username = TURN_USER; Username = TURN_USER;
Password = TURN_PASSWORD; Password = TURN_PASSWORD;
}]; }
];
CredentialsTTL = "12h"; CredentialsTTL = "12h";
Secret = TURN_SECRET; Secret = TURN_SECRET;
TimeBasedCredentials = false; TimeBasedCredentials = false;
@ -340,8 +376,7 @@ in {
ClientID = NETBIRD_AUTH_DEVICE_AUTH_CLIENT_ID; ClientID = NETBIRD_AUTH_DEVICE_AUTH_CLIENT_ID;
TokenEndpoint = NETBIRD_AUTH_TOKEN_ENDPOINT; TokenEndpoint = NETBIRD_AUTH_TOKEN_ENDPOINT;
DeviceAuthEndpoint = NETBIRD_AUTH_DEVICE_AUTH_ENDPOINT; DeviceAuthEndpoint = NETBIRD_AUTH_DEVICE_AUTH_ENDPOINT;
Scope = Scope = builtins.concatStringsSep " " NETBIRD_AUTH_DEVICE_AUTH_SCOPE;
builtins.concatStringsSep " " NETBIRD_AUTH_DEVICE_AUTH_SCOPE;
UseIDToken = NETBIRD_AUTH_DEVICE_AUTH_USE_ID_TOKEN; UseIDToken = NETBIRD_AUTH_DEVICE_AUTH_USE_ID_TOKEN;
}; };
}; };
@ -377,13 +412,10 @@ in {
grpc_socket_keepalive on; grpc_socket_keepalive on;
''; '';
"/api".proxyPass = "/api".proxyPass = "http://localhost:${builtins.toString cfg.ports.management}";
"http://localhost:${builtins.toString cfg.ports.management}";
"/management.ManagementService/".extraConfig = '' "/management.ManagementService/".extraConfig = ''
grpc_pass grpc://localhost:${ grpc_pass grpc://localhost:${builtins.toString cfg.ports.management};
builtins.toString cfg.ports.management
};
grpc_read_timeout 1d; grpc_read_timeout 1d;
grpc_send_timeout 1d; grpc_send_timeout 1d;
grpc_socket_keepalive on; grpc_socket_keepalive on;
@ -411,12 +443,26 @@ in {
StartLimitBurst = 10; StartLimitBurst = 10;
}; };
path = (with pkgs; [ coreutils findutils gettext gnused ]) path =
++ (optionals cfg.setupAutoOidc (with pkgs; [ curl jq ])); (with pkgs; [
coreutils
findutils
gettext
gnused
])
++ (optionals cfg.setupAutoOidc (
with pkgs;
[
curl
jq
]
));
script = '' script =
''
cp ${managementFile} ${stateDir}/management.json.copy cp ${managementFile} ${stateDir}/management.json.copy
'' + (optionalString cfg.setupAutoOidc '' ''
+ (optionalString cfg.setupAutoOidc ''
mv ${stateDir}/management.json.copy ${stateDir}/management.json mv ${stateDir}/management.json.copy ${stateDir}/management.json
echo "loading OpenID configuration from $NETBIRD_AUTH_OIDC_CONFIGURATION_ENDPOINT to the openid-configuration.json file" echo "loading OpenID configuration from $NETBIRD_AUTH_OIDC_CONFIGURATION_ENDPOINT to the openid-configuration.json file"
curl "$NETBIRD_AUTH_OIDC_CONFIGURATION_ENDPOINT" -q -o ${stateDir}/openid-configuration.json curl "$NETBIRD_AUTH_OIDC_CONFIGURATION_ENDPOINT" -q -o ${stateDir}/openid-configuration.json
@ -428,11 +474,16 @@ in {
export NETBIRD_AUTH_PKCE_AUTHORIZATION_ENDPOINT=$(jq -r '.authorization_endpoint' ${stateDir}/openid-configuration.json) export NETBIRD_AUTH_PKCE_AUTHORIZATION_ENDPOINT=$(jq -r '.authorization_endpoint' ${stateDir}/openid-configuration.json)
envsubst '$NETBIRD_AUTH_AUTHORITY $NETBIRD_AUTH_JWT_CERTS $NETBIRD_AUTH_TOKEN_ENDPOINT $NETBIRD_AUTH_DEVICE_AUTH_ENDPOINT $NETBIRD_AUTH_PKCE_AUTHORIZATION_ENDPOINT' < ${stateDir}/management.json > ${stateDir}/management.json.copy envsubst '$NETBIRD_AUTH_AUTHORITY $NETBIRD_AUTH_JWT_CERTS $NETBIRD_AUTH_TOKEN_ENDPOINT $NETBIRD_AUTH_DEVICE_AUTH_ENDPOINT $NETBIRD_AUTH_PKCE_AUTHORIZATION_ENDPOINT' < ${stateDir}/management.json > ${stateDir}/management.json.copy
'') + '' '')
+ ''
# Update secrets in management.json # Update secrets in management.json
${builtins.concatStringsSep "\n" (builtins.attrValues ${builtins.concatStringsSep "\n" (
(builtins.mapAttrs (name: path: "export ${name}=$(cat ${path})") builtins.attrValues (
(filterAttrs (_: p: p != null) cfg.secretFiles)))} builtins.mapAttrs (name: path: "export ${name}=$(cat ${path})") (
filterAttrs (_: p: p != null) cfg.secretFiles
)
)
)}
envsubst '$TURN_PASSWORD $TURN_SECRET $STUN_PASSWORD $AUTH_CLIENT_SECRET $IDP_MGMT_CLIENT_SECRET' < ${stateDir}/management.json.copy > ${stateDir}/management.json envsubst '$TURN_PASSWORD $TURN_SECRET $STUN_PASSWORD $AUTH_CLIENT_SECRET $IDP_MGMT_CLIENT_SECRET' < ${stateDir}/management.json.copy > ${stateDir}/management.json
@ -463,7 +514,10 @@ in {
netbird-signal = { netbird-signal = {
after = [ "network.target" ]; after = [ "network.target" ];
wantedBy = [ "netbird-management.service" ]; wantedBy = [ "netbird-management.service" ];
restartTriggers = [ settingsFile managementFile ]; restartTriggers = [
settingsFile
managementFile
];
serviceConfig = { serviceConfig = {
ExecStart = '' ExecStart = ''
@ -487,24 +541,27 @@ in {
netbird-management = { netbird-management = {
description = "The management server for Netbird, a wireguard VPN"; description = "The management server for Netbird, a wireguard VPN";
documentation = [ "https://netbird.io/docs/" ]; documentation = [ "https://netbird.io/docs/" ];
after = [ "network.target" "netbird-setup.service" ]; after = [
"network.target"
"netbird-setup.service"
];
wantedBy = [ "multi-user.target" ]; wantedBy = [ "multi-user.target" ];
wants = [ "netbird-signal.service" "netbird-setup.service" ]; wants = [
restartTriggers = [ settingsFile managementFile ]; "netbird-signal.service"
"netbird-setup.service"
];
restartTriggers = [
settingsFile
managementFile
];
serviceConfig = { serviceConfig = {
ExecStart = '' ExecStart = ''
${cfg.package}/bin/netbird-mgmt management \ ${cfg.package}/bin/netbird-mgmt management \
--config ${stateDir}/management.json \ --config ${stateDir}/management.json \
--datadir ${stateDir}/data \ --datadir ${stateDir}/data \
${ ${optionalString cfg.management.disableAnonymousMetrics "--disable-anonymous-metrics"} \
optionalString cfg.management.disableAnonymousMetrics ${optionalString cfg.management.disableSingleAccountMode "--disable-single-account-mode"} \
"--disable-anonymous-metrics"
} \
${
optionalString cfg.management.disableSingleAccountMode
"--disable-single-account-mode"
} \
--dns-domain ${cfg.management.dnsDomain} \ --dns-domain ${cfg.management.dnsDomain} \
--single-account-mode-domain ${cfg.management.singleAccountModeDomain} \ --single-account-mode-domain ${cfg.management.singleAccountModeDomain} \
--idp-sign-key-refresh-enabled \ --idp-sign-key-refresh-enabled \
@ -514,7 +571,10 @@ in {
''; '';
Restart = "always"; Restart = "always";
RuntimeDirectory = "netbird-mgmt"; RuntimeDirectory = "netbird-mgmt";
StateDirectory = [ "netbird-mgmt" "netbird-mgmt/data" ]; StateDirectory = [
"netbird-mgmt"
"netbird-mgmt/data"
];
WorkingDirectory = stateDir; WorkingDirectory = stateDir;
}; };
unitConfig = { unitConfig = {
@ -549,18 +609,25 @@ in {
5349 5349
5350 5350
]; ];
allowedTCPPorts = with settings; [ TURN_PORT (TURN_PORT + 1) ]; allowedTCPPorts = with settings; [
allowedUDPPortRanges = [{ TURN_PORT
(TURN_PORT + 1)
];
allowedUDPPortRanges = [
{
from = settings.TURN_MIN_PORT; from = settings.TURN_MIN_PORT;
to = settings.TURN_MAX_PORT; to = settings.TURN_MAX_PORT;
}]; }
];
}; };
}) })
(mkIf (cfg.enableNginx && cfg.enableCoturn) { (mkIf (cfg.enableNginx && cfg.enableCoturn) {
services.coturn = services.coturn =
let cert = config.security.acme.certs.${settings.TURN_DOMAIN}; let
in { cert = config.security.acme.certs.${settings.TURN_DOMAIN};
in
{
cert = "${cert.directory}/fullchain.pem"; cert = "${cert.directory}/fullchain.pem";
pkey = "${cert.directory}/key.pem"; pkey = "${cert.directory}/key.pem";
}; };
@ -570,8 +637,7 @@ in {
# share certs with coturn and restart on renewal # share certs with coturn and restart on renewal
security.acme.certs.${settings.TURN_DOMAIN} = { security.acme.certs.${settings.TURN_DOMAIN} = {
group = "turnserver"; group = "turnserver";
postRun = postRun = "systemctl reload nginx.service; systemctl restart coturn.service";
"systemctl reload nginx.service; systemctl restart coturn.service";
}; };
}) })
]; ];

View file

@ -1,4 +1,8 @@
{ lib, buildNpmPackage, fetchFromGitHub }: {
lib,
buildNpmPackage,
fetchFromGitHub,
}:
buildNpmPackage rec { buildNpmPackage rec {
pname = "netbird-dashboard"; pname = "netbird-dashboard";

View file

@ -1,4 +1,6 @@
{ pkgs ? import <nixpkgs> {} }: {
pkgs ? import <nixpkgs> { },
}:
{ {
dashboard = pkgs.callPackage ./dashboard.nix { }; dashboard = pkgs.callPackage ./dashboard.nix { };

View file

@ -1,7 +1,9 @@
{ config, ... }: { config, ... }:
let host = "videos.dgnum.eu"; let
in { host = "videos.dgnum.eu";
in
{
services.peertube = { services.peertube = {
enable = true; enable = true;
@ -53,8 +55,7 @@ in {
database.createLocally = true; database.createLocally = true;
smtp.passwordFile = config.age.secrets."peertube-smtp_password_file".path; smtp.passwordFile = config.age.secrets."peertube-smtp_password_file".path;
serviceEnvironmentFile = serviceEnvironmentFile = config.age.secrets."peertube-service_environment_file".path;
config.age.secrets."peertube-service_environment_file".path;
secrets.secretsFile = config.age.secrets."peertube-secrets_file".path; secrets.secretsFile = config.age.secrets."peertube-secrets_file".path;
}; };
@ -63,5 +64,7 @@ in {
forceSSL = true; forceSSL = true;
}; };
age-secrets.matches."^peertube-.*$" = { owner = "peertube"; }; age-secrets.matches."^peertube-.*$" = {
owner = "peertube";
};
} }

View file

@ -1,8 +1,8 @@
let let
lib = import ../../../lib { }; lib = import ../../../lib { };
publicKeys = lib.getNodeKeys "storage01"; publicKeys = lib.getNodeKeys "storage01";
in
in lib.setDefault { inherit publicKeys; } [ lib.setDefault { inherit publicKeys; } [
"atticd-credentials_file" "atticd-credentials_file"
"forgejo-database_password_file" "forgejo-database_password_file"
"forgejo_runners-token_file" "forgejo_runners-token_file"

View file

@ -11,8 +11,10 @@ lib.extra.mkConfig {
]; ];
extraConfig = { extraConfig = {
dgn-fail2ban.jails = dgn-fail2ban.jails = lib.extra.enableAttrs' "enabled" [
lib.extra.enableAttrs' "enabled" [ "sshd-bruteforce" "sshd-timeout" ]; "sshd-bruteforce"
"sshd-timeout"
];
services.netbird.enable = true; services.netbird.enable = true;

View file

@ -8,8 +8,14 @@
boot = { boot = {
initrd = { initrd = {
availableKernelModules = availableKernelModules = [
[ "xhci_pci" "megaraid_sas" "ehci_pci" "ahci" "usb_storage" "sd_mod" ]; "xhci_pci"
"megaraid_sas"
"ehci_pci"
"ahci"
"usb_storage"
"sd_mod"
];
kernelModules = [ ]; kernelModules = [ ];
}; };
@ -30,6 +36,5 @@
}; };
}; };
swapDevices = swapDevices = [ { device = "/dev/disk/by-uuid/954ecb9c-ccd1-4e98-9eb6-3514bd3c01d1"; } ];
[{ device = "/dev/disk/by-uuid/954ecb9c-ccd1-4e98-9eb6-3514bd3c01d1"; }];
} }

View file

@ -1,6 +1,5 @@
let let
lib = import ../../../lib { }; lib = import ../../../lib { };
publicKeys = lib.getNodeKeys "vault01"; publicKeys = lib.getNodeKeys "vault01";
in
in lib.setDefault { inherit publicKeys; } [ lib.setDefault { inherit publicKeys; } [ ]
]

View file

@ -6,7 +6,12 @@
{ {
imports = [ imports = [
(modulesPath + "/profiles/qemu-guest.nix") (modulesPath + "/profiles/qemu-guest.nix")
(let sources = import ../../npins; in sources.disko + "/module.nix") (
let
sources = import ../../npins;
in
sources.disko + "/module.nix"
)
./disko.nix ./disko.nix
]; ];
} }

View file

@ -16,7 +16,7 @@ in
''; '';
}; };
locations."~ \.php$" = { locations."~ .php$" = {
extraConfig = lib.mkForce '' extraConfig = lib.mkForce ''
error_page 550 = @force_get; error_page 550 = @force_get;
if ($request_method = HEAD) { return 550; } if ($request_method = HEAD) { return 550; }

View file

@ -3,10 +3,10 @@ let
host = "podcasts.dgnum.eu"; host = "podcasts.dgnum.eu";
in in
{ {
imports = [ imports = [ ./castopod-head-proxy.nix ];
./castopod-head-proxy.nix
]; services = {
services.castopod = { castopod = {
enable = true; enable = true;
localDomain = host; localDomain = host;
environmentFile = config.age.secrets.castopod-environment_file.path; environmentFile = config.age.secrets.castopod-environment_file.path;
@ -30,9 +30,12 @@ in
database.createLocally = true; database.createLocally = true;
configureNginx = true; configureNginx = true;
}; };
services.mysql.package = pkgs.mariadb;
services.nginx.virtualHosts.${host} = { mysql.package = pkgs.mariadb;
nginx.virtualHosts.${host} = {
forceSSL = true; forceSSL = true;
enableACME = true; enableACME = true;
}; };
};
} }

View file

@ -56,7 +56,10 @@ in
mountpoint = "/var/log"; mountpoint = "/var/log";
}; };
"/nix" = { "/nix" = {
mountOptions = [ "noatime" "compress=zstd" ]; mountOptions = [
"noatime"
"compress=zstd"
];
mountpoint = "/nix"; mountpoint = "/nix";
}; };
}; };

View file

@ -1,5 +1,4 @@
{ ... }: _: {
{
services.dolibarr = { services.dolibarr = {
enable = true; enable = true;
domain = "erp.dgnum.eu"; domain = "erp.dgnum.eu";

View file

@ -1,4 +1,9 @@
{ sources, pkgs, lib, ... }: {
sources,
pkgs,
lib,
...
}:
let let
host = "cal.dgnum.eu"; host = "cal.dgnum.eu";
@ -26,7 +31,8 @@ let
calendars = metis2linkal sources.metis; calendars = metis2linkal sources.metis;
}; };
}; };
in { in
{
imports = [ ./module.nix ]; imports = [ ./module.nix ];
dgn-linkal = { dgn-linkal = {

View file

@ -7,18 +7,10 @@ let
inherit (import source { inherit pkgs; }) providers; inherit (import source { inherit pkgs; }) providers;
# helper function to map 2-level deep attribute-sets # helper function to map 2-level deep attribute-sets
mapDeepAttrs = mapFct: mapDeepAttrs =
lib.concatMapAttrs (name: value: mapFct:
lib.mapAttrs' (name': value': lib.concatMapAttrs (name: value: lib.mapAttrs' (name': value': mapFct name name' value') value);
mapFct name name' value'
) value
);
toLinkal = upstream: identifier:
lib.nameValuePair
"${providers.${upstream}}${identifier}"
;
toLinkal = upstream: identifier: lib.nameValuePair "${providers.${upstream}}${identifier}";
in in
mapDeepAttrs toLinkal calendars mapDeepAttrs toLinkal calendars

View file

@ -1,14 +1,28 @@
{ config, lib, pkgs, sources, ... }: {
config,
lib,
pkgs,
sources,
...
}:
let let
inherit (lib) mapAttrs' mkEnableOption mkIf mkOption nameValuePair types; inherit (lib)
mapAttrs'
mkEnableOption
mkIf
mkOption
nameValuePair
types
;
package = import sources.linkal { inherit pkgs; }; package = import sources.linkal { inherit pkgs; };
cfg = config.dgn-linkal; cfg = config.dgn-linkal;
jsonFormat = pkgs.formats.json { }; jsonFormat = pkgs.formats.json { };
in { in
{
options.dgn-linkal = { options.dgn-linkal = {
enable = mkEnableOption "the linkal server."; enable = mkEnableOption "the linkal server.";
@ -20,32 +34,40 @@ in {
domain = mkOption { type = types.str; }; domain = mkOption { type = types.str; };
calendarGroups = mkOption { calendarGroups = mkOption {
type = let inherit (types) attrsOf port submodule; type =
in attrsOf (submodule { let
inherit (types) attrsOf port submodule;
in
attrsOf (
submodule {
options = { options = {
port = mkOption { type = port; }; port = mkOption { type = port; };
calendars = mkOption { inherit (jsonFormat) type; }; calendars = mkOption { inherit (jsonFormat) type; };
}; };
}); }
);
default = { }; default = { };
}; };
}; };
config = mkIf cfg.enable { config = mkIf cfg.enable {
systemd.services = mapAttrs' (name: systemd.services =
mapAttrs'
(
name:
{ port, calendars }: { port, calendars }:
nameValuePair "linkal-${name}" { nameValuePair "linkal-${name}" {
description = "Linkal - ${name}"; description = "Linkal - ${name}";
wantedBy = [ "multi-user.target" ]; wantedBy = [ "multi-user.target" ];
serviceConfig = { serviceConfig = {
Type = "simple"; Type = "simple";
ExecStart = "${cfg.package}/bin/linkal --port ${ ExecStart = "${cfg.package}/bin/linkal --port ${builtins.toString port} --calendar-file ${
builtins.toString port
} --calendar-file ${
jsonFormat.generate "linkal-${name}.json" { inherit calendars; } jsonFormat.generate "linkal-${name}.json" { inherit calendars; }
}"; }";
}; };
}) cfg.calendarGroups; }
)
cfg.calendarGroups;
# Configure bind for DNS certificate validation on *.cal.dgnum.eu. # Configure bind for DNS certificate validation on *.cal.dgnum.eu.
# services.bind = { # services.bind = {
@ -85,16 +107,20 @@ in {
services.nginx = { services.nginx = {
enable = true; enable = true;
virtualHosts = mapAttrs' (name: virtualHosts =
mapAttrs'
(
name:
{ port, ... }: { port, ... }:
nameValuePair "${name}.${cfg.domain}" { nameValuePair "${name}.${cfg.domain}" {
enableACME = true; enableACME = true;
# acmeRoot = null; # Use DNS-01 validation # acmeRoot = null; # Use DNS-01 validation
forceSSL = true; forceSSL = true;
locations."/".proxyPass = locations."/".proxyPass = "http://127.0.0.1:${builtins.toString port}/";
"http://127.0.0.1:${builtins.toString port}/"; }
}) cfg.calendarGroups; )
cfg.calendarGroups;
}; };
}; };
} }

View file

@ -6,5 +6,7 @@
configPath = config.age.secrets."matterbridge-config_file".path; configPath = config.age.secrets."matterbridge-config_file".path;
}; };
age-secrets.matches."^matterbridge-.*$" = { owner = "matterbridge"; }; age-secrets.matches."^matterbridge-.*$" = {
owner = "matterbridge";
};
} }

View file

@ -1,16 +1,25 @@
{ lib, pkgs, sources, ... }: {
lib,
pkgs,
sources,
...
}:
let let
metis = import sources.metis { inherit pkgs; }; metis = import sources.metis { inherit pkgs; };
inherit (metis) providers; inherit (metis) providers;
in { in
{
services.nginx.virtualHosts."calendrier.dgnum.eu" = { services.nginx.virtualHosts."calendrier.dgnum.eu" = {
enableACME = true; enableACME = true;
forceSSL = true; forceSSL = true;
root = metis.production; root = metis.production;
locations = lib.mapAttrs' (name: value: locations =
lib.mapAttrs'
(
name: value:
lib.nameValuePair "/cal/${name}/" { lib.nameValuePair "/cal/${name}/" {
extraConfig = '' extraConfig = ''
proxy_set_header X-Forwarded-Host $host; proxy_set_header X-Forwarded-Host $host;
@ -18,7 +27,9 @@ in {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass ${value}; proxy_pass ${value};
''; '';
}) providers; }
)
providers;
extraConfig = '' extraConfig = ''
rewrite ^/calendrier(.*)$ $1 permanent; rewrite ^/calendrier(.*)$ $1 permanent;

View file

@ -1,8 +1,9 @@
{ config, ... }: { config, ... }:
let host = "push.dgnum.eu"; let
host = "push.dgnum.eu";
in { in
{
services.ntfy-sh = { services.ntfy-sh = {
enable = true; enable = true;
@ -26,6 +27,7 @@ in {
}; };
}; };
systemd.services.ntfy-sh.serviceConfig.EnvironmentFile = systemd.services.ntfy-sh.serviceConfig.EnvironmentFile = [
[ config.age.secrets."ntfy_sh-environment_file".path ]; config.age.secrets."ntfy_sh-environment_file".path
];
} }

View file

@ -3,15 +3,19 @@ _:
let let
retired_host = "retired.dgnum.eu"; retired_host = "retired.dgnum.eu";
mkRetired = hosts: mkRetired =
builtins.listToAttrs (builtins.map (name: { hosts:
builtins.listToAttrs (
builtins.map
(name: {
inherit name; inherit name;
value.to = retired_host; value.to = retired_host;
}) hosts); })
hosts
);
mkSub = domain: builtins.map (s: "${s}.${domain}"); mkSub = domain: builtins.map (s: "${s}.${domain}");
mkSubs = attrs: mkSubs = attrs: builtins.concatLists (builtins.attrValues (builtins.mapAttrs mkSub attrs));
builtins.concatLists (builtins.attrValues (builtins.mapAttrs mkSub attrs));
redirections = { redirections = {
"calendrier.eleves.ens.fr".to = "calendrier.dgnum.eu"; "calendrier.eleves.ens.fr".to = "calendrier.dgnum.eu";
@ -23,9 +27,15 @@ let
} // (mkRetired retired); } // (mkRetired retired);
retired = mkSubs { retired = mkSubs {
"ens.fr" = [ "alevins" "www.climatenavigator" ]; "ens.fr" = [
"alevins"
"www.climatenavigator"
];
"ens.wtf" = [ "photos" ]; "ens.wtf" = [ "photos" ];
"rz.ens.wtf" = [ "s3" "cdn" ]; "rz.ens.wtf" = [
"s3"
"cdn"
];
"beta.rz.ens.wtf" = [ "beta.rz.ens.wtf" = [
"todo" "todo"
"minecraft" "minecraft"
@ -39,14 +49,25 @@ let
"rstudio" "rstudio"
]; ];
}; };
in
in { {
services.nginx.virtualHosts = { services.nginx.virtualHosts =
{
${retired_host}.default = true; ${retired_host}.default = true;
} // (builtins.mapAttrs (host: }
{ to, ssl ? true }: { // (builtins.mapAttrs
(
_:
{
to,
ssl ? true,
}:
{
globalRedirect = to; globalRedirect = to;
enableACME = ssl; enableACME = ssl;
forceSSL = ssl; forceSSL = ssl;
}) redirections); }
)
redirections
);
} }

View file

@ -1,7 +1,8 @@
let let
lib = import ../../../lib { }; lib = import ../../../lib { };
publicKeys = lib.getNodeKeys "web01"; publicKeys = lib.getNodeKeys "web01";
in lib.setDefault { inherit publicKeys; } [ in
lib.setDefault { inherit publicKeys; } [
"acme-certs_secret" "acme-certs_secret"
"matterbridge-config_file" "matterbridge-config_file"
"named-bind_dnskeys_conf" "named-bind_dnskeys_conf"

View file

@ -1,20 +1,34 @@
# Generated by npins. Do not modify; will be overwritten regularly # Generated by npins. Do not modify; will be overwritten regularly
let let
data = builtins.fromJSON (builtins.readFile ./sources.json); data = builtins.fromJSON (builtins.readFile ./sources.json);
version = data.version; inherit (data) version;
mkSource = spec: mkSource =
assert spec ? type; let spec:
assert spec ? type;
let
path = path =
if spec.type == "Git" then mkGitSource spec if spec.type == "Git" then
else if spec.type == "GitRelease" then mkGitSource spec mkGitSource spec
else if spec.type == "PyPi" then mkPyPiSource spec else if spec.type == "GitRelease" then
else if spec.type == "Channel" then mkChannelSource spec mkGitSource spec
else builtins.throw "Unknown source type ${spec.type}"; else if spec.type == "PyPi" then
mkPyPiSource spec
else if spec.type == "Channel" then
mkChannelSource spec
else
builtins.throw "Unknown source type ${spec.type}";
in in
spec // { outPath = path; }; spec // { outPath = path; };
mkGitSource = { repository, revision, url ? null, hash, ... }: mkGitSource =
{
repository,
revision,
url ? null,
hash,
...
}:
assert repository ? type; assert repository ? type;
# At the moment, either it is a plain git repository (which has an url), or it is a GitHub/GitLab repository # At the moment, either it is a plain git repository (which has an url), or it is a GitHub/GitLab repository
# In the latter case, there we will always be an url to the tarball # In the latter case, there we will always be an url to the tarball
@ -23,19 +37,23 @@ let
inherit url; inherit url;
sha256 = hash; # FIXME: check nix version & use SRI hashes sha256 = hash; # FIXME: check nix version & use SRI hashes
}) })
else assert repository.type == "Git"; builtins.fetchGit { else
url = repository.url; assert repository.type == "Git";
builtins.fetchGit {
inherit (repository) url;
rev = revision; rev = revision;
# hash = hash; # hash = hash;
}; };
mkPyPiSource = { url, hash, ... }: mkPyPiSource =
{ url, hash, ... }:
builtins.fetchurl { builtins.fetchurl {
inherit url; inherit url;
sha256 = hash; sha256 = hash;
}; };
mkChannelSource = { url, hash, ... }: mkChannelSource =
{ url, hash, ... }:
builtins.fetchTarball { builtins.fetchTarball {
inherit url; inherit url;
sha256 = hash; sha256 = hash;

View file

@ -1,7 +1,9 @@
{ pkgs, sources, ... }: { pkgs, sources, ... }:
let wp4nix = pkgs.callPackage sources.wp4nix { }; let
in { wp4nix = pkgs.callPackage sources.wp4nix { };
in
{
imports = [ ./module.nix ]; imports = [ ./module.nix ];
services.wp-containers = { services.wp-containers = {
@ -9,26 +11,38 @@ in {
sites = { sites = {
"lavoixduntexte.normalesup.eu" = { "lavoixduntexte.normalesup.eu" = {
themes = { inherit (wp4nix.themes) avant; }; themes = {
inherit (wp4nix.themes) avant;
};
plugins = { inherit (wp4nix.plugins) wordpress-importer; }; plugins = {
inherit (wp4nix.plugins) wordpress-importer;
};
languages = [ pkgs.wordpressPackages.languages.fr_FR ]; languages = [ pkgs.wordpressPackages.languages.fr_FR ];
}; };
"bds.wp.dgnum.eu" = { "bds.wp.dgnum.eu" = {
plugins = { inherit (wp4nix.plugins) user-role-editor; }; plugins = {
inherit (wp4nix.plugins) user-role-editor;
};
languages = [ pkgs.wordpressPackages.languages.fr_FR ]; languages = [ pkgs.wordpressPackages.languages.fr_FR ];
themes = { inherit (wp4nix.themes) gateway twentytwentythree; }; themes = {
inherit (wp4nix.themes) gateway twentytwentythree;
};
}; };
"bda.wp.dgnum.eu" = { "bda.wp.dgnum.eu" = {
plugins = { inherit (wp4nix.plugins) user-role-editor; }; plugins = {
inherit (wp4nix.plugins) user-role-editor;
};
languages = [ pkgs.wordpressPackages.languages.fr_FR ]; languages = [ pkgs.wordpressPackages.languages.fr_FR ];
}; };
"cineclub.wp.dgnum.eu" = { "cineclub.wp.dgnum.eu" = {
plugins = { inherit (wp4nix.plugins) user-role-editor; }; plugins = {
inherit (wp4nix.plugins) user-role-editor;
};
languages = [ pkgs.wordpressPackages.languages.fr_FR ]; languages = [ pkgs.wordpressPackages.languages.fr_FR ];
}; };
}; };

View file

@ -1,4 +1,9 @@
{ config, lib, pkgs, ... }: {
config,
lib,
pkgs,
...
}:
let let
inherit (lib) mkEnableOption mkIf mkOption; inherit (lib) mkEnableOption mkIf mkOption;
@ -13,7 +18,13 @@ let
mkHost = mkIp "10.31.41"; mkHost = mkIp "10.31.41";
mkLocal = mkIp "10.0.0"; mkLocal = mkIp "10.0.0";
mkConfig = { name, value, i }: { mkConfig =
{
name,
value,
i,
}:
{
services.wordpress = { services.wordpress = {
webserver = "nginx"; webserver = "nginx";
sites.${name} = value; sites.${name} = value;
@ -33,7 +44,10 @@ let
firewall.allowedTCPPorts = [ 443 ]; firewall.allowedTCPPorts = [ 443 ];
}; };
environment.systemPackages = [ pkgs.wp-cli pkgs.neovim ]; environment.systemPackages = [
pkgs.wp-cli
pkgs.neovim
];
system.stateVersion = "23.11"; system.stateVersion = "23.11";
}; };
@ -44,10 +58,12 @@ let
value = { value = {
privateNetwork = true; privateNetwork = true;
forwardPorts = [{ forwardPorts = [
{
containerPort = 443; containerPort = 443;
hostPort = cfg.basePort + i; hostPort = cfg.basePort + i;
}]; }
];
bindMounts.certs = { bindMounts.certs = {
hostPath = certs.${site.name}.directory; hostPath = certs.${site.name}.directory;
@ -69,13 +85,13 @@ let
enableACME = true; enableACME = true;
forceSSL = true; forceSSL = true;
locations."/".proxyPass = locations."/".proxyPass = "https://${mkHost i}:${builtins.toString (cfg.basePort + i)}";
"https://${mkHost i}:${builtins.toString (cfg.basePort + i)}";
}; };
}; };
siteList = lib.attrsToList cfg.sites; siteList = lib.attrsToList cfg.sites;
in { in
{
options.services.wp-containers = { options.services.wp-containers = {
enable = mkEnableOption "wordpress sites in containers"; enable = mkEnableOption "wordpress sites in containers";
@ -93,7 +109,6 @@ in {
config = mkIf cfg.enable { config = mkIf cfg.enable {
containers = builtins.listToAttrs (lib.imap1 mkContainer siteList); containers = builtins.listToAttrs (lib.imap1 mkContainer siteList);
services.nginx.virtualHosts = services.nginx.virtualHosts = builtins.listToAttrs (lib.imap1 mkVhost siteList);
builtins.listToAttrs (lib.imap1 mkVhost siteList);
}; };
} }

View file

@ -11,8 +11,10 @@ lib.extra.mkConfig {
]; ];
extraConfig = { extraConfig = {
dgn-fail2ban.jails = dgn-fail2ban.jails = lib.extra.enableAttrs' "enabled" [
lib.extra.enableAttrs' "enabled" [ "sshd-bruteforce" "sshd-timeout" ]; "sshd-bruteforce"
"sshd-timeout"
];
services.netbird.enable = true; services.netbird.enable = true;
}; };

View file

@ -8,8 +8,14 @@
boot = { boot = {
initrd = { initrd = {
availableKernelModules = availableKernelModules = [
[ "ata_piix" "uhci_hcd" "ehci_pci" "virtio_pci" "sr_mod" "virtio_blk" ]; "ata_piix"
"uhci_hcd"
"ehci_pci"
"virtio_pci"
"sr_mod"
"virtio_blk"
];
kernelModules = [ ]; kernelModules = [ ];
}; };
@ -30,6 +36,5 @@
}; };
}; };
swapDevices = swapDevices = [ { device = "/dev/disk/by-uuid/d64ae21e-693c-4c77-b62c-97d5e2a960cb"; } ];
[{ device = "/dev/disk/by-uuid/d64ae21e-693c-4c77-b62c-97d5e2a960cb"; }];
} }

View file

@ -1,6 +1,5 @@
let let
lib = import ../../../lib { }; lib = import ../../../lib { };
publicKeys = lib.getNodeKeys "web02"; publicKeys = lib.getNodeKeys "web02";
in
in lib.setDefault { inherit publicKeys; } [ lib.setDefault { inherit publicKeys; } [ ]
]

View file

@ -8,9 +8,7 @@
]; ];
# Jourdan # Jourdan
par02 = [ par02 = [ "vault01" ];
"vault01"
];
# VMs du SPI/NPS/Whatever # VMs du SPI/NPS/Whatever
dmi01 = [ dmi01 = [

View file

@ -26,15 +26,25 @@ let
groups = { groups = {
# members of this group are root on all nodes # members of this group are root on all nodes
root = [ "thubrecht" "raito" "mdebray" ]; root = [
"thubrecht"
"raito"
"mdebray"
];
# members of this group will have root access on the installation isos # members of this group will have root access on the installation isos
iso = [ "thubrecht" "mdebray" "raito" ]; iso = [
"thubrecht"
"mdebray"
"raito"
];
# members of this group can access netbox's secret # members of this group can access netbox's secret
netbox = [ ]; netbox = [ ];
bureau = [ "gdd" ]; bureau = [ "gdd" ];
}; };
in
in { inherit groups members; } {
inherit groups members;
}

View file

@ -1,27 +1,47 @@
let let
mkDefaultInterface = _: attrs: { ipv4 = [ ]; ipv6 = [ ]; gateways = [ ]; } // attrs; mkDefaultInterface =
_: attrs:
{
ipv4 = [ ];
ipv6 = [ ];
gateways = [ ];
}
// attrs;
mkBase = config: config // { interfaces = builtins.mapAttrs mkDefaultInterface (config.interfaces or { }); }; mkBase =
config: config // { interfaces = builtins.mapAttrs mkDefaultInterface (config.interfaces or { }); };
getAddresses = version: interface: builtins.map (builtins.getAttr "address") interface.${version}; getAddresses = version: interface: builtins.map (builtins.getAttr "address") interface.${version};
filterIPv4 = ip: builtins.substring 0 7 ip != "192.168"; filterIPv4 = ip: builtins.substring 0 7 ip != "192.168";
filterIPv6 = _: true; filterIPv6 = _: true;
mkNet = _: value: mkNet =
let base = mkBase value; in _: value:
base // { let
base = mkBase value;
in
base
// {
addresses = addresses =
let let
_addresses = builtins.foldl' _addresses =
({ ipv4, ipv6 }: net: { builtins.foldl'
(
{ ipv4, ipv6 }:
net: {
ipv4 = ipv4 ++ getAddresses "ipv4" net; ipv4 = ipv4 ++ getAddresses "ipv4" net;
ipv6 = ipv6 ++ getAddresses "ipv6" net; ipv6 = ipv6 ++ getAddresses "ipv6" net;
}) }
{ ipv4 = [ ]; ipv6 = [ ]; } )
{
ipv4 = [ ];
ipv6 = [ ];
}
(builtins.attrValues base.interfaces); (builtins.attrValues base.interfaces);
in in
_addresses // rec { _addresses
// rec {
publicV4 = builtins.filter filterIPv4 _addresses.ipv4; publicV4 = builtins.filter filterIPv4 _addresses.ipv4;
publicV6 = builtins.filter filterIPv6 _addresses.ipv6; publicV6 = builtins.filter filterIPv6 _addresses.ipv6;
public = publicV4 ++ publicV6; public = publicV4 ++ publicV6;
@ -34,8 +54,14 @@ builtins.mapAttrs mkNet {
interfaces = { interfaces = {
eno1 = { eno1 = {
ipv4 = [ ipv4 = [
{ address = "129.199.146.147"; prefixLength = 24; } {
{ address = "192.168.1.147"; prefixLength = 24; } address = "129.199.146.147";
prefixLength = 24;
}
{
address = "192.168.1.147";
prefixLength = 24;
}
]; ];
gateways = [ "129.199.146.254" ]; gateways = [ "129.199.146.254" ];
@ -49,8 +75,14 @@ builtins.mapAttrs mkNet {
interfaces = { interfaces = {
eno1 = { eno1 = {
ipv4 = [ ipv4 = [
{ address = "129.199.146.148"; prefixLength = 24; } {
{ address = "192.168.1.148"; prefixLength = 24; } address = "129.199.146.148";
prefixLength = 24;
}
{
address = "192.168.1.148";
prefixLength = 24;
}
]; ];
gateways = [ "129.199.146.254" ]; gateways = [ "129.199.146.254" ];
@ -64,7 +96,10 @@ builtins.mapAttrs mkNet {
interfaces = { interfaces = {
enp130s0f0 = { enp130s0f0 = {
ipv4 = [ ipv4 = [
{ address = "129.199.210.85"; prefixLength = 24; } {
address = "129.199.210.85";
prefixLength = 24;
}
]; ];
gateways = [ "129.199.210.254" ]; gateways = [ "129.199.210.254" ];
@ -77,7 +112,12 @@ builtins.mapAttrs mkNet {
web01 = { web01 = {
interfaces = { interfaces = {
ens3 = { ens3 = {
ipv4 = [{ address = "129.199.129.53"; prefixLength = 24; }]; ipv4 = [
{
address = "129.199.129.53";
prefixLength = 24;
}
];
gateways = [ "129.199.129.1" ]; gateways = [ "129.199.129.1" ];
}; };
@ -89,7 +129,12 @@ builtins.mapAttrs mkNet {
web02 = { web02 = {
interfaces = { interfaces = {
ens3 = { ens3 = {
ipv4 = [{ address = "129.199.129.235"; prefixLength = 24; }]; ipv4 = [
{
address = "129.199.129.235";
prefixLength = 24;
}
];
gateways = [ "129.199.129.1" ]; gateways = [ "129.199.129.1" ];
}; };

View file

@ -11,14 +11,17 @@
# } # }
let let
mkNode = _: attrs: { mkNode =
_: attrs:
{
adminGroups = [ ]; adminGroups = [ ];
admins = [ ]; admins = [ ];
deployment = { }; deployment = { };
nixpkgs = "23.11"; nixpkgs = "23.11";
} // attrs; }
// attrs;
in in
builtins.mapAttrs mkNode { builtins.mapAttrs mkNode {

View file

@ -35,7 +35,8 @@
{ lib, sources, ... }: { lib, sources, ... }:
{ {
imports = (lib.extra.mkImports ./. [ imports =
(lib.extra.mkImports ./. [
"dgn-access-control" "dgn-access-control"
"dgn-acme" "dgn-acme"
"dgn-console" "dgn-console"
@ -45,10 +46,12 @@
"dgn-ssh" "dgn-ssh"
"dgn-web" "dgn-web"
"dgn-vm-variant" "dgn-vm-variant"
]) ++ [ ])
++ [
"${sources.agenix}/modules/age.nix" "${sources.agenix}/modules/age.nix"
"${sources.attic}/nixos/atticd.nix" "${sources.attic}/nixos/atticd.nix"
] ++ ((import sources.nix-modules { inherit lib; }).importModules [ ]
++ ((import sources.nix-modules { inherit lib; }).importModules [
"age-secrets" "age-secrets"
"services/crabfit" "services/crabfit"
"services/forgejo-nix-runners" "services/forgejo-nix-runners"

View file

@ -31,7 +31,13 @@
# pris connaissance de la licence CeCILL, et que vous en avez accepté les # pris connaissance de la licence CeCILL, et que vous en avez accepté les
# termes. # termes.
{ config, lib, meta, name, ... }: {
config,
lib,
meta,
name,
...
}:
let let
inherit (lib) inherit (lib)
@ -40,10 +46,13 @@ let
mkIf mkIf
mkOption mkOption
types; types
;
nodeMeta = meta.nodes.${name}; nodeMeta = meta.nodes.${name};
admins = meta.members.groups.root ++ nodeMeta.admins admins =
meta.members.groups.root
++ nodeMeta.admins
++ (builtins.concatMap (g: meta.members.groups.${g}) nodeMeta.adminGroups); ++ (builtins.concatMap (g: meta.members.groups.${g}) nodeMeta.adminGroups);
cfg = config.dgn-access-control; cfg = config.dgn-access-control;
@ -51,7 +60,9 @@ in
{ {
options.dgn-access-control = { options.dgn-access-control = {
enable = mkEnableOption "DGNum access control." // { default = true; }; enable = mkEnableOption "DGNum access control." // {
default = true;
};
users = mkOption { users = mkOption {
type = with types; attrsOf (listOf str); type = with types; attrsOf (listOf str);
@ -72,8 +83,8 @@ in
# Admins have root access to the node # Admins have root access to the node
dgn-access-control.users.root = mkDefault admins; dgn-access-control.users.root = mkDefault admins;
users.users = builtins.mapAttrs users.users =
(u: members: { openssh.authorizedKeys.keys = lib.extra.getAllKeys members; }) builtins.mapAttrs (_: members: { openssh.authorizedKeys.keys = lib.extra.getAllKeys members; })
cfg.users; cfg.users;
}; };
} }

View file

@ -34,15 +34,15 @@
{ config, lib, ... }: { config, lib, ... }:
let let
inherit (lib) inherit (lib) mkEnableOption mkIf;
mkEnableOption
mkIf;
cfg = config.dgn-acme; cfg = config.dgn-acme;
in in
{ {
options.dgn-acme.enable = mkEnableOption "ACME settings." // { default = true; }; options.dgn-acme.enable = mkEnableOption "ACME settings." // {
default = true;
};
config = mkIf cfg.enable { config = mkIf cfg.enable {
security.acme = { security.acme = {

View file

@ -1,13 +1,20 @@
{ config, lib, pkgs, ... }: {
config,
lib,
pkgs,
...
}:
let let
inherit (lib) mkEnableOption mkOption mkIf; inherit (lib) mkEnableOption mkOption mkIf;
cfg = config.dgn-console; cfg = config.dgn-console;
in
in { {
options.dgn-console = { options.dgn-console = {
enable = mkEnableOption "DGNum console setup." // { default = true; }; enable = mkEnableOption "DGNum console setup." // {
default = true;
};
pg-upgrade-to = mkOption { pg-upgrade-to = mkOption {
type = lib.types.package; type = lib.types.package;
@ -18,7 +25,9 @@ in {
config = mkIf cfg.enable { config = mkIf cfg.enable {
time.timeZone = "Europe/Paris"; time.timeZone = "Europe/Paris";
console = { keyMap = "fr"; }; console = {
keyMap = "fr";
};
environment.variables.EDITOR = "nvim"; environment.variables.EDITOR = "nvim";
@ -26,7 +35,7 @@ in {
# services.nscd.enableNsncd = false; # services.nscd.enableNsncd = false;
nixpkgs.overlays = [ nixpkgs.overlays = [
(final: prev: { (_: _: {
nsncd = pkgs.rustPlatform.buildRustPackage { nsncd = pkgs.rustPlatform.buildRustPackage {
pname = "nsncd"; pname = "nsncd";
version = "unstable-2023-10-26"; version = "unstable-2023-10-26";
@ -70,10 +79,16 @@ in {
hardware.enableRedistributableFirmware = true; hardware.enableRedistributableFirmware = true;
environment.systemPackages = (with pkgs; [ neovim wget kitty.terminfo ]) environment.systemPackages =
++ lib.optional (config.services.postgresql.enable (with pkgs; [
&& config.services.postgresql.package != cfg.pg-upgrade-to) neovim
(pkgs.writeScriptBin "upgrade-pg-cluster" '' wget
kitty.terminfo
])
++ lib.optional
(config.services.postgresql.enable && config.services.postgresql.package != cfg.pg-upgrade-to)
(
pkgs.writeScriptBin "upgrade-pg-cluster" ''
set -eux set -eux
# XXX it's perhaps advisable to stop all services that depend on postgresql # XXX it's perhaps advisable to stop all services that depend on postgresql
systemctl stop postgresql systemctl stop postgresql
@ -93,6 +108,7 @@ in {
--old-datadir "$OLDDATA" --new-datadir "$NEWDATA" \ --old-datadir "$OLDDATA" --new-datadir "$NEWDATA" \
--old-bindir $OLDBIN --new-bindir $NEWBIN \ --old-bindir $OLDBIN --new-bindir $NEWBIN \
"$@" "$@"
''); ''
);
}; };
} }

View file

@ -1,10 +1,19 @@
{ config, lib, pkgs, ... }: {
config,
lib,
pkgs,
...
}:
let let
inherit (lib) inherit (lib)
mkDefault mkEnableOption mkIf mkOption mkDefault
mkEnableOption
mkIf
mkOption
types; types
;
cfg = config.dgn-fail2ban; cfg = config.dgn-fail2ban;
@ -22,8 +31,7 @@ let
}; };
filter = mkOption { filter = mkOption {
type = type = types.nullOr (types.submodule { freeformType = configFormat.type; });
types.nullOr (types.submodule { freeformType = configFormat.type; });
description = "Content of the filter used for this jail."; description = "Content of the filter used for this jail.";
}; };
@ -36,8 +44,8 @@ let
}; };
}; };
}; };
in
in { {
options.dgn-fail2ban = { options.dgn-fail2ban = {
enable = mkEnableOption "fail2ban service."; enable = mkEnableOption "fail2ban service.";
@ -50,9 +58,9 @@ in {
}; };
config = mkIf cfg.enable { config = mkIf cfg.enable {
dgn-fail2ban.jails = dgn-fail2ban.jails = builtins.mapAttrs (_: j: j // { enabled = mkDefault false; }) (
builtins.mapAttrs (_: j: j // { enabled = mkDefault false; }) import ./jails.nix { }
(import ./jails.nix { }); );
services.fail2ban = { services.fail2ban = {
enable = true; enable = true;

View file

@ -33,8 +33,7 @@
_: { _: {
nginx-spam = { nginx-spam = {
filter.Definition.failregex = '' filter.Definition.failregex = ''^<HOST>.*GET.*(matrix/server|\.php|admin|wp\-).* HTTP/\d.\d\" 404.*$'';
^<HOST>.*GET.*(matrix/server|\.php|admin|wp\-).* HTTP/\d.\d\" 404.*$'';
settings = { settings = {
logpath = "/var/log/nginx/access.log"; logpath = "/var/log/nginx/access.log";

View file

@ -1,11 +1,16 @@
{ config, lib, pkgs, ... }: {
config,
lib,
pkgs,
...
}:
let let
inherit (lib) mkEnableOption mkIf mkMerge; inherit (lib) mkEnableOption mkIf mkMerge;
cfg = config.dgn-hardware; cfg = config.dgn-hardware;
in
in { {
options.dgn-hardware = { options.dgn-hardware = {
enable = mkEnableOption "default hardware configuration." // { enable = mkEnableOption "default hardware configuration." // {
default = true; default = true;
@ -19,7 +24,8 @@ in {
useBcachefs = mkEnableOption "bcachefs configuration"; useBcachefs = mkEnableOption "bcachefs configuration";
}; };
config = mkIf cfg.enable (mkMerge [ config = mkIf cfg.enable (
mkMerge [
{ {
hardware.enableRedistributableFirmware = true; hardware.enableRedistributableFirmware = true;
hardware.cpu.intel.updateMicrocode = true; hardware.cpu.intel.updateMicrocode = true;
@ -27,8 +33,14 @@ in {
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux"; nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
boot = { boot = {
initrd.availableKernelModules = initrd.availableKernelModules = [
[ "ata_piix" "uhci_hcd" "ehci_pci" "virtio_pci" "ahci" "virtio_blk" ]; "ata_piix"
"uhci_hcd"
"ehci_pci"
"virtio_pci"
"ahci"
"virtio_blk"
];
kernelModules = [ "kvm-intel" ]; kernelModules = [ "kvm-intel" ];
kernelParams = [ kernelParams = [
"cgroup_enable=cpu" "cgroup_enable=cpu"
@ -54,10 +66,14 @@ in {
zfs = { zfs = {
forceImportRoot = false; forceImportRoot = false;
extraPools = [ "fast01" "work01" ]; extraPools = [
"fast01"
"work01"
];
package = pkgs.zfs_2_1; package = pkgs.zfs_2_1;
}; };
}; };
}) })
]); ]
);
} }

View file

@ -1,12 +1,22 @@
{ config, lib, meta, name, ... }: {
config,
lib,
meta,
name,
...
}:
let let
inherit (lib) mapAttrs' mkEnableOption mkIf optionalAttrs; inherit (lib)
mapAttrs'
mkEnableOption
mkIf
optionalAttrs
;
net = meta.network.${name}; net = meta.network.${name};
mkAddress = { address, prefixLength, ... }: mkAddress = { address, prefixLength, ... }: "${address}/${builtins.toString prefixLength}";
"${address}/${builtins.toString prefixLength}";
mkRoute = gateway: { mkRoute = gateway: {
routeConfig = { routeConfig = {
Gateway = gateway; Gateway = gateway;
@ -38,10 +48,9 @@ let
}; };
cfg = config.dgn-network; cfg = config.dgn-network;
in
in { {
options.dgn-network.enable = options.dgn-network.enable = mkEnableOption "automatic network configuration based on metadata" // {
mkEnableOption "automatic network configuration based on metadata" // {
default = true; default = true;
}; };

View file

@ -1,14 +1,14 @@
{ config, lib, ... }: { config, lib, ... }:
let let
inherit (lib) inherit (lib) mkEnableOption mkIf;
mkEnableOption
mkIf;
cfg = config.dgn-vmVariant; cfg = config.dgn-vmVariant;
in in
{ {
options.dgn-vmVariant.enable = mkEnableOption "ACME settings." // { default = true; }; options.dgn-vmVariant.enable = mkEnableOption "ACME settings." // {
default = true;
};
config = mkIf cfg.enable { config = mkIf cfg.enable {
virtualisation.vmVariant = { virtualisation.vmVariant = {
@ -16,4 +16,3 @@ in
}; };
}; };
} }

View file

@ -4,7 +4,8 @@ let
inherit (lib) mkEnableOption mkIf; inherit (lib) mkEnableOption mkIf;
cfg = config.dgn-web; cfg = config.dgn-web;
in { in
{
options.dgn-web = { options.dgn-web = {
enable = mkEnableOption "sane defaults for web services."; enable = mkEnableOption "sane defaults for web services.";
}; };
@ -21,6 +22,9 @@ in {
recommendedZstdSettings = true; recommendedZstdSettings = true;
}; };
networking.firewall.allowedTCPPorts = [ 80 443 ]; networking.firewall.allowedTCPPorts = [
80
443
];
}; };
} }

View file

@ -1,20 +1,34 @@
# Generated by npins. Do not modify; will be overwritten regularly # Generated by npins. Do not modify; will be overwritten regularly
let let
data = builtins.fromJSON (builtins.readFile ./sources.json); data = builtins.fromJSON (builtins.readFile ./sources.json);
version = data.version; inherit (data) version;
mkSource = spec: mkSource =
assert spec ? type; let spec:
assert spec ? type;
let
path = path =
if spec.type == "Git" then mkGitSource spec if spec.type == "Git" then
else if spec.type == "GitRelease" then mkGitSource spec mkGitSource spec
else if spec.type == "PyPi" then mkPyPiSource spec else if spec.type == "GitRelease" then
else if spec.type == "Channel" then mkChannelSource spec mkGitSource spec
else builtins.throw "Unknown source type ${spec.type}"; else if spec.type == "PyPi" then
mkPyPiSource spec
else if spec.type == "Channel" then
mkChannelSource spec
else
builtins.throw "Unknown source type ${spec.type}";
in in
spec // { outPath = path; }; spec // { outPath = path; };
mkGitSource = { repository, revision, url ? null, hash, ... }: mkGitSource =
{
repository,
revision,
url ? null,
hash,
...
}:
assert repository ? type; assert repository ? type;
# At the moment, either it is a plain git repository (which has an url), or it is a GitHub/GitLab repository # At the moment, either it is a plain git repository (which has an url), or it is a GitHub/GitLab repository
# In the latter case, there we will always be an url to the tarball # In the latter case, there we will always be an url to the tarball
@ -23,19 +37,23 @@ let
inherit url; inherit url;
sha256 = hash; # FIXME: check nix version & use SRI hashes sha256 = hash; # FIXME: check nix version & use SRI hashes
}) })
else assert repository.type == "Git"; builtins.fetchGit { else
url = repository.url; assert repository.type == "Git";
builtins.fetchGit {
inherit (repository) url;
rev = revision; rev = revision;
# hash = hash; # hash = hash;
}; };
mkPyPiSource = { url, hash, ... }: mkPyPiSource =
{ url, hash, ... }:
builtins.fetchurl { builtins.fetchurl {
inherit url; inherit url;
sha256 = hash; sha256 = hash;
}; };
mkChannelSource = { url, hash, ... }: mkChannelSource =
{ url, hash, ... }:
builtins.fetchTarball { builtins.fetchTarball {
inherit url; inherit url;
sha256 = hash; sha256 = hash;

View file

@ -118,6 +118,18 @@
"url": "https://releases.nixos.org/nixpkgs/nixpkgs-24.05pre578430.5ad9903c1612/nixexprs.tar.xz", "url": "https://releases.nixos.org/nixpkgs/nixpkgs-24.05pre578430.5ad9903c1612/nixexprs.tar.xz",
"hash": "1zg01pxmaf56gqxdf59mj1aanlvkpw5b3gmsx4mawxi6m1f2l6c6" "hash": "1zg01pxmaf56gqxdf59mj1aanlvkpw5b3gmsx4mawxi6m1f2l6c6"
}, },
"pre-commit-hooks": {
"type": "Git",
"repository": {
"type": "GitHub",
"owner": "cachix",
"repo": "pre-commit-hooks.nix"
},
"branch": "master",
"revision": "7c54e08a689b53c8a1e5d70169f2ec9e2a68ffaf",
"url": "https://github.com/cachix/pre-commit-hooks.nix/archive/7c54e08a689b53c8a1e5d70169f2ec9e2a68ffaf.tar.gz",
"hash": "0gj03fzsqcybzr4shj7x62l0xc34w20zhphd2jg7sd2rxaw42x23"
},
"wp4nix": { "wp4nix": {
"type": "Git", "type": "Git",
"repository": { "repository": {

View file

@ -8,10 +8,14 @@ let
coreutils coreutils
nvd nvd
git git
jq; jq
;
}; };
mkShellScript = name: (pkgs.substituteAll ({ mkShellScript =
name:
(pkgs.substituteAll (
{
inherit name; inherit name;
src = ./. + "/${name}.sh"; src = ./. + "/${name}.sh";
dir = "/bin/"; dir = "/bin/";
@ -20,7 +24,9 @@ let
checkPhase = '' checkPhase = ''
${pkgs.stdenv.shellDryRun} "$target" ${pkgs.stdenv.shellDryRun} "$target"
''; '';
} // substitutions)); }
// substitutions
));
scripts = [ scripts = [
"check-deployment" "check-deployment"

View file

@ -1,52 +1 @@
/* (import ./.).shells.default
Copyright :
- Maurice Debray <maurice.debray@dgnum.eu> 2023
- Tom Hubrecht <tom.hubrecht@dgnum.eu> 2023
Ce logiciel est un programme informatique servant à déployer des
configurations de serveurs via NixOS.
Ce logiciel est régi par la licence CeCILL soumise au droit français et
respectant les principes de diffusion des logiciels libres. Vous pouvez
utiliser, modifier et/ou redistribuer ce programme sous les conditions
de la licence CeCILL telle que diffusée par le CEA, le CNRS et l'INRIA
sur le site "http://www.cecill.info".
En contrepartie de l'accessibilité au code source et des droits de copie,
de modification et de redistribution accordés par cette licence, il n'est
offert aux utilisateurs qu'une garantie limitée. Pour les mêmes raisons,
seule une responsabilité restreinte pèse sur l'auteur du programme, le
titulaire des droits patrimoniaux et les concédants successifs.
A cet égard l'attention de l'utilisateur est attirée sur les risques
associés au chargement, à l'utilisation, à la modification et/ou au
développement et à la reproduction du logiciel par l'utilisateur étant
donné sa spécificité de logiciel libre, qui peut le rendre complexe à
manipuler et qui le réserve donc à des développeurs et des professionnels
avertis possédant des connaissances informatiques approfondies. Les
utilisateurs sont donc invités à charger et tester l'adéquation du
logiciel à leurs besoins dans des conditions permettant d'assurer la
sécurité de leurs systèmes et ou de leurs données et, plus généralement,
à l'utiliser et l'exploiter dans les mêmes conditions de sécurité.
Le fait que vous puissiez accéder à cet en-tête signifie que vous avez
pris connaissance de la licence CeCILL, et que vous en avez accepté les
termes.
*/
let
sources = import ./npins;
pkgs = import sources.nixpkgs { };
in
pkgs.mkShell {
packages = (with pkgs; [
npins
colmena
nixos-generators
] ++ (builtins.map (p: callPackage p { }) [
(sources.disko + "/package.nix")
])) ++ (import ./scripts { inherit pkgs; });
preferLocalBuild = true;
}