feat(shell): Add pre-commit hooks and reformat the repo
This commit is contained in:
parent
988c44d461
commit
5e3819c9b2
91 changed files with 3772 additions and 2282 deletions
1
.pre-commit-config.yaml
Symbolic link
1
.pre-commit-config.yaml
Symbolic link
|
@ -0,0 +1 @@
|
|||
/nix/store/sbc33iwjwgwj0cklac3qjffvi93i723k-pre-commit-config.json
|
93
default.nix
Normal file
93
default.nix
Normal 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}
|
||||
'';
|
||||
};
|
||||
};
|
||||
}
|
19
external/netbox/default.nix
vendored
19
external/netbox/default.nix
vendored
|
@ -1,4 +1,5 @@
|
|||
{ config, pkgs, ... }: {
|
||||
{ config, pkgs, ... }:
|
||||
{
|
||||
imports = [ ./secrets ];
|
||||
|
||||
services = {
|
||||
|
@ -8,8 +9,7 @@
|
|||
listenAddress = "127.0.0.1";
|
||||
settings = {
|
||||
ALLOWED_HOSTS = [ "netbox.dgnum.sinavir.fr" ];
|
||||
REMOTE_AUTH_BACKEND =
|
||||
"social_core.backends.open_id_connect.OpenIdConnectAuth";
|
||||
REMOTE_AUTH_BACKEND = "social_core.backends.open_id_connect.OpenIdConnectAuth";
|
||||
};
|
||||
|
||||
extraConfig = ''
|
||||
|
@ -27,12 +27,8 @@
|
|||
enableACME = true;
|
||||
forceSSL = true;
|
||||
|
||||
locations."/".proxyPass =
|
||||
"http://${config.services.netbox.listenAddress}:${
|
||||
builtins.toString config.services.netbox.port
|
||||
}";
|
||||
locations."/static/".alias =
|
||||
"${config.services.netbox.dataDir}/static/";
|
||||
locations."/".proxyPass = "http://${config.services.netbox.listenAddress}:${builtins.toString config.services.netbox.port}";
|
||||
locations."/static/".alias = "${config.services.netbox.dataDir}/static/";
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -50,5 +46,8 @@
|
|||
};
|
||||
|
||||
users.users.nginx.extraGroups = [ "netbox" ];
|
||||
networking.firewall.allowedTCPPorts = [ 443 80 ];
|
||||
networking.firewall.allowedTCPPorts = [
|
||||
443
|
||||
80
|
||||
];
|
||||
}
|
||||
|
|
15
external/netbox/secrets/secrets.nix
vendored
15
external/netbox/secrets/secrets.nix
vendored
|
@ -6,10 +6,15 @@ let
|
|||
|
||||
inherit ((import ../../../meta).members) groups;
|
||||
|
||||
publicKeys = lib.splitString "\n"
|
||||
(builtins.readFile (./maurice.keys)) # maurice servers' keys
|
||||
publicKeys =
|
||||
lib.splitString "\n" (builtins.readFile (./maurice.keys)) # maurice servers' keys
|
||||
++ nix-lib.getAllKeys (groups.netbox ++ groups.root);
|
||||
in {
|
||||
"netbox.age" = { inherit publicKeys; };
|
||||
"netbox_env.age" = { inherit publicKeys; };
|
||||
in
|
||||
{
|
||||
"netbox.age" = {
|
||||
inherit publicKeys;
|
||||
};
|
||||
"netbox_env.age" = {
|
||||
inherit publicKeys;
|
||||
};
|
||||
}
|
||||
|
|
58
hive.nix
58
hive.nix
|
@ -6,32 +6,34 @@ let
|
|||
|
||||
patch = import sources.nix-patches { patchFile = ./patches; };
|
||||
|
||||
mkNode = node:
|
||||
{ name, nodes, pkgs, ... }: {
|
||||
# Import the base configuration for each node
|
||||
imports = builtins.map (lib.mkRel ./machines/${node}) [
|
||||
"_configuration.nix"
|
||||
"_hardware-configuration.nix"
|
||||
];
|
||||
mkNode = node: _: {
|
||||
# Import the base configuration for each node
|
||||
imports = builtins.map (lib.mkRel ./machines/${node}) [
|
||||
"_configuration.nix"
|
||||
"_hardware-configuration.nix"
|
||||
];
|
||||
|
||||
# Include default secrets
|
||||
age-secrets.sources = [ ./machines/${node}/secrets ];
|
||||
# Include default secrets
|
||||
age-secrets.sources = [ ./machines/${node}/secrets ];
|
||||
|
||||
# Deployment config is specified in meta.nodes.${node}.deployment
|
||||
inherit (metadata.nodes.${node}) deployment;
|
||||
# Deployment config is specified in meta.nodes.${node}.deployment
|
||||
inherit (metadata.nodes.${node}) deployment;
|
||||
|
||||
# Set NIX_PATH to the patched version of nixpkgs
|
||||
nix.nixPath = [ "nixpkgs=${mkNixpkgs node}" ];
|
||||
nix.optimise.automatic = true;
|
||||
# Set NIX_PATH to the patched version of nixpkgs
|
||||
nix.nixPath = [ "nixpkgs=${mkNixpkgs node}" ];
|
||||
nix.optimise.automatic = true;
|
||||
|
||||
# Allow unfree packages
|
||||
nixpkgs.config.allowUnfree = true;
|
||||
# Allow unfree packages
|
||||
nixpkgs.config.allowUnfree = true;
|
||||
|
||||
# Use the stateVersion declared in the metadata
|
||||
system = { inherit (metadata.nodes.${node}) stateVersion; };
|
||||
# Use the stateVersion declared in the metadata
|
||||
system = {
|
||||
inherit (metadata.nodes.${node}) stateVersion;
|
||||
};
|
||||
};
|
||||
|
||||
mkNixpkgs = node:
|
||||
mkNixpkgs =
|
||||
node:
|
||||
patch.mkNixpkgsSrc rec {
|
||||
src = sources.${version};
|
||||
version = "nixos-${metadata.nodes.${node}.nixpkgs}";
|
||||
|
@ -42,9 +44,12 @@ let
|
|||
###
|
||||
# Function to create arguments based on the node
|
||||
#
|
||||
mkArgs = node:
|
||||
let lib' = (mkNixpkgs' node).lib;
|
||||
in {
|
||||
mkArgs =
|
||||
node:
|
||||
let
|
||||
lib' = (mkNixpkgs' node).lib;
|
||||
in
|
||||
{
|
||||
lib = import sources.nix-lib {
|
||||
lib = lib';
|
||||
keysRoot = ./keys;
|
||||
|
@ -52,8 +57,8 @@ let
|
|||
};
|
||||
|
||||
nodes = builtins.attrNames metadata.nodes;
|
||||
|
||||
in {
|
||||
in
|
||||
{
|
||||
meta = {
|
||||
nodeNixpkgs = lib.mapSingleFuse mkNixpkgs' nodes;
|
||||
|
||||
|
@ -65,8 +70,9 @@ in {
|
|||
nodeSpecialArgs = lib.mapSingleFuse mkArgs nodes;
|
||||
};
|
||||
|
||||
defaults = { pkgs, ... }: {
|
||||
defaults = _: {
|
||||
# Import the default modules
|
||||
imports = [ ./modules ];
|
||||
};
|
||||
} // (lib.mapSingleFuse mkNode nodes)
|
||||
}
|
||||
// (lib.mapSingleFuse mkNode nodes)
|
||||
|
|
|
@ -34,5 +34,6 @@ in
|
|||
};
|
||||
|
||||
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;
|
||||
}
|
||||
|
|
|
@ -2,4 +2,7 @@ let
|
|||
inherit (import ../npins) nixpkgs;
|
||||
in
|
||||
|
||||
(import nixpkgs { }).srcOnly { name = "nixpkgs-for-iso"; src = nixpkgs; }
|
||||
(import nixpkgs { }).srcOnly {
|
||||
name = "nixpkgs-for-iso";
|
||||
src = nixpkgs;
|
||||
}
|
||||
|
|
|
@ -3,20 +3,24 @@ _:
|
|||
let
|
||||
sources = import ../npins;
|
||||
|
||||
nix-lib = (import sources.nix-lib {
|
||||
inherit ((import sources.nixpkgs { })) lib;
|
||||
nix-lib =
|
||||
(import sources.nix-lib {
|
||||
inherit ((import sources.nixpkgs { })) lib;
|
||||
|
||||
keysRoot = ../keys;
|
||||
}).extra;
|
||||
|
||||
in nix-lib // (with nix-lib; {
|
||||
keysRoot = ../keys;
|
||||
}).extra;
|
||||
in
|
||||
nix-lib
|
||||
// (with nix-lib; {
|
||||
# Get publickeys associated to a node
|
||||
getNodeKeys = node:
|
||||
getNodeKeys =
|
||||
node:
|
||||
let
|
||||
meta = import ../meta;
|
||||
names =
|
||||
builtins.foldl' (names: group: names ++ meta.members.groups.${group})
|
||||
(meta.nodes.${node}.admins ++ [ "/machines/${node}" ])
|
||||
(meta.nodes.${node}.adminGroups ++ [ "root" ]);
|
||||
in getAllKeys names;
|
||||
(meta.nodes.${node}.admins ++ [ "/machines/${node}" ])
|
||||
(meta.nodes.${node}.adminGroups ++ [ "root" ]);
|
||||
in
|
||||
getAllKeys names;
|
||||
})
|
||||
|
|
|
@ -29,6 +29,5 @@
|
|||
fsType = "vfat";
|
||||
};
|
||||
|
||||
swapDevices =
|
||||
[{ device = "/dev/disk/by-uuid/30547280-00e9-4ee1-8a07-d116590d9fbf"; }];
|
||||
swapDevices = [ { device = "/dev/disk/by-uuid/30547280-00e9-4ee1-8a07-d116590d9fbf"; } ];
|
||||
}
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
{ config, ... }:
|
||||
|
||||
let host = "demarches.dgnum.eu";
|
||||
in {
|
||||
let
|
||||
host = "demarches.dgnum.eu";
|
||||
in
|
||||
{
|
||||
imports = [ ./module.nix ];
|
||||
|
||||
services.demarches-simplifiees = {
|
||||
|
@ -62,5 +64,7 @@ in {
|
|||
};
|
||||
};
|
||||
|
||||
age-secrets.matches."^ds_fr-.*$" = { owner = "ds-fr"; };
|
||||
age-secrets.matches."^ds_fr-.*$" = {
|
||||
owner = "ds-fr";
|
||||
};
|
||||
}
|
||||
|
|
|
@ -31,15 +31,26 @@
|
|||
# The fact that you are presently reading this means that you have had
|
||||
# knowledge of the CeCILL license and that you accept its terms.
|
||||
|
||||
{ config, lib, pkgs, ... }:
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
|
||||
let
|
||||
inherit (lib)
|
||||
mdDoc mkDefault mkEnableOption mkIf mkOption
|
||||
mdDoc
|
||||
mkDefault
|
||||
mkEnableOption
|
||||
mkIf
|
||||
mkOption
|
||||
|
||||
optional optionalString
|
||||
optional
|
||||
optionalString
|
||||
|
||||
types;
|
||||
types
|
||||
;
|
||||
|
||||
cfg = config.services.demarches-simplifiees;
|
||||
|
||||
|
@ -64,16 +75,14 @@ let
|
|||
|
||||
$SUDO ${cfg.package}/bin/$BIN "$@"
|
||||
'';
|
||||
|
||||
in {
|
||||
in
|
||||
{
|
||||
options.services.demarches-simplifiees = {
|
||||
enable = mkEnableOption "demarches-simplifiees.";
|
||||
|
||||
package = mkOption {
|
||||
type = types.package;
|
||||
default = pkgs.callPackage ./package {
|
||||
inherit (cfg) initialDeploymentDate dataDir logDir;
|
||||
};
|
||||
default = pkgs.callPackage ./package { inherit (cfg) initialDeploymentDate dataDir logDir; };
|
||||
};
|
||||
|
||||
user = mkOption {
|
||||
|
@ -127,15 +136,17 @@ in {
|
|||
description = "Demarches Simplifiees setup";
|
||||
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
path = [ pkgs.bash ds-fr ];
|
||||
path = [
|
||||
pkgs.bash
|
||||
ds-fr
|
||||
];
|
||||
after = [ "postgresql.service" ];
|
||||
|
||||
serviceConfig = {
|
||||
Type = "oneshot";
|
||||
User = cfg.user;
|
||||
Group = cfg.group;
|
||||
EnvironmentFile = [ env ]
|
||||
++ (optional (cfg.secretFile != null) cfg.secretFile);
|
||||
EnvironmentFile = [ env ] ++ (optional (cfg.secretFile != null) cfg.secretFile);
|
||||
StateDirectory = mkIf (cfg.dataDir == "/var/lib/ds-fr") "ds-fr";
|
||||
LogsDirectory = mkIf (cfg.logDir == "/var/log/ds-fr") "ds-fr";
|
||||
};
|
||||
|
@ -155,14 +166,19 @@ in {
|
|||
ds-fr-work = {
|
||||
description = "Demarches Simplifiees work service";
|
||||
|
||||
wantedBy = [ "multi-user.target" "ds-fr.service" ];
|
||||
after = [ "network.target" "ds-fr-setup.service" ];
|
||||
wantedBy = [
|
||||
"multi-user.target"
|
||||
"ds-fr.service"
|
||||
];
|
||||
after = [
|
||||
"network.target"
|
||||
"ds-fr-setup.service"
|
||||
];
|
||||
requires = [ "ds-fr-setup.service" ];
|
||||
|
||||
serviceConfig = {
|
||||
ExecStart = "${ds-fr}/bin/ds-fr rails jobs:work";
|
||||
EnvironmentFile = [ env ]
|
||||
++ (optional (cfg.secretFile != null) cfg.secretFile);
|
||||
EnvironmentFile = [ env ] ++ (optional (cfg.secretFile != null) cfg.secretFile);
|
||||
User = cfg.user;
|
||||
Group = cfg.group;
|
||||
StateDirectory = mkIf (cfg.dataDir == "/var/lib/ds-fr") "ds-fr";
|
||||
|
@ -174,15 +190,17 @@ in {
|
|||
description = "Demarches Simplifiees web service";
|
||||
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
after = [ "network.target" "ds-fr-setup.service" ];
|
||||
after = [
|
||||
"network.target"
|
||||
"ds-fr-setup.service"
|
||||
];
|
||||
requires = [ "ds-fr-setup.service" ];
|
||||
path = [ pkgs.imagemagick ];
|
||||
|
||||
serviceConfig = {
|
||||
ExecStart = "${ds-fr}/bin/ds-fr rails server";
|
||||
Environment = [ "RAILS_QUEUE_ADAPTER=delayed_job" ];
|
||||
EnvironmentFile = [ env ]
|
||||
++ (optional (cfg.secretFile != null) cfg.secretFile);
|
||||
EnvironmentFile = [ env ] ++ (optional (cfg.secretFile != null) cfg.secretFile);
|
||||
User = cfg.user;
|
||||
Group = cfg.group;
|
||||
StateDirectory = mkIf (cfg.dataDir == "/var/lib/ds-fr") "ds-fr";
|
||||
|
@ -192,171 +210,173 @@ in {
|
|||
};
|
||||
|
||||
services = {
|
||||
demarches-simplifiees.settings = (builtins.mapAttrs (_: mkDefault) {
|
||||
RAILS_ENV = "production";
|
||||
RAILS_ROOT = builtins.toString cfg.package;
|
||||
demarches-simplifiees.settings =
|
||||
(builtins.mapAttrs (_: mkDefault) {
|
||||
RAILS_ENV = "production";
|
||||
RAILS_ROOT = builtins.toString cfg.package;
|
||||
|
||||
# Application host name
|
||||
#
|
||||
# Examples:
|
||||
# * For local development: localhost:3000
|
||||
# * For preproduction: staging.ds.example.org
|
||||
# * For production: ds.example.org
|
||||
APP_HOST = "localhost:3000";
|
||||
# Application host name
|
||||
#
|
||||
# Examples:
|
||||
# * For local development: localhost:3000
|
||||
# * For preproduction: staging.ds.example.org
|
||||
# * For production: ds.example.org
|
||||
APP_HOST = "localhost:3000";
|
||||
|
||||
# Rails key for signing sensitive data
|
||||
# See https://guides.rubyonrails.org/security.html
|
||||
#
|
||||
# For production you MUST generate a new key, and keep it secret.
|
||||
# Secrets must be long and random. Use bin/rails secret to get new unique secrets.
|
||||
# Rails key for signing sensitive data
|
||||
# See https://guides.rubyonrails.org/security.html
|
||||
#
|
||||
# For production you MUST generate a new key, and keep it secret.
|
||||
# Secrets must be long and random. Use bin/rails secret to get new unique secrets.
|
||||
|
||||
# Secret key for One-Time-Password codes, used for 2-factors authentication
|
||||
# OTP_SECRET_KEY = "";
|
||||
# Secret key for One-Time-Password codes, used for 2-factors authentication
|
||||
# OTP_SECRET_KEY = "";
|
||||
|
||||
# Protect access to the instance with a static login/password (useful for staging environments)
|
||||
BASIC_AUTH_ENABLED = "disabled";
|
||||
BASIC_AUTH_USERNAME = "";
|
||||
BASIC_AUTH_PASSWORD = "";
|
||||
# Protect access to the instance with a static login/password (useful for staging environments)
|
||||
BASIC_AUTH_ENABLED = "disabled";
|
||||
BASIC_AUTH_USERNAME = "";
|
||||
BASIC_AUTH_PASSWORD = "";
|
||||
|
||||
# ActiveStorage service to use for attached files.
|
||||
# Possible values:
|
||||
# - "local": store files on the local filesystem
|
||||
# - "amazon": store files remotely on an S3 storage service
|
||||
# - "openstack": store files remotely on an OpenStack storage service
|
||||
#
|
||||
# (See config/storage.yml for the configuration of each service.)
|
||||
ACTIVE_STORAGE_SERVICE = "local";
|
||||
# ActiveStorage service to use for attached files.
|
||||
# Possible values:
|
||||
# - "local": store files on the local filesystem
|
||||
# - "amazon": store files remotely on an S3 storage service
|
||||
# - "openstack": store files remotely on an OpenStack storage service
|
||||
#
|
||||
# (See config/storage.yml for the configuration of each service.)
|
||||
ACTIVE_STORAGE_SERVICE = "local";
|
||||
|
||||
# Configuration for the OpenStack storage service (if enabled)
|
||||
FOG_OPENSTACK_API_KEY = "";
|
||||
FOG_OPENSTACK_USERNAME = "";
|
||||
FOG_OPENSTACK_URL = "";
|
||||
FOG_OPENSTACK_REGION = "";
|
||||
DS_PROXY_URL = "";
|
||||
# Configuration for the OpenStack storage service (if enabled)
|
||||
FOG_OPENSTACK_API_KEY = "";
|
||||
FOG_OPENSTACK_USERNAME = "";
|
||||
FOG_OPENSTACK_URL = "";
|
||||
FOG_OPENSTACK_REGION = "";
|
||||
DS_PROXY_URL = "";
|
||||
|
||||
# SAML
|
||||
SAML_IDP_ENABLED = "disabled";
|
||||
# SAML
|
||||
SAML_IDP_ENABLED = "disabled";
|
||||
|
||||
# External service: authentication through France Connect
|
||||
FC_PARTICULIER_ID = "";
|
||||
FC_PARTICULIER_SECRET = "";
|
||||
FC_PARTICULIER_BASE_URL = "";
|
||||
# External service: authentication through France Connect
|
||||
FC_PARTICULIER_ID = "";
|
||||
FC_PARTICULIER_SECRET = "";
|
||||
FC_PARTICULIER_BASE_URL = "";
|
||||
|
||||
# External service: authentication through Agent Connect
|
||||
AGENT_CONNECT_ID = "";
|
||||
AGENT_CONNECT_SECRET = "";
|
||||
AGENT_CONNECT_BASE_URL = "";
|
||||
AGENT_CONNECT_JWKS = "";
|
||||
AGENT_CONNECT_REDIRECT = "";
|
||||
# External service: authentication through Agent Connect
|
||||
AGENT_CONNECT_ID = "";
|
||||
AGENT_CONNECT_SECRET = "";
|
||||
AGENT_CONNECT_BASE_URL = "";
|
||||
AGENT_CONNECT_JWKS = "";
|
||||
AGENT_CONNECT_REDIRECT = "";
|
||||
|
||||
# External service: integration with HelpScout (optional)
|
||||
HELPSCOUT_MAILBOX_ID = "";
|
||||
HELPSCOUT_CLIENT_ID = "";
|
||||
HELPSCOUT_CLIENT_SECRET = "";
|
||||
HELPSCOUT_WEBHOOK_SECRET = "";
|
||||
# External service: integration with HelpScout (optional)
|
||||
HELPSCOUT_MAILBOX_ID = "";
|
||||
HELPSCOUT_CLIENT_ID = "";
|
||||
HELPSCOUT_CLIENT_SECRET = "";
|
||||
HELPSCOUT_WEBHOOK_SECRET = "";
|
||||
|
||||
# External service: external supervision
|
||||
SENTRY_ENABLED = "disabled";
|
||||
SENTRY_CURRENT_ENV = "development";
|
||||
SENTRY_DSN_RAILS = "";
|
||||
SENTRY_DSN_JS = "";
|
||||
# External service: external supervision
|
||||
SENTRY_ENABLED = "disabled";
|
||||
SENTRY_CURRENT_ENV = "development";
|
||||
SENTRY_DSN_RAILS = "";
|
||||
SENTRY_DSN_JS = "";
|
||||
|
||||
# External service: Matomo web analytics
|
||||
MATOMO_ENABLED = "disabled";
|
||||
MATOMO_COOKIE_DOMAIN = "*.www.demarches-simplifiees.fr";
|
||||
MATOMO_DOMAIN = "*.www.demarches-simplifiees.fr";
|
||||
MATOMO_ID = "";
|
||||
MATOMO_HOST = "matomo.example.org";
|
||||
# External service: Matomo web analytics
|
||||
MATOMO_ENABLED = "disabled";
|
||||
MATOMO_COOKIE_DOMAIN = "*.www.demarches-simplifiees.fr";
|
||||
MATOMO_DOMAIN = "*.www.demarches-simplifiees.fr";
|
||||
MATOMO_ID = "";
|
||||
MATOMO_HOST = "matomo.example.org";
|
||||
|
||||
# Default SMTP Provider: Mailjet
|
||||
MAILJET_API_KEY = "";
|
||||
MAILJET_SECRET_KEY = "";
|
||||
# Default SMTP Provider: Mailjet
|
||||
MAILJET_API_KEY = "";
|
||||
MAILJET_SECRET_KEY = "";
|
||||
|
||||
# Alternate SMTP Provider: SendInBlue/DoList
|
||||
SENDINBLUE_CLIENT_KEY = "";
|
||||
SENDINBLUE_SMTP_KEY = "";
|
||||
SENDINBLUE_USER_NAME = "";
|
||||
# SENDINBLUE_LOGIN_URL="https://app.sendinblue.com/account/saml/login/truc"
|
||||
# Alternate SMTP Provider: SendInBlue/DoList
|
||||
SENDINBLUE_CLIENT_KEY = "";
|
||||
SENDINBLUE_SMTP_KEY = "";
|
||||
SENDINBLUE_USER_NAME = "";
|
||||
# SENDINBLUE_LOGIN_URL="https://app.sendinblue.com/account/saml/login/truc"
|
||||
|
||||
# Alternate SMTP Provider: Mailtrap (mail catcher for staging environments)
|
||||
# When enabled, all emails will be sent using this provider
|
||||
MAILTRAP_ENABLED = "disabled";
|
||||
MAILTRAP_USERNAME = "";
|
||||
MAILTRAP_PASSWORD = "";
|
||||
# Alternate SMTP Provider: Mailtrap (mail catcher for staging environments)
|
||||
# When enabled, all emails will be sent using this provider
|
||||
MAILTRAP_ENABLED = "disabled";
|
||||
MAILTRAP_USERNAME = "";
|
||||
MAILTRAP_PASSWORD = "";
|
||||
|
||||
# Alternative SMTP Provider: Mailcatcher (Catches mail and serves it through a dream.)
|
||||
# When enabled, all emails will be sent using this provider
|
||||
MAILCATCHER_ENABLED = "disabled";
|
||||
MAILCATCHER_HOST = "";
|
||||
MAILCATCHER_PORT = "";
|
||||
# Alternative SMTP Provider: Mailcatcher (Catches mail and serves it through a dream.)
|
||||
# When enabled, all emails will be sent using this provider
|
||||
MAILCATCHER_ENABLED = "disabled";
|
||||
MAILCATCHER_HOST = "";
|
||||
MAILCATCHER_PORT = "";
|
||||
|
||||
# External service: live chat for admins (specific to démarches-simplifiées.fr)
|
||||
CRISP_ENABLED = "disabled";
|
||||
CRISP_CLIENT_KEY = "";
|
||||
# External service: live chat for admins (specific to démarches-simplifiées.fr)
|
||||
CRISP_ENABLED = "disabled";
|
||||
CRISP_CLIENT_KEY = "";
|
||||
|
||||
# API Entreprise credentials
|
||||
# https://api.gouv.fr/api/api-entreprise.html
|
||||
API_ENTREPRISE_KEY = "";
|
||||
# API Entreprise credentials
|
||||
# https://api.gouv.fr/api/api-entreprise.html
|
||||
API_ENTREPRISE_KEY = "";
|
||||
|
||||
# External service: CRM for following admin accounts pipeline (specific to démarches-simplifiées.fr)
|
||||
PIPEDRIVE_KEY = "";
|
||||
# External service: CRM for following admin accounts pipeline (specific to démarches-simplifiées.fr)
|
||||
PIPEDRIVE_KEY = "";
|
||||
|
||||
# Networks bypassing the email login token that verifies new devices, and rack-attack throttling
|
||||
TRUSTED_NETWORKS = "";
|
||||
# Networks bypassing the email login token that verifies new devices, and rack-attack throttling
|
||||
TRUSTED_NETWORKS = "";
|
||||
|
||||
# External service: mesuring performance of the Rails app (specific to démarches-simplifiées.fr)
|
||||
SKYLIGHT_AUTHENTICATION_KEY = "";
|
||||
# "sXaot-fKhBlkI8qaSirQyuZbrpv5sVFoOturQ0pFEh0";
|
||||
# External service: mesuring performance of the Rails app (specific to démarches-simplifiées.fr)
|
||||
SKYLIGHT_AUTHENTICATION_KEY = "";
|
||||
# "sXaot-fKhBlkI8qaSirQyuZbrpv5sVFoOturQ0pFEh0";
|
||||
|
||||
# Enable or disable Lograge logs
|
||||
LOGRAGE_ENABLED = "disabled";
|
||||
# Enable or disable Lograge logs
|
||||
LOGRAGE_ENABLED = "disabled";
|
||||
|
||||
# Logs source for Lograge
|
||||
#
|
||||
# Examples:
|
||||
# * For local development: tps_local
|
||||
# * For preproduction: tps_staging
|
||||
# * For production: tps_prod
|
||||
LOGRAGE_SOURCE = "tps_prod";
|
||||
# Logs source for Lograge
|
||||
#
|
||||
# Examples:
|
||||
# * For local development: tps_local
|
||||
# * For preproduction: tps_staging
|
||||
# * For production: tps_prod
|
||||
LOGRAGE_SOURCE = "tps_prod";
|
||||
|
||||
# External service: timestamping a daily archive of dossiers status changes
|
||||
UNIVERSIGN_API_URL = "https://ws.universign.eu/tsa/post/";
|
||||
UNIVERSIGN_USERPWD = "";
|
||||
# External service: timestamping a daily archive of dossiers status changes
|
||||
UNIVERSIGN_API_URL = "https://ws.universign.eu/tsa/post/";
|
||||
UNIVERSIGN_USERPWD = "";
|
||||
|
||||
# External service: API Geo / Adresse
|
||||
API_ADRESSE_URL = "https://api-adresse.data.gouv.fr";
|
||||
API_GEO_URL = "https://geo.api.gouv.fr";
|
||||
# External service: API Geo / Adresse
|
||||
API_ADRESSE_URL = "https://api-adresse.data.gouv.fr";
|
||||
API_GEO_URL = "https://geo.api.gouv.fr";
|
||||
|
||||
# External service: API Education
|
||||
API_EDUCATION_URL = "https://data.education.gouv.fr/api/records/1.0";
|
||||
# External service: API Education
|
||||
API_EDUCATION_URL = "https://data.education.gouv.fr/api/records/1.0";
|
||||
|
||||
# Encryption key for sensitive columns in the database
|
||||
ENCRYPTION_SERVICE_SALT = "";
|
||||
# Encryption key for sensitive columns in the database
|
||||
ENCRYPTION_SERVICE_SALT = "";
|
||||
|
||||
# ActiveRecord encryption keys. Generate them with bin/rails db:encryption:init (you can omit deterministic_key)
|
||||
AR_ENCRYPTION_PRIMARY_KEY = "";
|
||||
AR_ENCRYPTION_KEY_DERIVATION_SALT = "";
|
||||
# ActiveRecord encryption keys. Generate them with bin/rails db:encryption:init (you can omit deterministic_key)
|
||||
AR_ENCRYPTION_PRIMARY_KEY = "";
|
||||
AR_ENCRYPTION_KEY_DERIVATION_SALT = "";
|
||||
|
||||
# Salt for invisible_captcha session data.
|
||||
# Must be the same value for all app instances behind a load-balancer.
|
||||
INVISIBLE_CAPTCHA_SECRET = "kikooloool";
|
||||
# Salt for invisible_captcha session data.
|
||||
# Must be the same value for all app instances behind a load-balancer.
|
||||
INVISIBLE_CAPTCHA_SECRET = "kikooloool";
|
||||
|
||||
# Clamav antivirus usage
|
||||
CLAMAV_ENABLED = "disabled";
|
||||
# Clamav antivirus usage
|
||||
CLAMAV_ENABLED = "disabled";
|
||||
|
||||
# Siret number used for API Entreprise, by default we use SIRET from dinum
|
||||
API_ENTREPRISE_DEFAULT_SIRET = "put_your_own_siret";
|
||||
}) // {
|
||||
# Database credentials
|
||||
DB_DATABASE = "ds-fr";
|
||||
DB_USERNAME = cfg.user;
|
||||
DB_PASSWORD = "";
|
||||
DB_HOST = "/run/postgresql";
|
||||
DB_POOL = "";
|
||||
# Siret number used for API Entreprise, by default we use SIRET from dinum
|
||||
API_ENTREPRISE_DEFAULT_SIRET = "put_your_own_siret";
|
||||
})
|
||||
// {
|
||||
# Database credentials
|
||||
DB_DATABASE = "ds-fr";
|
||||
DB_USERNAME = cfg.user;
|
||||
DB_PASSWORD = "";
|
||||
DB_HOST = "/run/postgresql";
|
||||
DB_POOL = "";
|
||||
|
||||
# Log on stdout
|
||||
RAILS_LOG_TO_STDOUT = true;
|
||||
};
|
||||
# Log on stdout
|
||||
RAILS_LOG_TO_STDOUT = true;
|
||||
};
|
||||
|
||||
postgresql = {
|
||||
enable = true;
|
||||
|
@ -368,8 +388,7 @@ in {
|
|||
ensureDBOwnership = true;
|
||||
};
|
||||
|
||||
extraPlugins = with config.services.postgresql.package.pkgs;
|
||||
[ postgis ];
|
||||
extraPlugins = with config.services.postgresql.package.pkgs; [ postgis ];
|
||||
};
|
||||
|
||||
nginx = {
|
||||
|
@ -381,7 +400,9 @@ in {
|
|||
root = "${cfg.package}/public/";
|
||||
|
||||
locations."/".tryFiles = "$uri @proxy";
|
||||
locations."@proxy" = { proxyPass = "http://127.0.0.1:3000"; };
|
||||
locations."@proxy" = {
|
||||
proxyPass = "http://127.0.0.1:3000";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
|
|
@ -1,6 +1,18 @@
|
|||
{ lib, stdenv, fetchFromGitHub, git, fetchYarnDeps, yarn, fixup_yarn_lock, imagemagick
|
||||
, nodejs, ruby_3_2, bundlerEnv, logDir ? "/var/log/ds-fr"
|
||||
, dataDir ? "/var/lib/ds-fr", initialDeploymentDate ? "17941030" }:
|
||||
{
|
||||
lib,
|
||||
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
|
||||
pname = "ds-fr";
|
||||
|
@ -43,7 +55,12 @@ let
|
|||
};
|
||||
|
||||
buildInputs = [ rubyEnv ];
|
||||
nativeBuildInputs = [ fixup_yarn_lock nodejs yarn rubyEnv.wrappedRuby ];
|
||||
nativeBuildInputs = [
|
||||
fixup_yarn_lock
|
||||
nodejs
|
||||
yarn
|
||||
rubyEnv.wrappedRuby
|
||||
];
|
||||
|
||||
RAILS_ENV = "production";
|
||||
NODE_ENV = "dev";
|
||||
|
@ -53,8 +70,9 @@ let
|
|||
./patches/build.patch
|
||||
];
|
||||
|
||||
postPatch = builtins.concatStringsSep "\n"
|
||||
(builtins.map (p: "${git}/bin/git apply -p1 < ${p}") dgn-patches);
|
||||
postPatch = builtins.concatStringsSep "\n" (
|
||||
builtins.map (p: "${git}/bin/git apply -p1 < ${p}") dgn-patches
|
||||
);
|
||||
|
||||
OTP_SECRET_KEY = "precompile_placeholder";
|
||||
SECRET_KEY_BASE = "precompile_placeholder";
|
||||
|
@ -82,8 +100,8 @@ let
|
|||
};
|
||||
|
||||
dgn-patches = import ./dgnum.nix { };
|
||||
|
||||
in stdenv.mkDerivation {
|
||||
in
|
||||
stdenv.mkDerivation {
|
||||
name = "demarches-simplifiees.fr-${version}";
|
||||
|
||||
inherit src;
|
||||
|
@ -98,8 +116,9 @@ in stdenv.mkDerivation {
|
|||
./patches/secrets-fc.patch
|
||||
];
|
||||
|
||||
postPatch = builtins.concatStringsSep "\n"
|
||||
(builtins.map (p: "${git}/bin/git apply -p1 < ${p}") dgn-patches);
|
||||
postPatch = builtins.concatStringsSep "\n" (
|
||||
builtins.map (p: "${git}/bin/git apply -p1 < ${p}") dgn-patches
|
||||
);
|
||||
|
||||
buildPhase = ''
|
||||
rm -rf public
|
||||
|
@ -132,8 +151,7 @@ in stdenv.mkDerivation {
|
|||
|
||||
meta = with lib; {
|
||||
description = "Dématérialiser et simplifier les démarches administratives";
|
||||
homepage =
|
||||
"https://github.com/demarches-simplifiees/demarches-simplifiees.fr";
|
||||
homepage = "https://github.com/demarches-simplifiees/demarches-simplifiees.fr";
|
||||
license = licenses.agpl3Only;
|
||||
maintainers = with maintainers; [ thubrecht ];
|
||||
};
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
_:
|
||||
|
||||
builtins.map (id:
|
||||
builtins.fetchurl
|
||||
"https://git.dgnum.eu/DGNum/demarches-normaliennes/commit/${id}.patch")
|
||||
[ "0b9b32483a700ad3060b3d4ef723d5f40c290c62" ]
|
||||
builtins.map
|
||||
(id: builtins.fetchurl "https://git.dgnum.eu/DGNum/demarches-normaliennes/commit/${id}.patch")
|
||||
[ "0b9b32483a700ad3060b3d4ef723d5f40c290c62" ]
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
version = "2024-01-31-02";
|
||||
src-hash = "sha256-4ATsSXbjkIMGn5yuyYiI+N+C2R/MSzecMLs5hWCCAM4=";
|
||||
deps-hash = "sha256-UR5K6DQMvmpWWTH8O9/zJ3Nd+Kkl7xofktFdmBB9z6M=";
|
||||
version = "2024-01-31-02";
|
||||
src-hash = "sha256-4ATsSXbjkIMGn5yuyYiI+N+C2R/MSzecMLs5hWCCAM4=";
|
||||
deps-hash = "sha256-UR5K6DQMvmpWWTH8O9/zJ3Nd+Kkl7xofktFdmBB9z6M=";
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -3,7 +3,8 @@
|
|||
let
|
||||
host = "pads.dgnum.eu";
|
||||
port = 3007;
|
||||
in {
|
||||
in
|
||||
{
|
||||
services = {
|
||||
hedgedoc = {
|
||||
enable = true;
|
||||
|
@ -43,13 +44,17 @@ in {
|
|||
|
||||
ensureDatabases = [ "hedgedoc" ];
|
||||
|
||||
ensureUsers = [{
|
||||
name = "hedgedoc";
|
||||
ensureDBOwnership = true;
|
||||
}];
|
||||
ensureUsers = [
|
||||
{
|
||||
name = "hedgedoc";
|
||||
ensureDBOwnership = true;
|
||||
}
|
||||
];
|
||||
};
|
||||
};
|
||||
|
||||
systemd.services.hedgedoc.serviceConfig.StateDirectory =
|
||||
lib.mkForce [ "hedgedoc" "hedgedoc/uploads" ];
|
||||
systemd.services.hedgedoc.serviceConfig.StateDirectory = lib.mkForce [
|
||||
"hedgedoc"
|
||||
"hedgedoc/uploads"
|
||||
];
|
||||
}
|
||||
|
|
|
@ -40,22 +40,23 @@
|
|||
};
|
||||
|
||||
authTokenFile = config.age.secrets."radius-auth_token_file".path;
|
||||
privateKeyPasswordFile =
|
||||
config.age.secrets."radius-private_key_password_file".path;
|
||||
privateKeyPasswordFile = config.age.secrets."radius-private_key_password_file".path;
|
||||
|
||||
certs = builtins.listToAttrs (builtins.map (name:
|
||||
lib.nameValuePair name
|
||||
config.age.secrets."radius-${name}_pem_file".path) [
|
||||
certs = builtins.listToAttrs (
|
||||
builtins.map (name: lib.nameValuePair name config.age.secrets."radius-${name}_pem_file".path) [
|
||||
"ca"
|
||||
"cert"
|
||||
"dh"
|
||||
"key"
|
||||
]);
|
||||
]
|
||||
);
|
||||
|
||||
radiusClients = { };
|
||||
};
|
||||
|
||||
age-secrets.matches."^radius-.*$" = { owner = "radius"; };
|
||||
age-secrets.matches."^radius-.*$" = {
|
||||
owner = "radius";
|
||||
};
|
||||
|
||||
networking.firewall.allowedTCPPorts = [ 1812 ];
|
||||
networking.firewall.allowedUDPPorts = [ 1812 ];
|
||||
|
|
|
@ -1,17 +1,27 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
|
||||
let
|
||||
inherit (lib) mkEnableOption mkIf mkOption types;
|
||||
inherit (lib)
|
||||
mkEnableOption
|
||||
mkIf
|
||||
mkOption
|
||||
types
|
||||
;
|
||||
|
||||
settingsFormat = pkgs.formats.toml { };
|
||||
|
||||
py-pkgs = import ./packages/python { inherit pkgs; };
|
||||
pykanidm =
|
||||
pkgs.callPackage ./packages/pykanidm.nix { inherit (py-pkgs) pydantic; };
|
||||
pykanidm = pkgs.callPackage ./packages/pykanidm.nix { inherit (py-pkgs) pydantic; };
|
||||
rlm_python = pkgs.callPackage ./packages/rlm_python.nix { inherit pykanidm; };
|
||||
|
||||
cfg = config.services.k-radius;
|
||||
in {
|
||||
in
|
||||
{
|
||||
options.services.k-radius = {
|
||||
enable = mkEnableOption "a freeradius service linked to kanidm.";
|
||||
|
||||
|
@ -19,17 +29,17 @@ in {
|
|||
|
||||
freeradius = mkOption {
|
||||
type = types.package;
|
||||
default = pkgs.freeradius.overrideAttrs (old: {
|
||||
buildInputs = (old.buildInputs or [ ])
|
||||
++ [ (pkgs.python3.withPackages (ps: [ ps.kanidm ])) ];
|
||||
});
|
||||
default = pkgs.freeradius.overrideAttrs (
|
||||
old: {
|
||||
buildInputs = (old.buildInputs or [ ]) ++ [ (pkgs.python3.withPackages (ps: [ ps.kanidm ])) ];
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
configDir = mkOption {
|
||||
type = types.path;
|
||||
default = "/var/lib/radius/raddb";
|
||||
description =
|
||||
"The path of the freeradius server configuration directory.";
|
||||
description = "The path of the freeradius server configuration directory.";
|
||||
};
|
||||
|
||||
authTokenFile = mkOption {
|
||||
|
@ -38,12 +48,14 @@ in {
|
|||
};
|
||||
|
||||
radiusClients = mkOption {
|
||||
type = types.attrsOf (types.submodule {
|
||||
options = {
|
||||
secret = mkOption { type = types.path; };
|
||||
ipaddr = mkOption { type = types.str; };
|
||||
};
|
||||
});
|
||||
type = types.attrsOf (
|
||||
types.submodule {
|
||||
options = {
|
||||
secret = mkOption { type = types.path; };
|
||||
ipaddr = mkOption { type = types.str; };
|
||||
};
|
||||
}
|
||||
);
|
||||
default = { };
|
||||
description = "A mapping of clients and their authentication tokens.";
|
||||
};
|
||||
|
@ -55,8 +67,7 @@ in {
|
|||
};
|
||||
dh = mkOption {
|
||||
type = types.str;
|
||||
description =
|
||||
"The output of `openssl dhparam -in ca.pem -out dh.pem 2048`.";
|
||||
description = "The output of `openssl dhparam -in ca.pem -out dh.pem 2048`.";
|
||||
};
|
||||
cert = mkOption {
|
||||
type = types.str;
|
||||
|
@ -113,26 +124,32 @@ in {
|
|||
|
||||
# write the clients configuration
|
||||
rm ${cfg.configDir}/clients.conf && touch ${cfg.configDir}/clients.conf
|
||||
${builtins.concatStringsSep "\n" (builtins.attrValues (builtins.mapAttrs
|
||||
(name:
|
||||
{ secret, ipaddr }: ''
|
||||
cat <<EOF >> ${cfg.configDir}/client.conf
|
||||
client ${name} {
|
||||
ipaddr = ${ipaddr}
|
||||
secret = $(cat "${secret}")
|
||||
proto = *
|
||||
}
|
||||
EOF
|
||||
'') cfg.radiusClients))}
|
||||
${builtins.concatStringsSep "\n" (
|
||||
builtins.attrValues (
|
||||
builtins.mapAttrs
|
||||
(
|
||||
name:
|
||||
{ secret, ipaddr }:
|
||||
''
|
||||
cat <<EOF >> ${cfg.configDir}/client.conf
|
||||
client ${name} {
|
||||
ipaddr = ${ipaddr}
|
||||
secret = $(cat "${secret}")
|
||||
proto = *
|
||||
}
|
||||
EOF
|
||||
''
|
||||
)
|
||||
cfg.radiusClients
|
||||
)
|
||||
)}
|
||||
|
||||
# Copy the kanidm configuration
|
||||
cat <<EOF > /var/lib/radius/kanidm.toml
|
||||
auth_token = "$(cat "${cfg.authTokenFile}")"
|
||||
EOF
|
||||
|
||||
cat ${
|
||||
settingsFormat.generate "kanidm.toml" cfg.settings
|
||||
} >> /var/lib/radius/kanidm.toml
|
||||
cat ${settingsFormat.generate "kanidm.toml" cfg.settings} >> /var/lib/radius/kanidm.toml
|
||||
chmod u+w /var/lib/radius/kanidm.toml
|
||||
|
||||
# Copy the certificates to the correct directory
|
||||
|
@ -154,11 +171,13 @@ in {
|
|||
# ${pkgs.freeradius}/bin/radiusd -C -d ${cfg.configDir} -l stdout
|
||||
'';
|
||||
|
||||
path = [ pkgs.openssl pkgs.gnused ];
|
||||
path = [
|
||||
pkgs.openssl
|
||||
pkgs.gnused
|
||||
];
|
||||
|
||||
serviceConfig = {
|
||||
ExecStart =
|
||||
"${cfg.freeradius}/bin/radiusd -f -d ${cfg.configDir} -l stdout";
|
||||
ExecStart = "${cfg.freeradius}/bin/radiusd -f -d ${cfg.configDir} -l stdout";
|
||||
ExecReload = [
|
||||
"${cfg.freeradius}/bin/radiusd -C -d ${cfg.configDir} -l stdout"
|
||||
"${pkgs.coreutils}/bin/kill -HUP $MAINPID"
|
||||
|
|
|
@ -1,25 +1,38 @@
|
|||
{ lib, fetchFromGitHub, python3, pydantic }:
|
||||
{
|
||||
lib,
|
||||
fetchFromGitHub,
|
||||
python3,
|
||||
pydantic,
|
||||
}:
|
||||
|
||||
let
|
||||
pname = "kanidm";
|
||||
version = "0.0.3";
|
||||
in python3.pkgs.buildPythonPackage {
|
||||
in
|
||||
python3.pkgs.buildPythonPackage {
|
||||
inherit pname version;
|
||||
format = "pyproject";
|
||||
|
||||
disabled = python3.pythonOlder "3.8";
|
||||
|
||||
src = (fetchFromGitHub {
|
||||
owner = pname;
|
||||
repo = pname;
|
||||
# Latest 1.1.0-rc.15 tip
|
||||
rev = "a5ca8018e3a636dbb0a79b3fd869db059d92979d";
|
||||
hash = "sha256-PFGoeGn7a/lVR6rOmOKA3ydAoo3/+9RlkwBAKS22Psg=";
|
||||
}) + "/pykanidm";
|
||||
src =
|
||||
(fetchFromGitHub {
|
||||
owner = pname;
|
||||
repo = pname;
|
||||
# Latest 1.1.0-rc.15 tip
|
||||
rev = "a5ca8018e3a636dbb0a79b3fd869db059d92979d";
|
||||
hash = "sha256-PFGoeGn7a/lVR6rOmOKA3ydAoo3/+9RlkwBAKS22Psg=";
|
||||
})
|
||||
+ "/pykanidm";
|
||||
|
||||
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;
|
||||
|
||||
|
@ -29,6 +42,9 @@ in python3.pkgs.buildPythonPackage {
|
|||
description = "Kanidm client library";
|
||||
homepage = "https://github.com/kanidm/kanidm/tree/master/pykanidm";
|
||||
license = licenses.mpl20;
|
||||
maintainers = with maintainers; [ arianvp hexa ];
|
||||
maintainers = with maintainers; [
|
||||
arianvp
|
||||
hexa
|
||||
];
|
||||
};
|
||||
}
|
||||
|
|
|
@ -5,8 +5,16 @@ let
|
|||
|
||||
callPackage = lib.callPackageWith (pkgs // pkgs.python3.pkgs // self);
|
||||
|
||||
self = builtins.listToAttrs (builtins.map (name: {
|
||||
inherit name;
|
||||
value = callPackage (./. + "/${name}.nix") { };
|
||||
}) [ "pydantic" "pydantic-core" ]);
|
||||
in self
|
||||
self = builtins.listToAttrs (
|
||||
builtins.map
|
||||
(name: {
|
||||
inherit name;
|
||||
value = callPackage (./. + "/${name}.nix") { };
|
||||
})
|
||||
[
|
||||
"pydantic"
|
||||
"pydantic-core"
|
||||
]
|
||||
);
|
||||
in
|
||||
self
|
||||
|
|
|
@ -1,17 +1,18 @@
|
|||
{ stdenv
|
||||
, lib
|
||||
, buildPythonPackage
|
||||
, fetchFromGitHub
|
||||
, cargo
|
||||
, rustPlatform
|
||||
, rustc
|
||||
, libiconv
|
||||
, typing-extensions
|
||||
, pytestCheckHook
|
||||
, hypothesis
|
||||
, pytest-timeout
|
||||
, pytest-mock
|
||||
, dirty-equals
|
||||
{
|
||||
stdenv,
|
||||
lib,
|
||||
buildPythonPackage,
|
||||
fetchFromGitHub,
|
||||
cargo,
|
||||
rustPlatform,
|
||||
rustc,
|
||||
libiconv,
|
||||
typing-extensions,
|
||||
pytestCheckHook,
|
||||
hypothesis,
|
||||
pytest-timeout,
|
||||
pytest-mock,
|
||||
dirty-equals,
|
||||
}:
|
||||
|
||||
let
|
||||
|
@ -27,9 +28,7 @@ let
|
|||
hash = "sha256-UguZpA3KEutOgIavjx8Ie//0qJq+4FTZNQTwb/ZIgb8=";
|
||||
};
|
||||
|
||||
patches = [
|
||||
./01-remove-benchmark-flags.patch
|
||||
];
|
||||
patches = [ ./01-remove-benchmark-flags.patch ];
|
||||
|
||||
cargoDeps = rustPlatform.fetchCargoTarball {
|
||||
inherit src;
|
||||
|
@ -45,13 +44,9 @@ let
|
|||
typing-extensions
|
||||
];
|
||||
|
||||
buildInputs = lib.optionals stdenv.isDarwin [
|
||||
libiconv
|
||||
];
|
||||
buildInputs = lib.optionals stdenv.isDarwin [ libiconv ];
|
||||
|
||||
propagatedBuildInputs = [
|
||||
typing-extensions
|
||||
];
|
||||
propagatedBuildInputs = [ typing-extensions ];
|
||||
|
||||
pythonImportsCheck = [ "pydantic_core" ];
|
||||
|
||||
|
@ -85,4 +80,5 @@ let
|
|||
maintainers = with maintainers; [ blaggacao ];
|
||||
};
|
||||
};
|
||||
in pydantic-core
|
||||
in
|
||||
pydantic-core
|
||||
|
|
|
@ -1,27 +1,28 @@
|
|||
{ lib
|
||||
, buildPythonPackage
|
||||
, fetchFromGitHub
|
||||
, pythonOlder
|
||||
{
|
||||
lib,
|
||||
buildPythonPackage,
|
||||
fetchFromGitHub,
|
||||
pythonOlder,
|
||||
|
||||
# build-system
|
||||
, hatchling
|
||||
, hatch-fancy-pypi-readme
|
||||
# build-system
|
||||
hatchling,
|
||||
hatch-fancy-pypi-readme,
|
||||
|
||||
# native dependencies
|
||||
, libxcrypt
|
||||
# native dependencies
|
||||
libxcrypt,
|
||||
|
||||
# dependencies
|
||||
, annotated-types
|
||||
, pydantic-core
|
||||
, typing-extensions
|
||||
# dependencies
|
||||
annotated-types,
|
||||
pydantic-core,
|
||||
typing-extensions,
|
||||
|
||||
# tests
|
||||
, cloudpickle
|
||||
, email-validator
|
||||
, dirty-equals
|
||||
, faker
|
||||
, pytestCheckHook
|
||||
, pytest-mock
|
||||
# tests
|
||||
cloudpickle,
|
||||
email-validator,
|
||||
dirty-equals,
|
||||
faker,
|
||||
pytestCheckHook,
|
||||
pytest-mock,
|
||||
}:
|
||||
|
||||
buildPythonPackage rec {
|
||||
|
@ -38,9 +39,7 @@ buildPythonPackage rec {
|
|||
hash = "sha256-D0gYcyrKVVDhBgV9sCVTkGq/kFmIoT9l0i5bRM1qxzM=";
|
||||
};
|
||||
|
||||
buildInputs = lib.optionals (pythonOlder "3.9") [
|
||||
libxcrypt
|
||||
];
|
||||
buildInputs = lib.optionals (pythonOlder "3.9") [ libxcrypt ];
|
||||
|
||||
nativeBuildInputs = [
|
||||
hatch-fancy-pypi-readme
|
||||
|
@ -54,9 +53,7 @@ buildPythonPackage rec {
|
|||
];
|
||||
|
||||
passthru.optional-dependencies = {
|
||||
email = [
|
||||
email-validator
|
||||
];
|
||||
email = [ email-validator ];
|
||||
};
|
||||
|
||||
nativeCheckInputs = [
|
||||
|
@ -93,4 +90,3 @@ buildPythonPackage rec {
|
|||
maintainers = with maintainers; [ wd15 ];
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -1,8 +1,14 @@
|
|||
{ stdenv, fetchFromGitHub, python3, pykanidm }:
|
||||
{
|
||||
stdenv,
|
||||
fetchFromGitHub,
|
||||
python3,
|
||||
pykanidm,
|
||||
}:
|
||||
|
||||
let pythonPath = with python3.pkgs; makePythonPath [ pykanidm ];
|
||||
|
||||
in stdenv.mkDerivation rec {
|
||||
let
|
||||
pythonPath = with python3.pkgs; makePythonPath [ pykanidm ];
|
||||
in
|
||||
stdenv.mkDerivation rec {
|
||||
pname = "rlm_python";
|
||||
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/
|
||||
'';
|
||||
|
||||
phases = [ "unpackPhase" "patchPhase" "installPhase" ];
|
||||
phases = [
|
||||
"unpackPhase"
|
||||
"patchPhase"
|
||||
"installPhase"
|
||||
];
|
||||
|
||||
passthru = { inherit pythonPath; };
|
||||
passthru = {
|
||||
inherit pythonPath;
|
||||
};
|
||||
|
||||
preferLocalBuild = true;
|
||||
}
|
||||
|
|
|
@ -5,8 +5,16 @@ let
|
|||
|
||||
cert = config.security.acme.certs.${domain};
|
||||
|
||||
allowedSubDomains = [ "cloud" "git" "videos" "social" "demarches" "netbird" ];
|
||||
in {
|
||||
allowedSubDomains = [
|
||||
"cloud"
|
||||
"git"
|
||||
"videos"
|
||||
"social"
|
||||
"demarches"
|
||||
"netbird"
|
||||
];
|
||||
in
|
||||
{
|
||||
services.kanidm = {
|
||||
enableServer = true;
|
||||
|
||||
|
|
|
@ -7,4 +7,3 @@ lib.setDefault { inherit publicKeys; } [
|
|||
"kanidm-password_admin"
|
||||
"kanidm-password_idm_admin"
|
||||
]
|
||||
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
{ config, ... }:
|
||||
|
||||
let host = "social.dgnum.eu";
|
||||
in {
|
||||
let
|
||||
host = "social.dgnum.eu";
|
||||
in
|
||||
{
|
||||
services.mastodon = {
|
||||
enable = true;
|
||||
|
||||
|
@ -9,7 +11,6 @@ in {
|
|||
smtp = {
|
||||
# TODO: smtp setup
|
||||
fromAddress = "social@services.dgnum.eu";
|
||||
|
||||
};
|
||||
|
||||
streamingProcesses = 4;
|
||||
|
@ -38,5 +39,7 @@ in {
|
|||
extraEnvFiles = [ config.age.secrets."mastodon-extra_env_file".path ];
|
||||
};
|
||||
|
||||
age-secrets.matches."^mastodon-.*$" = { owner = "mastodon"; };
|
||||
age-secrets.matches."^mastodon-.*$" = {
|
||||
owner = "mastodon";
|
||||
};
|
||||
}
|
||||
|
|
|
@ -3,7 +3,8 @@
|
|||
let
|
||||
host = "cloud.dgnum.eu";
|
||||
nextcloud-occ = "${config.services.nextcloud.occ}/bin/nextcloud-occ";
|
||||
in {
|
||||
in
|
||||
{
|
||||
services.nextcloud = {
|
||||
enable = true;
|
||||
hostName = host;
|
||||
|
@ -102,8 +103,7 @@ in {
|
|||
image = "collabora/code";
|
||||
imageFile = pkgs.dockerTools.pullImage {
|
||||
imageName = "collabora/code";
|
||||
imageDigest =
|
||||
"sha256:a8cce07c949aa59cea0a7f1f220266a1a6d886c717c3b5005782baf6f384d645";
|
||||
imageDigest = "sha256:a8cce07c949aa59cea0a7f1f220266a1a6d886c717c3b5005782baf6f384d645";
|
||||
sha256 = "sha256-lN6skv62x+x7G7SNOUyZ8W6S/uScrkqE1nbBwwSEWXQ=";
|
||||
};
|
||||
ports = [ "9980:9980" ];
|
||||
|
@ -111,7 +111,12 @@ in {
|
|||
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";
|
||||
};
|
||||
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.";
|
||||
script = "${nextcloud-occ} preview:pre-generate -vvv";
|
||||
startAt = "*-*-* 01:00:00 UTC";
|
||||
serviceConfig = { Restart = "on-failure"; };
|
||||
serviceConfig = {
|
||||
Restart = "on-failure";
|
||||
};
|
||||
};
|
||||
|
||||
nextcloud-cron.path = [ pkgs.perl ];
|
||||
|
@ -188,9 +195,13 @@ in {
|
|||
|
||||
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 = {
|
||||
restart-nextcloud.text = ''
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
{ config, ... }:
|
||||
|
||||
let host = "docs.dgnum.eu";
|
||||
in {
|
||||
let
|
||||
host = "docs.dgnum.eu";
|
||||
in
|
||||
{
|
||||
services.outline = {
|
||||
enable = true;
|
||||
|
||||
|
@ -27,8 +29,7 @@ in {
|
|||
userinfoUrl = "https://sso.dgnum.eu/oauth2/openid/outline_dgn/userinfo";
|
||||
displayName = "DGNum SSO";
|
||||
|
||||
clientSecretFile =
|
||||
config.age.secrets."outline-oidc_client_secret_file".path;
|
||||
clientSecretFile = config.age.secrets."outline-oidc_client_secret_file".path;
|
||||
};
|
||||
|
||||
defaultLanguage = "fr_FR";
|
||||
|
@ -51,5 +52,7 @@ in {
|
|||
};
|
||||
};
|
||||
|
||||
age-secrets.matches."^outline-.*$" = { owner = "outline"; };
|
||||
age-secrets.matches."^outline-.*$" = {
|
||||
owner = "outline";
|
||||
};
|
||||
}
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
{ pkgs, ... }:
|
||||
|
||||
let
|
||||
host = "rstudio.dgnum.eu";
|
||||
# host = "rstudio.dgnum.eu";
|
||||
port = 19000;
|
||||
in {
|
||||
in
|
||||
{
|
||||
services.rstudio-server = {
|
||||
enable = true;
|
||||
rserverExtraConfig = ''
|
||||
|
@ -11,14 +12,17 @@ in {
|
|||
'';
|
||||
|
||||
package = pkgs.rstudioServerWrapper.override {
|
||||
packages = with pkgs.rPackages; [ ggplot2 rmarkdown dplyr ];
|
||||
packages = with pkgs.rPackages; [
|
||||
ggplot2
|
||||
rmarkdown
|
||||
dplyr
|
||||
];
|
||||
};
|
||||
};
|
||||
|
||||
users.users.ruser = {
|
||||
isNormalUser = true;
|
||||
hashedPassword =
|
||||
"$6$pTXXVh8NfE.M8VPc$q0fFh3Y7Y0DauLCcZLgJzFciq1wkjoHmO61XpOrZLH3a1M32ZzOMbjx2XMm2QxrUncbx6hGerY/lD8rQ8InS4.";
|
||||
hashedPassword = "$6$pTXXVh8NfE.M8VPc$q0fFh3Y7Y0DauLCcZLgJzFciq1wkjoHmO61XpOrZLH3a1M32ZzOMbjx2XMm2QxrUncbx6hGerY/lD8rQ8InS4.";
|
||||
};
|
||||
|
||||
dgn-access-control.users.ruser = [ "jemagius" ];
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
{ config, ... }:
|
||||
|
||||
let host = "saml-idp.dgnum.eu";
|
||||
in {
|
||||
let
|
||||
host = "saml-idp.dgnum.eu";
|
||||
in
|
||||
{
|
||||
|
||||
imports = [ ./module.nix ];
|
||||
|
||||
|
@ -20,8 +22,7 @@ in {
|
|||
config = {
|
||||
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-Redirect" =
|
||||
"sso/redirect";
|
||||
"urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" = "sso/redirect";
|
||||
};
|
||||
entityid_endpoint = true;
|
||||
enable_metadata_reload = false;
|
||||
|
@ -32,11 +33,13 @@ in {
|
|||
url = "https://dgnum.eu";
|
||||
};
|
||||
|
||||
contact_person = [{
|
||||
contact_type = "technical";
|
||||
email_address = "mailto:tom.hubrecht@dgnum.eu";
|
||||
given_name = "Tom Hubrecht";
|
||||
}];
|
||||
contact_person = [
|
||||
{
|
||||
contact_type = "technical";
|
||||
email_address = "mailto:tom.hubrecht@dgnum.eu";
|
||||
given_name = "Tom Hubrecht";
|
||||
}
|
||||
];
|
||||
|
||||
key_file = "/var/lib/satosa/ssl/key.pem";
|
||||
cert_file = "/var/lib/satosa/ssl/cert.pem";
|
||||
|
@ -50,10 +53,12 @@ in {
|
|||
endpoints.single_sign_on_service = [ ];
|
||||
name = "DGNum proxy IdP";
|
||||
ui_info = {
|
||||
display_name = [{
|
||||
lang = "fr";
|
||||
text = "Service de connexion DGNum";
|
||||
}];
|
||||
display_name = [
|
||||
{
|
||||
lang = "fr";
|
||||
text = "Service de connexion DGNum";
|
||||
}
|
||||
];
|
||||
};
|
||||
name_id_format = [
|
||||
"urn:oasis:names:tc:SAML:2.0:nameid-format:persistent"
|
||||
|
@ -63,9 +68,10 @@ in {
|
|||
default = {
|
||||
attribute_restrictions = null;
|
||||
fail_on_missing_requested = false;
|
||||
lifetime = { minutes = 15; };
|
||||
name_form =
|
||||
"urn:oasis:names:tc:SAML:2.0:attrname-format:uri";
|
||||
lifetime = {
|
||||
minutes = 15;
|
||||
};
|
||||
name_form = "urn:oasis:names:tc:SAML:2.0:attrname-format:uri";
|
||||
encrypt_assertion = false;
|
||||
encrypted_advice_attributes = false;
|
||||
};
|
||||
|
@ -121,12 +127,15 @@ in {
|
|||
module = "satosa.backends.openid_connect.OpenIDConnectBackend";
|
||||
name = "kanidm";
|
||||
config = {
|
||||
provider_metadata.issuer =
|
||||
"https://sso.dgnum.eu/oauth2/openid/satosa_dgn/";
|
||||
provider_metadata.issuer = "https://sso.dgnum.eu/oauth2/openid/satosa_dgn/";
|
||||
client = {
|
||||
auth_req_params = {
|
||||
response_type = "code";
|
||||
scope = [ "openid" "profile" "email" ];
|
||||
scope = [
|
||||
"openid"
|
||||
"profile"
|
||||
"email"
|
||||
];
|
||||
};
|
||||
client_metadata = {
|
||||
client_id = "satosa_dgn";
|
||||
|
@ -144,5 +153,7 @@ in {
|
|||
forceSSL = true;
|
||||
};
|
||||
|
||||
age-secrets.matches."^satosa-.*$" = { owner = "satosa"; };
|
||||
age-secrets.matches."^satosa-.*$" = {
|
||||
owner = "satosa";
|
||||
};
|
||||
}
|
||||
|
|
|
@ -1,7 +1,18 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
|
||||
let
|
||||
inherit (lib) mkDefault mkEnableOption mkIf mkOption types;
|
||||
inherit (lib)
|
||||
mkDefault
|
||||
mkEnableOption
|
||||
mkIf
|
||||
mkOption
|
||||
types
|
||||
;
|
||||
|
||||
yamlFormat = pkgs.formats.yaml { };
|
||||
|
||||
|
@ -9,12 +20,17 @@ let
|
|||
|
||||
cfg = config.services.satosa;
|
||||
|
||||
mkYamlFiles = files:
|
||||
builtins.attrValues
|
||||
(builtins.mapAttrs (name: yamlFormat.generate "${name}.yaml") files);
|
||||
mkYamlFiles =
|
||||
files: builtins.attrValues (builtins.mapAttrs (name: yamlFormat.generate "${name}.yaml") files);
|
||||
|
||||
pyEnv = cfg.package.python.withPackages (ps: [ cfg.package ps.gunicorn ]);
|
||||
in {
|
||||
pyEnv = cfg.package.python.withPackages (
|
||||
ps: [
|
||||
cfg.package
|
||||
ps.gunicorn
|
||||
]
|
||||
);
|
||||
in
|
||||
{
|
||||
options.services.satosa = {
|
||||
enable = mkEnableOption "SATOSA, a SAML and OIDC proxy.";
|
||||
|
||||
|
@ -88,8 +104,7 @@ in {
|
|||
MICRO_SERVICES = mkYamlFiles cfg.microServices;
|
||||
LOGGING = {
|
||||
version = 1;
|
||||
formatters.simple.format =
|
||||
"[%(asctime)s] [%(levelname)s] [%(name)s.%(funcName)s] %(message)s";
|
||||
formatters.simple.format = "[%(asctime)s] [%(levelname)s] [%(name)s.%(funcName)s] %(message)s";
|
||||
handlers.stdout = {
|
||||
class = "logging.StreamHandler";
|
||||
stream = "ext://sys.stdout";
|
||||
|
@ -171,7 +186,9 @@ in {
|
|||
TimeoutStopSec = "5";
|
||||
EnvironmentFile = lib.optional (cfg.envFile != null) cfg.envFile;
|
||||
};
|
||||
environment = { SATOSA_CONFIG = configFile; };
|
||||
environment = {
|
||||
SATOSA_CONFIG = configFile;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -179,8 +196,7 @@ in {
|
|||
enable = true;
|
||||
|
||||
virtualHosts.${cfg.host} = {
|
||||
locations."/".proxyPass =
|
||||
"http://127.0.0.1:${builtins.toString cfg.port}";
|
||||
locations."/".proxyPass = "http://127.0.0.1:${builtins.toString cfg.port}";
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
{ lib
|
||||
, python3
|
||||
, fetchPypi
|
||||
{
|
||||
lib,
|
||||
python3,
|
||||
fetchPypi,
|
||||
}:
|
||||
|
||||
python3.pkgs.buildPythonPackage rec {
|
||||
|
|
|
@ -13,5 +13,5 @@ let
|
|||
pydantic = callPackage ./pydantic.nix { };
|
||||
pydantic-core = callPackage ./pydantic-core.nix { };
|
||||
};
|
||||
|
||||
in self.satosa
|
||||
in
|
||||
self.satosa
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
{ lib
|
||||
, python3
|
||||
, fetchPypi
|
||||
, pydantic-settings
|
||||
{
|
||||
lib,
|
||||
python3,
|
||||
fetchPypi,
|
||||
pydantic-settings,
|
||||
}:
|
||||
|
||||
python3.pkgs.buildPythonPackage rec {
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
{ lib
|
||||
, python3
|
||||
, fetchPypi
|
||||
, cargo
|
||||
, rustPlatform
|
||||
, rustc
|
||||
{
|
||||
lib,
|
||||
python3,
|
||||
fetchPypi,
|
||||
cargo,
|
||||
rustPlatform,
|
||||
rustc,
|
||||
}:
|
||||
|
||||
python3.pkgs.buildPythonPackage rec {
|
||||
|
@ -31,9 +32,7 @@ python3.pkgs.buildPythonPackage rec {
|
|||
rustc
|
||||
];
|
||||
|
||||
propagatedBuildInputs = with python3.pkgs; [
|
||||
typing-extensions
|
||||
];
|
||||
propagatedBuildInputs = with python3.pkgs; [ typing-extensions ];
|
||||
|
||||
pythonImportsCheck = [ "pydantic_core" ];
|
||||
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
{ lib
|
||||
, python3
|
||||
, fetchPypi
|
||||
, pydantic
|
||||
{
|
||||
lib,
|
||||
python3,
|
||||
fetchPypi,
|
||||
pydantic,
|
||||
}:
|
||||
|
||||
python3.pkgs.buildPythonPackage rec {
|
||||
|
@ -15,9 +16,7 @@ python3.pkgs.buildPythonPackage rec {
|
|||
hash = "sha256-li3DZySVqtaulqQ5D6x+WTWR4URiXlES01n49n+3WUU=";
|
||||
};
|
||||
|
||||
nativeBuildInputs = [
|
||||
python3.pkgs.hatchling
|
||||
];
|
||||
nativeBuildInputs = [ python3.pkgs.hatchling ];
|
||||
|
||||
propagatedBuildInputs = with python3.pkgs; [
|
||||
pydantic
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
{ lib
|
||||
, python3
|
||||
, fetchPypi
|
||||
, pydantic-core
|
||||
{
|
||||
lib,
|
||||
python3,
|
||||
fetchPypi,
|
||||
pydantic-core,
|
||||
}:
|
||||
|
||||
python3.pkgs.buildPythonPackage rec {
|
||||
|
@ -26,9 +27,7 @@ python3.pkgs.buildPythonPackage rec {
|
|||
];
|
||||
|
||||
passthru.optional-dependencies = with python3.pkgs; {
|
||||
email = [
|
||||
email-validator
|
||||
];
|
||||
email = [ email-validator ];
|
||||
};
|
||||
|
||||
pythonImportsCheck = [ "pydantic" ];
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
{ lib
|
||||
, python3
|
||||
, fetchPypi
|
||||
, oic
|
||||
{
|
||||
lib,
|
||||
python3,
|
||||
fetchPypi,
|
||||
oic,
|
||||
}:
|
||||
|
||||
python3.pkgs.buildPythonPackage rec {
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
{ lib
|
||||
, python3
|
||||
, fetchPypi
|
||||
, cookies-samesite-compat
|
||||
, pyop
|
||||
{
|
||||
lib,
|
||||
python3,
|
||||
fetchPypi,
|
||||
cookies-samesite-compat,
|
||||
pyop,
|
||||
}:
|
||||
|
||||
python3.pkgs.buildPythonPackage rec {
|
||||
|
@ -36,15 +37,9 @@ python3.pkgs.buildPythonPackage rec {
|
|||
];
|
||||
|
||||
passthru.optional-dependencies = with python3.pkgs; {
|
||||
ldap = [
|
||||
ldap3
|
||||
];
|
||||
pyop_mongo = [
|
||||
pyop
|
||||
];
|
||||
pyop_redis = [
|
||||
pyop
|
||||
];
|
||||
ldap = [ ldap3 ];
|
||||
pyop_mongo = [ pyop ];
|
||||
pyop_redis = [ pyop ];
|
||||
};
|
||||
|
||||
passthru.python = python3;
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
{ config, ... }:
|
||||
|
||||
let host = "pass.dgnum.eu";
|
||||
|
||||
in {
|
||||
let
|
||||
host = "pass.dgnum.eu";
|
||||
in
|
||||
{
|
||||
services.vaultwarden = {
|
||||
enable = true;
|
||||
|
||||
|
@ -62,10 +63,12 @@ in {
|
|||
|
||||
ensureDatabases = [ "vaultwarden" ];
|
||||
|
||||
ensureUsers = [{
|
||||
name = "vaultwarden";
|
||||
ensureDBOwnership = true;
|
||||
}];
|
||||
ensureUsers = [
|
||||
{
|
||||
name = "vaultwarden";
|
||||
ensureDBOwnership = true;
|
||||
}
|
||||
];
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
|
@ -5,7 +5,8 @@ let
|
|||
|
||||
port = 3005;
|
||||
websocketPort = 6902;
|
||||
in {
|
||||
in
|
||||
{
|
||||
services.zammad = {
|
||||
enable = true;
|
||||
|
||||
|
@ -38,10 +39,9 @@ in {
|
|||
proxyWebsockets = true;
|
||||
};
|
||||
|
||||
"~ ^/(assets/|robots.txt|humans.txt|favicon.ico|apple-touch-icon.png)".extraConfig =
|
||||
''
|
||||
expires max;
|
||||
'';
|
||||
"~ ^/(assets/|robots.txt|humans.txt|favicon.ico|apple-touch-icon.png)".extraConfig = ''
|
||||
expires max;
|
||||
'';
|
||||
};
|
||||
|
||||
extraConfig = ''
|
||||
|
@ -51,5 +51,7 @@ in {
|
|||
};
|
||||
};
|
||||
|
||||
age-secrets.matches."^zammad-.*$" = { owner = "zammad"; };
|
||||
age-secrets.matches."^zammad-.*$" = {
|
||||
owner = "zammad";
|
||||
};
|
||||
}
|
||||
|
|
|
@ -29,6 +29,5 @@
|
|||
fsType = "vfat";
|
||||
};
|
||||
|
||||
swapDevices =
|
||||
[{ device = "/dev/disk/by-uuid/65a6f6e4-e996-4718-a4d0-cd0c78dcb15b"; }];
|
||||
swapDevices = [ { device = "/dev/disk/by-uuid/65a6f6e4-e996-4718-a4d0-cd0c78dcb15b"; } ];
|
||||
}
|
||||
|
|
|
@ -1,8 +1,14 @@
|
|||
{ config, pkgs, sources, ... }:
|
||||
{
|
||||
config,
|
||||
pkgs,
|
||||
sources,
|
||||
...
|
||||
}:
|
||||
|
||||
let host = "cachix.dgnum.eu";
|
||||
|
||||
in {
|
||||
let
|
||||
host = "cachix.dgnum.eu";
|
||||
in
|
||||
{
|
||||
services = {
|
||||
atticd = {
|
||||
enable = true;
|
||||
|
@ -68,10 +74,12 @@ in {
|
|||
|
||||
ensureDatabases = [ "atticd" ];
|
||||
|
||||
ensureUsers = [{
|
||||
name = "atticd";
|
||||
ensureDBOwnership = true;
|
||||
}];
|
||||
ensureUsers = [
|
||||
{
|
||||
name = "atticd";
|
||||
ensureDBOwnership = true;
|
||||
}
|
||||
];
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
|
@ -3,18 +3,29 @@
|
|||
let
|
||||
url = "https://git.dgnum.eu";
|
||||
|
||||
mkRunner = { labels, name, token }: {
|
||||
enable = true;
|
||||
mkRunner =
|
||||
{
|
||||
labels,
|
||||
name,
|
||||
token,
|
||||
}:
|
||||
{
|
||||
enable = true;
|
||||
|
||||
inherit name labels token url;
|
||||
inherit
|
||||
name
|
||||
labels
|
||||
token
|
||||
url
|
||||
;
|
||||
|
||||
settings.container = {
|
||||
network = "host";
|
||||
options = "--cpus=4";
|
||||
settings.container = {
|
||||
network = "host";
|
||||
options = "--cpus=4";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
in {
|
||||
in
|
||||
{
|
||||
services.forgejo-nix-runners = {
|
||||
enable = true;
|
||||
|
||||
|
@ -23,7 +34,11 @@ in {
|
|||
storePath = "/data/slow/nix";
|
||||
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" ];
|
||||
|
||||
|
|
|
@ -3,7 +3,8 @@
|
|||
let
|
||||
port = 3000;
|
||||
host = "git.dgnum.eu";
|
||||
in {
|
||||
in
|
||||
{
|
||||
services = {
|
||||
forgejo = {
|
||||
enable = true;
|
||||
|
@ -19,7 +20,9 @@ in {
|
|||
};
|
||||
|
||||
settings = {
|
||||
DEFAULT = { APP_NAME = "Forge git de la DGNum"; };
|
||||
DEFAULT = {
|
||||
APP_NAME = "Forge git de la DGNum";
|
||||
};
|
||||
|
||||
server = {
|
||||
ROOT_URL = "https://${host}/";
|
||||
|
@ -62,7 +65,9 @@ in {
|
|||
virtualHosts.${host} = {
|
||||
enableACME = 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 = { };
|
||||
|
||||
age-secrets.matches."^forgejo-.*$" = { owner = "git"; };
|
||||
age-secrets.matches."^forgejo-.*$" = {
|
||||
owner = "git";
|
||||
};
|
||||
}
|
||||
|
|
|
@ -8,20 +8,22 @@ let
|
|||
metadata_dir = "/data/fast/garage/meta";
|
||||
|
||||
buckets = [ "peertube-videos-dgnum" ];
|
||||
|
||||
in {
|
||||
in
|
||||
{
|
||||
services.garage = {
|
||||
enable = true;
|
||||
|
||||
package = pkgs.garage_0_9.overrideAttrs (old: {
|
||||
patches = (old.patches or [ ]) ++ [
|
||||
# Allow 0 as a part number marker
|
||||
(pkgs.fetchpatch {
|
||||
url = "https://git.deuxfleurs.fr/Deuxfleurs/garage/pulls/670.patch";
|
||||
hash = "sha256-28ctLl1qscMRj2JEVnmhuLyK1Avub8QeyfQFxAK0y08=";
|
||||
})
|
||||
];
|
||||
});
|
||||
package = pkgs.garage_0_9.overrideAttrs (
|
||||
old: {
|
||||
patches = (old.patches or [ ]) ++ [
|
||||
# Allow 0 as a part number marker
|
||||
(pkgs.fetchpatch {
|
||||
url = "https://git.deuxfleurs.fr/Deuxfleurs/garage/pulls/670.patch";
|
||||
hash = "sha256-28ctLl1qscMRj2JEVnmhuLyK1Avub8QeyfQFxAK0y08=";
|
||||
})
|
||||
];
|
||||
}
|
||||
);
|
||||
|
||||
settings = {
|
||||
inherit data_dir metadata_dir;
|
||||
|
@ -56,7 +58,10 @@ in {
|
|||
|
||||
systemd.services.garage.serviceConfig = {
|
||||
User = "garage";
|
||||
ReadWriteDirectories = [ data_dir metadata_dir ];
|
||||
ReadWriteDirectories = [
|
||||
data_dir
|
||||
metadata_dir
|
||||
];
|
||||
};
|
||||
|
||||
users.users.garage = {
|
||||
|
|
|
@ -1,8 +1,24 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
let
|
||||
inherit (lib)
|
||||
filterAttrs literalExpression maintainers mkDefault mkEnableOption mkIf
|
||||
mkMerge mkOption optionalAttrs optionalString optionals types;
|
||||
filterAttrs
|
||||
literalExpression
|
||||
maintainers
|
||||
mkDefault
|
||||
mkEnableOption
|
||||
mkIf
|
||||
mkMerge
|
||||
mkOption
|
||||
optionalAttrs
|
||||
optionalString
|
||||
optionals
|
||||
types
|
||||
;
|
||||
|
||||
inherit ((import ./package { inherit pkgs; })) dashboard;
|
||||
|
||||
|
@ -13,92 +29,100 @@ let
|
|||
settingsFormat = pkgs.formats.keyValue { };
|
||||
managementFormat = pkgs.formats.json { };
|
||||
|
||||
settingsFile = settingsFormat.generate "setup.env" (builtins.mapAttrs (_: val:
|
||||
if builtins.isList val then
|
||||
''"${builtins.concatStringsSep " " val}"''
|
||||
else
|
||||
val) settings);
|
||||
settingsFile = settingsFormat.generate "setup.env" (
|
||||
builtins.mapAttrs
|
||||
(_: val: if builtins.isList val then ''"${builtins.concatStringsSep " " val}"'' else val)
|
||||
settings
|
||||
);
|
||||
|
||||
managementFile = managementFormat.generate "config.json" cfg.managementConfig;
|
||||
|
||||
settings = rec {
|
||||
TURN_DOMAIN = cfg.settings.NETBIRD_DOMAIN;
|
||||
TURN_PORT = 3478;
|
||||
TURN_USER = "netbird";
|
||||
TURN_MIN_PORT = 49152;
|
||||
TURN_MAX_PORT = 65535;
|
||||
TURN_PASSWORD =
|
||||
if cfg.secretFiles.TURN_PASSWORD != null then "$TURN_PASSWORD" else null;
|
||||
TURN_SECRET =
|
||||
if cfg.secretFiles.TURN_SECRET != null then "$TURN_SECRET" else "secret";
|
||||
settings =
|
||||
rec {
|
||||
TURN_DOMAIN = cfg.settings.NETBIRD_DOMAIN;
|
||||
TURN_PORT = 3478;
|
||||
TURN_USER = "netbird";
|
||||
TURN_MIN_PORT = 49152;
|
||||
TURN_MAX_PORT = 65535;
|
||||
TURN_PASSWORD = if cfg.secretFiles.TURN_PASSWORD != null then "$TURN_PASSWORD" else null;
|
||||
TURN_SECRET = if cfg.secretFiles.TURN_SECRET != null then "$TURN_SECRET" else "secret";
|
||||
|
||||
STUN_USERNAME = "";
|
||||
STUN_PASSWORD =
|
||||
if cfg.secretFiles.STUN_PASSWORD != null then "$STUN_PASSWORD" else null;
|
||||
STUN_USERNAME = "";
|
||||
STUN_PASSWORD = if cfg.secretFiles.STUN_PASSWORD != null then "$STUN_PASSWORD" else null;
|
||||
|
||||
NETBIRD_DASHBOARD_ENDPOINT = "https://${cfg.settings.NETBIRD_DOMAIN}:443";
|
||||
NETBIRD_MGMT_API_ENDPOINT = "https://${cfg.settings.NETBIRD_DOMAIN}:${
|
||||
builtins.toString
|
||||
cfg.settings.NETBIRD_MGMT_API_PORT or NETBIRD_MGMT_API_PORT
|
||||
NETBIRD_DASHBOARD_ENDPOINT = "https://${cfg.settings.NETBIRD_DOMAIN}:443";
|
||||
NETBIRD_MGMT_API_ENDPOINT = "https://${cfg.settings.NETBIRD_DOMAIN}:${
|
||||
builtins.toString cfg.settings.NETBIRD_MGMT_API_PORT or NETBIRD_MGMT_API_PORT
|
||||
}";
|
||||
NETBIRD_SIGNAL_ENDPOINT = "https://${cfg.settings.NETBIRD_DOMAIN}:${
|
||||
builtins.toString
|
||||
cfg.settings.NETBIRD_SIGNAL_PORT or NETBIRD_SIGNAL_PORT
|
||||
NETBIRD_SIGNAL_ENDPOINT = "https://${cfg.settings.NETBIRD_DOMAIN}:${
|
||||
builtins.toString cfg.settings.NETBIRD_SIGNAL_PORT or NETBIRD_SIGNAL_PORT
|
||||
}";
|
||||
|
||||
NETBIRD_SIGNAL_PROTOCOL = "https";
|
||||
NETBIRD_SIGNAL_PORT = 443;
|
||||
NETBIRD_SIGNAL_PROTOCOL = "https";
|
||||
NETBIRD_SIGNAL_PORT = 443;
|
||||
|
||||
NETBIRD_AUTH_USER_ID_CLAIM = "sub";
|
||||
NETBIRD_AUTH_CLIENT_SECRET =
|
||||
if cfg.secretFiles.AUTH_CLIENT_SECRET != null then
|
||||
"$AUTH_CLIENT_SECRET"
|
||||
else
|
||||
"";
|
||||
NETBIRD_AUTH_SUPPORTED_SCOPES =
|
||||
[ "openid" "profile" "email" "offline_access" "api" ];
|
||||
NETBIRD_AUTH_USER_ID_CLAIM = "sub";
|
||||
NETBIRD_AUTH_CLIENT_SECRET =
|
||||
if cfg.secretFiles.AUTH_CLIENT_SECRET != null then "$AUTH_CLIENT_SECRET" else "";
|
||||
NETBIRD_AUTH_SUPPORTED_SCOPES = [
|
||||
"openid"
|
||||
"profile"
|
||||
"email"
|
||||
"offline_access"
|
||||
"api"
|
||||
];
|
||||
|
||||
NETBIRD_AUTH_REDIRECT_URI = "";
|
||||
NETBIRD_AUTH_SILENT_REDIRECT_URI = "";
|
||||
NETBIRD_AUTH_REDIRECT_URI = "";
|
||||
NETBIRD_AUTH_SILENT_REDIRECT_URI = "";
|
||||
|
||||
NETBIRD_AUTH_DEVICE_AUTH_PROVIDER = "none";
|
||||
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_SCOPE =
|
||||
[ "openid" "profile" "email" "offline_access" "api" ];
|
||||
NETBIRD_AUTH_DEVICE_AUTH_USE_ID_TOKEN = false;
|
||||
NETBIRD_AUTH_DEVICE_AUTH_PROVIDER = "none";
|
||||
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_SCOPE = [
|
||||
"openid"
|
||||
"profile"
|
||||
"email"
|
||||
"offline_access"
|
||||
"api"
|
||||
];
|
||||
NETBIRD_AUTH_DEVICE_AUTH_USE_ID_TOKEN = false;
|
||||
|
||||
NETBIRD_MGMT_API_PORT = 443;
|
||||
NETBIRD_MGMT_API_PORT = 443;
|
||||
|
||||
NETBIRD_MGMT_IDP = "none";
|
||||
NETBIRD_IDP_MGMT_CLIENT_ID = cfg.settings.NETBIRD_AUTH_CLIENT_ID;
|
||||
NETBIRD_IDP_MGMT_CLIENT_SECRET =
|
||||
if cfg.secretFiles.IDP_MGMT_CLIENT_SECRET != null then
|
||||
"$IDP_MGMT_CLIENT_SECRET"
|
||||
else
|
||||
cfg.settings.NETBIRD_AUTH_CLIENT_SECRET;
|
||||
NETBIRD_IDP_MGMT_GRANT_TYPE = "client_credentials";
|
||||
NETBIRD_MGMT_IDP = "none";
|
||||
NETBIRD_IDP_MGMT_CLIENT_ID = cfg.settings.NETBIRD_AUTH_CLIENT_ID;
|
||||
NETBIRD_IDP_MGMT_CLIENT_SECRET =
|
||||
if cfg.secretFiles.IDP_MGMT_CLIENT_SECRET != null then
|
||||
"$IDP_MGMT_CLIENT_SECRET"
|
||||
else
|
||||
cfg.settings.NETBIRD_AUTH_CLIENT_SECRET;
|
||||
NETBIRD_IDP_MGMT_GRANT_TYPE = "client_credentials";
|
||||
|
||||
NETBIRD_TOKEN_SOURCE = "accessToken";
|
||||
NETBIRD_DRAG_QUERY_PARAMS = false;
|
||||
NETBIRD_TOKEN_SOURCE = "accessToken";
|
||||
NETBIRD_DRAG_QUERY_PARAMS = false;
|
||||
|
||||
NETBIRD_USE_AUTH0 = false;
|
||||
NETBIRD_USE_AUTH0 = false;
|
||||
|
||||
NETBIRD_AUTH_DEVICE_AUTH_ENDPOINT = "";
|
||||
NETBIRD_AUTH_DEVICE_AUTH_ENDPOINT = "";
|
||||
|
||||
NETBIRD_AUTH_PKCE_REDIRECT_URL_PORTS = [ "53000" ];
|
||||
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;
|
||||
} // (optionalAttrs cfg.setupAutoOidc {
|
||||
NETBIRD_AUTH_PKCE_AUTHORIZATION_ENDPOINT =
|
||||
"$NETBIRD_AUTH_PKCE_AUTHORIZATION_ENDPOINT";
|
||||
NETBIRD_AUTH_DEVICE_AUTH_ENDPOINT = "$NETBIRD_AUTH_DEVICE_AUTH_ENDPOINT";
|
||||
NETBIRD_AUTH_TOKEN_ENDPOINT = "$NETBIRD_AUTH_TOKEN_ENDPOINT";
|
||||
NETBIRD_AUTH_JWT_CERTS = "$NETBIRD_AUTH_JWT_CERTS";
|
||||
NETBIRD_AUTH_AUTHORITY = "$NETBIRD_AUTH_AUTHORITY";
|
||||
}) // cfg.settings;
|
||||
in {
|
||||
meta = { maintainers = with maintainers; [ thubrecht ]; };
|
||||
NETBIRD_AUTH_PKCE_REDIRECT_URL_PORTS = [ "53000" ];
|
||||
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;
|
||||
}
|
||||
// (optionalAttrs cfg.setupAutoOidc {
|
||||
NETBIRD_AUTH_PKCE_AUTHORIZATION_ENDPOINT = "$NETBIRD_AUTH_PKCE_AUTHORIZATION_ENDPOINT";
|
||||
NETBIRD_AUTH_DEVICE_AUTH_ENDPOINT = "$NETBIRD_AUTH_DEVICE_AUTH_ENDPOINT";
|
||||
NETBIRD_AUTH_TOKEN_ENDPOINT = "$NETBIRD_AUTH_TOKEN_ENDPOINT";
|
||||
NETBIRD_AUTH_JWT_CERTS = "$NETBIRD_AUTH_JWT_CERTS";
|
||||
NETBIRD_AUTH_AUTHORITY = "$NETBIRD_AUTH_AUTHORITY";
|
||||
})
|
||||
// cfg.settings;
|
||||
in
|
||||
{
|
||||
meta = {
|
||||
maintainers = with maintainers; [ thubrecht ];
|
||||
};
|
||||
|
||||
options.services.netbird-server = {
|
||||
enable = mkEnableOption (lib.mdDoc "netbird management service.");
|
||||
|
@ -111,8 +135,19 @@ in {
|
|||
};
|
||||
|
||||
settings = mkOption {
|
||||
type = with types;
|
||||
attrsOf (nullOr (oneOf [ (listOf str) bool int float str ]));
|
||||
type =
|
||||
with types;
|
||||
attrsOf (
|
||||
nullOr (
|
||||
oneOf [
|
||||
(listOf str)
|
||||
bool
|
||||
int
|
||||
float
|
||||
str
|
||||
]
|
||||
)
|
||||
);
|
||||
defaultText = lib.literalExpression ''
|
||||
{
|
||||
TURN_DOMAIN = cfg.settings.NETBIRD_DOMAIN;
|
||||
|
@ -195,15 +230,19 @@ in {
|
|||
};
|
||||
|
||||
logLevel = mkOption {
|
||||
type = types.enum [ "ERROR" "WARN" "INFO" "DEBUG" ];
|
||||
type = types.enum [
|
||||
"ERROR"
|
||||
"WARN"
|
||||
"INFO"
|
||||
"DEBUG"
|
||||
];
|
||||
default = "INFO";
|
||||
description = lib.mdDoc "Log level of the netbird services.";
|
||||
};
|
||||
|
||||
enableDeviceAuthorizationFlow =
|
||||
mkEnableOption "device authorization flow for netbird." // {
|
||||
default = true;
|
||||
};
|
||||
enableDeviceAuthorizationFlow = mkEnableOption "device authorization flow for netbird." // {
|
||||
default = true;
|
||||
};
|
||||
|
||||
enableNginx = mkEnableOption "NGINX reverse-proxy for the netbird server.";
|
||||
|
||||
|
@ -232,8 +271,7 @@ in {
|
|||
disableAnonymousMetrics = mkOption {
|
||||
type = types.bool;
|
||||
default = true;
|
||||
description =
|
||||
lib.mdDoc "Disables push of anonymous usage metrics to NetBird.";
|
||||
description = lib.mdDoc "Disables push of anonymous usage metrics to NetBird.";
|
||||
};
|
||||
|
||||
disableSingleAccountMode = mkOption {
|
||||
|
@ -250,38 +288,32 @@ in {
|
|||
TURN_PASSWORD = mkOption {
|
||||
type = with types; nullOr path;
|
||||
default = null;
|
||||
description =
|
||||
lib.mdDoc "Path to a file containing the secret TURN_PASSWORD.";
|
||||
description = lib.mdDoc "Path to a file containing the secret TURN_PASSWORD.";
|
||||
};
|
||||
|
||||
TURN_SECRET = mkOption {
|
||||
type = with types; nullOr path;
|
||||
default = null;
|
||||
description =
|
||||
lib.mdDoc "Path to a file containing the secret TURN_SECRET.";
|
||||
description = lib.mdDoc "Path to a file containing the secret TURN_SECRET.";
|
||||
};
|
||||
|
||||
STUN_PASSWORD = mkOption {
|
||||
type = with types; nullOr path;
|
||||
default = null;
|
||||
description =
|
||||
lib.mdDoc "Path to a file containing the secret STUN_PASSWORD.";
|
||||
description = lib.mdDoc "Path to a file containing the secret STUN_PASSWORD.";
|
||||
};
|
||||
|
||||
AUTH_CLIENT_SECRET = mkOption {
|
||||
type = with types; nullOr path;
|
||||
default = null;
|
||||
description = lib.mdDoc
|
||||
"Path to a file containing the secret NETBIRD_AUTH_CLIENT_SECRET.";
|
||||
description = lib.mdDoc "Path to a file containing the secret NETBIRD_AUTH_CLIENT_SECRET.";
|
||||
};
|
||||
|
||||
IDP_MGMT_CLIENT_SECRET = mkOption {
|
||||
type = with types; nullOr path;
|
||||
default = cfg.secretFiles.AUTH_CLIENT_SECRET;
|
||||
defaultText =
|
||||
lib.literalExpression "cfg.secretFiles.AUTH_CLIENT_SECRET;";
|
||||
description = lib.mdDoc
|
||||
"Path to a file containing the secret NETBIRD_IDP_MGMT_CLIENT_SECRET.";
|
||||
defaultText = lib.literalExpression "cfg.secretFiles.AUTH_CLIENT_SECRET;";
|
||||
description = lib.mdDoc "Path to a file containing the secret NETBIRD_IDP_MGMT_CLIENT_SECRET.";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
@ -289,19 +321,23 @@ in {
|
|||
config = mkMerge [
|
||||
(mkIf cfg.enable {
|
||||
services.netbird-server.managementConfig = with settings; {
|
||||
Stuns = mkDefault [{
|
||||
Proto = "udp";
|
||||
URI = "stun:${TURN_DOMAIN}:${builtins.toString TURN_PORT}";
|
||||
Username = STUN_USERNAME;
|
||||
Password = STUN_PASSWORD;
|
||||
}];
|
||||
TURNConfig = {
|
||||
Turns = [{
|
||||
Stuns = mkDefault [
|
||||
{
|
||||
Proto = "udp";
|
||||
URI = "turn:${TURN_DOMAIN}:${builtins.toString TURN_PORT}";
|
||||
Username = TURN_USER;
|
||||
Password = TURN_PASSWORD;
|
||||
}];
|
||||
URI = "stun:${TURN_DOMAIN}:${builtins.toString TURN_PORT}";
|
||||
Username = STUN_USERNAME;
|
||||
Password = STUN_PASSWORD;
|
||||
}
|
||||
];
|
||||
TURNConfig = {
|
||||
Turns = [
|
||||
{
|
||||
Proto = "udp";
|
||||
URI = "turn:${TURN_DOMAIN}:${builtins.toString TURN_PORT}";
|
||||
Username = TURN_USER;
|
||||
Password = TURN_PASSWORD;
|
||||
}
|
||||
];
|
||||
CredentialsTTL = "12h";
|
||||
Secret = TURN_SECRET;
|
||||
TimeBasedCredentials = false;
|
||||
|
@ -340,8 +376,7 @@ in {
|
|||
ClientID = NETBIRD_AUTH_DEVICE_AUTH_CLIENT_ID;
|
||||
TokenEndpoint = NETBIRD_AUTH_TOKEN_ENDPOINT;
|
||||
DeviceAuthEndpoint = NETBIRD_AUTH_DEVICE_AUTH_ENDPOINT;
|
||||
Scope =
|
||||
builtins.concatStringsSep " " NETBIRD_AUTH_DEVICE_AUTH_SCOPE;
|
||||
Scope = builtins.concatStringsSep " " NETBIRD_AUTH_DEVICE_AUTH_SCOPE;
|
||||
UseIDToken = NETBIRD_AUTH_DEVICE_AUTH_USE_ID_TOKEN;
|
||||
};
|
||||
};
|
||||
|
@ -377,13 +412,10 @@ in {
|
|||
grpc_socket_keepalive on;
|
||||
'';
|
||||
|
||||
"/api".proxyPass =
|
||||
"http://localhost:${builtins.toString cfg.ports.management}";
|
||||
"/api".proxyPass = "http://localhost:${builtins.toString cfg.ports.management}";
|
||||
|
||||
"/management.ManagementService/".extraConfig = ''
|
||||
grpc_pass grpc://localhost:${
|
||||
builtins.toString cfg.ports.management
|
||||
};
|
||||
grpc_pass grpc://localhost:${builtins.toString cfg.ports.management};
|
||||
grpc_read_timeout 1d;
|
||||
grpc_send_timeout 1d;
|
||||
grpc_socket_keepalive on;
|
||||
|
@ -411,59 +443,81 @@ in {
|
|||
StartLimitBurst = 10;
|
||||
};
|
||||
|
||||
path = (with pkgs; [ coreutils findutils gettext gnused ])
|
||||
++ (optionals cfg.setupAutoOidc (with pkgs; [ curl jq ]));
|
||||
path =
|
||||
(with pkgs; [
|
||||
coreutils
|
||||
findutils
|
||||
gettext
|
||||
gnused
|
||||
])
|
||||
++ (optionals cfg.setupAutoOidc (
|
||||
with pkgs;
|
||||
[
|
||||
curl
|
||||
jq
|
||||
]
|
||||
));
|
||||
|
||||
script = ''
|
||||
cp ${managementFile} ${stateDir}/management.json.copy
|
||||
'' + (optionalString cfg.setupAutoOidc ''
|
||||
mv ${stateDir}/management.json.copy ${stateDir}/management.json
|
||||
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
|
||||
script =
|
||||
''
|
||||
cp ${managementFile} ${stateDir}/management.json.copy
|
||||
''
|
||||
+ (optionalString cfg.setupAutoOidc ''
|
||||
mv ${stateDir}/management.json.copy ${stateDir}/management.json
|
||||
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
|
||||
|
||||
export NETBIRD_AUTH_AUTHORITY=$(jq -r '.issuer' ${stateDir}/openid-configuration.json)
|
||||
export NETBIRD_AUTH_JWT_CERTS=$(jq -r '.jwks_uri' ${stateDir}/openid-configuration.json)
|
||||
export NETBIRD_AUTH_TOKEN_ENDPOINT=$(jq -r '.token_endpoint' ${stateDir}/openid-configuration.json)
|
||||
export NETBIRD_AUTH_DEVICE_AUTH_ENDPOINT=$(jq -r '.device_authorization_endpoint' ${stateDir}/openid-configuration.json)
|
||||
export NETBIRD_AUTH_PKCE_AUTHORIZATION_ENDPOINT=$(jq -r '.authorization_endpoint' ${stateDir}/openid-configuration.json)
|
||||
export NETBIRD_AUTH_AUTHORITY=$(jq -r '.issuer' ${stateDir}/openid-configuration.json)
|
||||
export NETBIRD_AUTH_JWT_CERTS=$(jq -r '.jwks_uri' ${stateDir}/openid-configuration.json)
|
||||
export NETBIRD_AUTH_TOKEN_ENDPOINT=$(jq -r '.token_endpoint' ${stateDir}/openid-configuration.json)
|
||||
export NETBIRD_AUTH_DEVICE_AUTH_ENDPOINT=$(jq -r '.device_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
|
||||
'') + ''
|
||||
# Update secrets in management.json
|
||||
${builtins.concatStringsSep "\n" (builtins.attrValues
|
||||
(builtins.mapAttrs (name: path: "export ${name}=$(cat ${path})")
|
||||
(filterAttrs (_: p: p != null) cfg.secretFiles)))}
|
||||
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
|
||||
${builtins.concatStringsSep "\n" (
|
||||
builtins.attrValues (
|
||||
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
|
||||
|
||||
rm -rf ${stateDir}/web-ui
|
||||
mkdir -p ${stateDir}/web-ui
|
||||
cp -R ${dashboard}/* ${stateDir}/web-ui
|
||||
rm -rf ${stateDir}/web-ui
|
||||
mkdir -p ${stateDir}/web-ui
|
||||
cp -R ${dashboard}/* ${stateDir}/web-ui
|
||||
|
||||
export AUTH_AUTHORITY="$NETBIRD_AUTH_AUTHORITY"
|
||||
export AUTH_CLIENT_ID="$NETBIRD_AUTH_CLIENT_ID"
|
||||
${optionalString (cfg.secretFiles.AUTH_CLIENT_SECRET == null)
|
||||
''export AUTH_CLIENT_SECRET="$NETBIRD_AUTH_CLIENT_SECRET"''}
|
||||
export AUTH_AUDIENCE="$NETBIRD_AUTH_AUDIENCE"
|
||||
export AUTH_REDIRECT_URI="$NETBIRD_AUTH_REDIRECT_URI"
|
||||
export AUTH_SILENT_REDIRECT_URI="$NETBIRD_AUTH_SILENT_REDIRECT_URI"
|
||||
export USE_AUTH0="$NETBIRD_USE_AUTH0"
|
||||
export AUTH_SUPPORTED_SCOPES=$(echo $NETBIRD_AUTH_SUPPORTED_SCOPES | sed -E 's/"//g')
|
||||
export AUTH_AUTHORITY="$NETBIRD_AUTH_AUTHORITY"
|
||||
export AUTH_CLIENT_ID="$NETBIRD_AUTH_CLIENT_ID"
|
||||
${optionalString (cfg.secretFiles.AUTH_CLIENT_SECRET == null)
|
||||
''export AUTH_CLIENT_SECRET="$NETBIRD_AUTH_CLIENT_SECRET"''}
|
||||
export AUTH_AUDIENCE="$NETBIRD_AUTH_AUDIENCE"
|
||||
export AUTH_REDIRECT_URI="$NETBIRD_AUTH_REDIRECT_URI"
|
||||
export AUTH_SILENT_REDIRECT_URI="$NETBIRD_AUTH_SILENT_REDIRECT_URI"
|
||||
export USE_AUTH0="$NETBIRD_USE_AUTH0"
|
||||
export AUTH_SUPPORTED_SCOPES=$(echo $NETBIRD_AUTH_SUPPORTED_SCOPES | sed -E 's/"//g')
|
||||
|
||||
export NETBIRD_MGMT_API_ENDPOINT=$(echo $NETBIRD_MGMT_API_ENDPOINT | sed -E 's/(:80|:443)$//')
|
||||
export NETBIRD_MGMT_API_ENDPOINT=$(echo $NETBIRD_MGMT_API_ENDPOINT | sed -E 's/(:80|:443)$//')
|
||||
|
||||
MAIN_JS=$(find ${stateDir}/web-ui/static/js/main.*js)
|
||||
OIDC_TRUSTED_DOMAINS=${stateDir}/web-ui/OidcTrustedDomains.js
|
||||
mv "$MAIN_JS" "$MAIN_JS".copy
|
||||
envsubst '$USE_AUTH0 $AUTH_AUTHORITY $AUTH_CLIENT_ID $AUTH_CLIENT_SECRET $AUTH_SUPPORTED_SCOPES $AUTH_AUDIENCE $NETBIRD_MGMT_API_ENDPOINT $NETBIRD_MGMT_GRPC_API_ENDPOINT $NETBIRD_HOTJAR_TRACK_ID $AUTH_REDIRECT_URI $AUTH_SILENT_REDIRECT_URI $NETBIRD_TOKEN_SOURCE $NETBIRD_DRAG_QUERY_PARAMS' < "$MAIN_JS".copy > "$MAIN_JS"
|
||||
envsubst '$NETBIRD_MGMT_API_ENDPOINT' < "$OIDC_TRUSTED_DOMAINS".tmpl > "$OIDC_TRUSTED_DOMAINS"
|
||||
'';
|
||||
MAIN_JS=$(find ${stateDir}/web-ui/static/js/main.*js)
|
||||
OIDC_TRUSTED_DOMAINS=${stateDir}/web-ui/OidcTrustedDomains.js
|
||||
mv "$MAIN_JS" "$MAIN_JS".copy
|
||||
envsubst '$USE_AUTH0 $AUTH_AUTHORITY $AUTH_CLIENT_ID $AUTH_CLIENT_SECRET $AUTH_SUPPORTED_SCOPES $AUTH_AUDIENCE $NETBIRD_MGMT_API_ENDPOINT $NETBIRD_MGMT_GRPC_API_ENDPOINT $NETBIRD_HOTJAR_TRACK_ID $AUTH_REDIRECT_URI $AUTH_SILENT_REDIRECT_URI $NETBIRD_TOKEN_SOURCE $NETBIRD_DRAG_QUERY_PARAMS' < "$MAIN_JS".copy > "$MAIN_JS"
|
||||
envsubst '$NETBIRD_MGMT_API_ENDPOINT' < "$OIDC_TRUSTED_DOMAINS".tmpl > "$OIDC_TRUSTED_DOMAINS"
|
||||
'';
|
||||
};
|
||||
|
||||
netbird-signal = {
|
||||
after = [ "network.target" ];
|
||||
wantedBy = [ "netbird-management.service" ];
|
||||
restartTriggers = [ settingsFile managementFile ];
|
||||
restartTriggers = [
|
||||
settingsFile
|
||||
managementFile
|
||||
];
|
||||
|
||||
serviceConfig = {
|
||||
ExecStart = ''
|
||||
|
@ -487,24 +541,27 @@ in {
|
|||
netbird-management = {
|
||||
description = "The management server for Netbird, a wireguard VPN";
|
||||
documentation = [ "https://netbird.io/docs/" ];
|
||||
after = [ "network.target" "netbird-setup.service" ];
|
||||
after = [
|
||||
"network.target"
|
||||
"netbird-setup.service"
|
||||
];
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
wants = [ "netbird-signal.service" "netbird-setup.service" ];
|
||||
restartTriggers = [ settingsFile managementFile ];
|
||||
wants = [
|
||||
"netbird-signal.service"
|
||||
"netbird-setup.service"
|
||||
];
|
||||
restartTriggers = [
|
||||
settingsFile
|
||||
managementFile
|
||||
];
|
||||
|
||||
serviceConfig = {
|
||||
ExecStart = ''
|
||||
${cfg.package}/bin/netbird-mgmt management \
|
||||
--config ${stateDir}/management.json \
|
||||
--datadir ${stateDir}/data \
|
||||
${
|
||||
optionalString cfg.management.disableAnonymousMetrics
|
||||
"--disable-anonymous-metrics"
|
||||
} \
|
||||
${
|
||||
optionalString cfg.management.disableSingleAccountMode
|
||||
"--disable-single-account-mode"
|
||||
} \
|
||||
${optionalString cfg.management.disableAnonymousMetrics "--disable-anonymous-metrics"} \
|
||||
${optionalString cfg.management.disableSingleAccountMode "--disable-single-account-mode"} \
|
||||
--dns-domain ${cfg.management.dnsDomain} \
|
||||
--single-account-mode-domain ${cfg.management.singleAccountModeDomain} \
|
||||
--idp-sign-key-refresh-enabled \
|
||||
|
@ -514,7 +571,10 @@ in {
|
|||
'';
|
||||
Restart = "always";
|
||||
RuntimeDirectory = "netbird-mgmt";
|
||||
StateDirectory = [ "netbird-mgmt" "netbird-mgmt/data" ];
|
||||
StateDirectory = [
|
||||
"netbird-mgmt"
|
||||
"netbird-mgmt/data"
|
||||
];
|
||||
WorkingDirectory = stateDir;
|
||||
};
|
||||
unitConfig = {
|
||||
|
@ -549,18 +609,25 @@ in {
|
|||
5349
|
||||
5350
|
||||
];
|
||||
allowedTCPPorts = with settings; [ TURN_PORT (TURN_PORT + 1) ];
|
||||
allowedUDPPortRanges = [{
|
||||
from = settings.TURN_MIN_PORT;
|
||||
to = settings.TURN_MAX_PORT;
|
||||
}];
|
||||
allowedTCPPorts = with settings; [
|
||||
TURN_PORT
|
||||
(TURN_PORT + 1)
|
||||
];
|
||||
allowedUDPPortRanges = [
|
||||
{
|
||||
from = settings.TURN_MIN_PORT;
|
||||
to = settings.TURN_MAX_PORT;
|
||||
}
|
||||
];
|
||||
};
|
||||
})
|
||||
|
||||
(mkIf (cfg.enableNginx && cfg.enableCoturn) {
|
||||
services.coturn =
|
||||
let cert = config.security.acme.certs.${settings.TURN_DOMAIN};
|
||||
in {
|
||||
let
|
||||
cert = config.security.acme.certs.${settings.TURN_DOMAIN};
|
||||
in
|
||||
{
|
||||
cert = "${cert.directory}/fullchain.pem";
|
||||
pkey = "${cert.directory}/key.pem";
|
||||
};
|
||||
|
@ -570,8 +637,7 @@ in {
|
|||
# share certs with coturn and restart on renewal
|
||||
security.acme.certs.${settings.TURN_DOMAIN} = {
|
||||
group = "turnserver";
|
||||
postRun =
|
||||
"systemctl reload nginx.service; systemctl restart coturn.service";
|
||||
postRun = "systemctl reload nginx.service; systemctl restart coturn.service";
|
||||
};
|
||||
})
|
||||
];
|
||||
|
|
|
@ -1,4 +1,8 @@
|
|||
{ lib, buildNpmPackage, fetchFromGitHub }:
|
||||
{
|
||||
lib,
|
||||
buildNpmPackage,
|
||||
fetchFromGitHub,
|
||||
}:
|
||||
|
||||
buildNpmPackage rec {
|
||||
pname = "netbird-dashboard";
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
{ pkgs ? import <nixpkgs> {} }:
|
||||
{
|
||||
pkgs ? import <nixpkgs> { },
|
||||
}:
|
||||
|
||||
{
|
||||
dashboard = pkgs.callPackage ./dashboard.nix { };
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
{ config, ... }:
|
||||
|
||||
let host = "videos.dgnum.eu";
|
||||
in {
|
||||
let
|
||||
host = "videos.dgnum.eu";
|
||||
in
|
||||
{
|
||||
services.peertube = {
|
||||
enable = true;
|
||||
|
||||
|
@ -53,8 +55,7 @@ in {
|
|||
database.createLocally = true;
|
||||
|
||||
smtp.passwordFile = config.age.secrets."peertube-smtp_password_file".path;
|
||||
serviceEnvironmentFile =
|
||||
config.age.secrets."peertube-service_environment_file".path;
|
||||
serviceEnvironmentFile = config.age.secrets."peertube-service_environment_file".path;
|
||||
secrets.secretsFile = config.age.secrets."peertube-secrets_file".path;
|
||||
};
|
||||
|
||||
|
@ -63,5 +64,7 @@ in {
|
|||
forceSSL = true;
|
||||
};
|
||||
|
||||
age-secrets.matches."^peertube-.*$" = { owner = "peertube"; };
|
||||
age-secrets.matches."^peertube-.*$" = {
|
||||
owner = "peertube";
|
||||
};
|
||||
}
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
let
|
||||
lib = import ../../../lib { };
|
||||
publicKeys = lib.getNodeKeys "storage01";
|
||||
|
||||
in lib.setDefault { inherit publicKeys; } [
|
||||
in
|
||||
lib.setDefault { inherit publicKeys; } [
|
||||
"atticd-credentials_file"
|
||||
"forgejo-database_password_file"
|
||||
"forgejo_runners-token_file"
|
||||
|
|
|
@ -11,8 +11,10 @@ lib.extra.mkConfig {
|
|||
];
|
||||
|
||||
extraConfig = {
|
||||
dgn-fail2ban.jails =
|
||||
lib.extra.enableAttrs' "enabled" [ "sshd-bruteforce" "sshd-timeout" ];
|
||||
dgn-fail2ban.jails = lib.extra.enableAttrs' "enabled" [
|
||||
"sshd-bruteforce"
|
||||
"sshd-timeout"
|
||||
];
|
||||
|
||||
services.netbird.enable = true;
|
||||
|
||||
|
|
|
@ -8,8 +8,14 @@
|
|||
|
||||
boot = {
|
||||
initrd = {
|
||||
availableKernelModules =
|
||||
[ "xhci_pci" "megaraid_sas" "ehci_pci" "ahci" "usb_storage" "sd_mod" ];
|
||||
availableKernelModules = [
|
||||
"xhci_pci"
|
||||
"megaraid_sas"
|
||||
"ehci_pci"
|
||||
"ahci"
|
||||
"usb_storage"
|
||||
"sd_mod"
|
||||
];
|
||||
kernelModules = [ ];
|
||||
};
|
||||
|
||||
|
@ -30,6 +36,5 @@
|
|||
};
|
||||
};
|
||||
|
||||
swapDevices =
|
||||
[{ device = "/dev/disk/by-uuid/954ecb9c-ccd1-4e98-9eb6-3514bd3c01d1"; }];
|
||||
swapDevices = [ { device = "/dev/disk/by-uuid/954ecb9c-ccd1-4e98-9eb6-3514bd3c01d1"; } ];
|
||||
}
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
let
|
||||
lib = import ../../../lib { };
|
||||
publicKeys = lib.getNodeKeys "vault01";
|
||||
|
||||
in lib.setDefault { inherit publicKeys; } [
|
||||
]
|
||||
in
|
||||
lib.setDefault { inherit publicKeys; } [ ]
|
||||
|
|
|
@ -6,7 +6,12 @@
|
|||
{
|
||||
imports = [
|
||||
(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
|
||||
];
|
||||
}
|
||||
|
|
|
@ -3,31 +3,31 @@ let
|
|||
cfg = config.services.castopod;
|
||||
fpm = config.services.phpfpm.pools.castopod;
|
||||
in
|
||||
{
|
||||
{
|
||||
services.nginx = {
|
||||
resolver.addresses = [ "127.0.0.53" ];
|
||||
virtualHosts."${cfg.localDomain}" = {
|
||||
resolver.addresses = [ "127.0.0.53" ];
|
||||
virtualHosts."${cfg.localDomain}" = {
|
||||
|
||||
locations."@force_get" = {
|
||||
extraConfig = lib.mkForce ''
|
||||
recursive_error_pages on;
|
||||
proxy_method GET;
|
||||
proxy_pass https://podcasts.dgnum.eu/$request_uri;
|
||||
'';
|
||||
};
|
||||
locations."@force_get" = {
|
||||
extraConfig = lib.mkForce ''
|
||||
recursive_error_pages on;
|
||||
proxy_method GET;
|
||||
proxy_pass https://podcasts.dgnum.eu/$request_uri;
|
||||
'';
|
||||
};
|
||||
|
||||
locations."~ \.php$" = {
|
||||
extraConfig = lib.mkForce ''
|
||||
error_page 550 = @force_get;
|
||||
if ($request_method = HEAD) { return 550; }
|
||||
fastcgi_intercept_errors on;
|
||||
fastcgi_index index.php;
|
||||
fastcgi_pass unix:${fpm.socket};
|
||||
try_files $uri =404;
|
||||
fastcgi_read_timeout 3600;
|
||||
fastcgi_send_timeout 3600;
|
||||
'';
|
||||
};
|
||||
locations."~ .php$" = {
|
||||
extraConfig = lib.mkForce ''
|
||||
error_page 550 = @force_get;
|
||||
if ($request_method = HEAD) { return 550; }
|
||||
fastcgi_intercept_errors on;
|
||||
fastcgi_index index.php;
|
||||
fastcgi_pass unix:${fpm.socket};
|
||||
try_files $uri =404;
|
||||
fastcgi_read_timeout 3600;
|
||||
fastcgi_send_timeout 3600;
|
||||
'';
|
||||
};
|
||||
};
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
|
@ -1,38 +1,41 @@
|
|||
{ config, pkgs, ...}:
|
||||
{ config, pkgs, ... }:
|
||||
let
|
||||
host = "podcasts.dgnum.eu";
|
||||
in
|
||||
{
|
||||
imports = [
|
||||
./castopod-head-proxy.nix
|
||||
];
|
||||
services.castopod = {
|
||||
enable = true;
|
||||
localDomain = host;
|
||||
environmentFile = config.age.secrets.castopod-environment_file.path;
|
||||
maxUploadSize = 512;
|
||||
settings = {
|
||||
"email.fromEmail"="noreply@infra.dgnum.eu";
|
||||
"email.SMTPHost"="kurisu.lahfa.xyz";
|
||||
"email.SMTPUser"="web-services@infra.dgnum.eu";
|
||||
"email.SMTPPort"="587";
|
||||
imports = [ ./castopod-head-proxy.nix ];
|
||||
|
||||
"media.fileManager"="s3";
|
||||
"media.s3.endpoint"="https://s3.dgnum.eu/";
|
||||
"media.s3.region"="garage";
|
||||
"media.s3.bucket"="castopod-dgnum";
|
||||
"media.s3.pathStyleEndpoint"=true;
|
||||
services = {
|
||||
castopod = {
|
||||
enable = true;
|
||||
localDomain = host;
|
||||
environmentFile = config.age.secrets.castopod-environment_file.path;
|
||||
maxUploadSize = 512;
|
||||
settings = {
|
||||
"email.fromEmail" = "noreply@infra.dgnum.eu";
|
||||
"email.SMTPHost" = "kurisu.lahfa.xyz";
|
||||
"email.SMTPUser" = "web-services@infra.dgnum.eu";
|
||||
"email.SMTPPort" = "587";
|
||||
|
||||
"restapi.enabled"=true;
|
||||
"restapi.basicAuthUsername"="castopod";
|
||||
"restapi.basicAuth"=true;
|
||||
"media.fileManager" = "s3";
|
||||
"media.s3.endpoint" = "https://s3.dgnum.eu/";
|
||||
"media.s3.region" = "garage";
|
||||
"media.s3.bucket" = "castopod-dgnum";
|
||||
"media.s3.pathStyleEndpoint" = true;
|
||||
|
||||
"restapi.enabled" = true;
|
||||
"restapi.basicAuthUsername" = "castopod";
|
||||
"restapi.basicAuth" = true;
|
||||
};
|
||||
database.createLocally = true;
|
||||
configureNginx = true;
|
||||
};
|
||||
|
||||
mysql.package = pkgs.mariadb;
|
||||
|
||||
nginx.virtualHosts.${host} = {
|
||||
forceSSL = true;
|
||||
enableACME = true;
|
||||
};
|
||||
database.createLocally = true;
|
||||
configureNginx = true;
|
||||
};
|
||||
services.mysql.package = pkgs.mariadb;
|
||||
services.nginx.virtualHosts.${host} = {
|
||||
forceSSL = true;
|
||||
enableACME = true;
|
||||
};
|
||||
}
|
||||
|
|
|
@ -56,7 +56,10 @@ in
|
|||
mountpoint = "/var/log";
|
||||
};
|
||||
"/nix" = {
|
||||
mountOptions = [ "noatime" "compress=zstd" ];
|
||||
mountOptions = [
|
||||
"noatime"
|
||||
"compress=zstd"
|
||||
];
|
||||
mountpoint = "/nix";
|
||||
};
|
||||
};
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
{ ... }:
|
||||
{
|
||||
_: {
|
||||
services.dolibarr = {
|
||||
enable = true;
|
||||
domain = "erp.dgnum.eu";
|
||||
|
|
|
@ -1,4 +1,9 @@
|
|||
{ sources, pkgs, lib, ... }:
|
||||
{
|
||||
sources,
|
||||
pkgs,
|
||||
lib,
|
||||
...
|
||||
}:
|
||||
|
||||
let
|
||||
host = "cal.dgnum.eu";
|
||||
|
@ -26,7 +31,8 @@ let
|
|||
calendars = metis2linkal sources.metis;
|
||||
};
|
||||
};
|
||||
in {
|
||||
in
|
||||
{
|
||||
imports = [ ./module.nix ];
|
||||
|
||||
dgn-linkal = {
|
||||
|
|
|
@ -7,18 +7,10 @@ let
|
|||
inherit (import source { inherit pkgs; }) providers;
|
||||
|
||||
# helper function to map 2-level deep attribute-sets
|
||||
mapDeepAttrs = mapFct:
|
||||
lib.concatMapAttrs (name: value:
|
||||
lib.mapAttrs' (name': value':
|
||||
mapFct name name' value'
|
||||
) value
|
||||
);
|
||||
|
||||
|
||||
toLinkal = upstream: identifier:
|
||||
lib.nameValuePair
|
||||
"${providers.${upstream}}${identifier}"
|
||||
;
|
||||
mapDeepAttrs =
|
||||
mapFct:
|
||||
lib.concatMapAttrs (name: value: lib.mapAttrs' (name': value': mapFct name name' value') value);
|
||||
|
||||
toLinkal = upstream: identifier: lib.nameValuePair "${providers.${upstream}}${identifier}";
|
||||
in
|
||||
mapDeepAttrs toLinkal calendars
|
||||
mapDeepAttrs toLinkal calendars
|
||||
|
|
|
@ -1,14 +1,28 @@
|
|||
{ config, lib, pkgs, sources, ... }:
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
sources,
|
||||
...
|
||||
}:
|
||||
|
||||
let
|
||||
inherit (lib) mapAttrs' mkEnableOption mkIf mkOption nameValuePair types;
|
||||
inherit (lib)
|
||||
mapAttrs'
|
||||
mkEnableOption
|
||||
mkIf
|
||||
mkOption
|
||||
nameValuePair
|
||||
types
|
||||
;
|
||||
|
||||
package = import sources.linkal { inherit pkgs; };
|
||||
|
||||
cfg = config.dgn-linkal;
|
||||
|
||||
jsonFormat = pkgs.formats.json { };
|
||||
in {
|
||||
in
|
||||
{
|
||||
options.dgn-linkal = {
|
||||
enable = mkEnableOption "the linkal server.";
|
||||
|
||||
|
@ -20,32 +34,40 @@ in {
|
|||
domain = mkOption { type = types.str; };
|
||||
|
||||
calendarGroups = mkOption {
|
||||
type = let inherit (types) attrsOf port submodule;
|
||||
in attrsOf (submodule {
|
||||
options = {
|
||||
port = mkOption { type = port; };
|
||||
calendars = mkOption { inherit (jsonFormat) type; };
|
||||
};
|
||||
});
|
||||
type =
|
||||
let
|
||||
inherit (types) attrsOf port submodule;
|
||||
in
|
||||
attrsOf (
|
||||
submodule {
|
||||
options = {
|
||||
port = mkOption { type = port; };
|
||||
calendars = mkOption { inherit (jsonFormat) type; };
|
||||
};
|
||||
}
|
||||
);
|
||||
default = { };
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
systemd.services = mapAttrs' (name:
|
||||
{ port, calendars }:
|
||||
nameValuePair "linkal-${name}" {
|
||||
description = "Linkal - ${name}";
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
serviceConfig = {
|
||||
Type = "simple";
|
||||
ExecStart = "${cfg.package}/bin/linkal --port ${
|
||||
builtins.toString port
|
||||
} --calendar-file ${
|
||||
jsonFormat.generate "linkal-${name}.json" { inherit calendars; }
|
||||
}";
|
||||
};
|
||||
}) cfg.calendarGroups;
|
||||
systemd.services =
|
||||
mapAttrs'
|
||||
(
|
||||
name:
|
||||
{ port, calendars }:
|
||||
nameValuePair "linkal-${name}" {
|
||||
description = "Linkal - ${name}";
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
serviceConfig = {
|
||||
Type = "simple";
|
||||
ExecStart = "${cfg.package}/bin/linkal --port ${builtins.toString port} --calendar-file ${
|
||||
jsonFormat.generate "linkal-${name}.json" { inherit calendars; }
|
||||
}";
|
||||
};
|
||||
}
|
||||
)
|
||||
cfg.calendarGroups;
|
||||
|
||||
# Configure bind for DNS certificate validation on *.cal.dgnum.eu.
|
||||
# services.bind = {
|
||||
|
@ -85,16 +107,20 @@ in {
|
|||
services.nginx = {
|
||||
enable = true;
|
||||
|
||||
virtualHosts = mapAttrs' (name:
|
||||
{ port, ... }:
|
||||
nameValuePair "${name}.${cfg.domain}" {
|
||||
enableACME = true;
|
||||
# acmeRoot = null; # Use DNS-01 validation
|
||||
forceSSL = true;
|
||||
virtualHosts =
|
||||
mapAttrs'
|
||||
(
|
||||
name:
|
||||
{ port, ... }:
|
||||
nameValuePair "${name}.${cfg.domain}" {
|
||||
enableACME = true;
|
||||
# acmeRoot = null; # Use DNS-01 validation
|
||||
forceSSL = true;
|
||||
|
||||
locations."/".proxyPass =
|
||||
"http://127.0.0.1:${builtins.toString port}/";
|
||||
}) cfg.calendarGroups;
|
||||
locations."/".proxyPass = "http://127.0.0.1:${builtins.toString port}/";
|
||||
}
|
||||
)
|
||||
cfg.calendarGroups;
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
|
@ -6,5 +6,7 @@
|
|||
configPath = config.age.secrets."matterbridge-config_file".path;
|
||||
};
|
||||
|
||||
age-secrets.matches."^matterbridge-.*$" = { owner = "matterbridge"; };
|
||||
age-secrets.matches."^matterbridge-.*$" = {
|
||||
owner = "matterbridge";
|
||||
};
|
||||
}
|
||||
|
|
|
@ -1,24 +1,35 @@
|
|||
{ lib, pkgs, sources, ... }:
|
||||
{
|
||||
lib,
|
||||
pkgs,
|
||||
sources,
|
||||
...
|
||||
}:
|
||||
|
||||
let
|
||||
metis = import sources.metis { inherit pkgs; };
|
||||
|
||||
inherit (metis) providers;
|
||||
in {
|
||||
in
|
||||
{
|
||||
services.nginx.virtualHosts."calendrier.dgnum.eu" = {
|
||||
enableACME = true;
|
||||
forceSSL = true;
|
||||
root = metis.production;
|
||||
|
||||
locations = lib.mapAttrs' (name: value:
|
||||
lib.nameValuePair "/cal/${name}/" {
|
||||
extraConfig = ''
|
||||
proxy_set_header X-Forwarded-Host $host;
|
||||
proxy_set_header X-Forwarded-Server $host;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_pass ${value};
|
||||
'';
|
||||
}) providers;
|
||||
locations =
|
||||
lib.mapAttrs'
|
||||
(
|
||||
name: value:
|
||||
lib.nameValuePair "/cal/${name}/" {
|
||||
extraConfig = ''
|
||||
proxy_set_header X-Forwarded-Host $host;
|
||||
proxy_set_header X-Forwarded-Server $host;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_pass ${value};
|
||||
'';
|
||||
}
|
||||
)
|
||||
providers;
|
||||
|
||||
extraConfig = ''
|
||||
rewrite ^/calendrier(.*)$ $1 permanent;
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
{ config, ... }:
|
||||
|
||||
let host = "push.dgnum.eu";
|
||||
|
||||
in {
|
||||
let
|
||||
host = "push.dgnum.eu";
|
||||
in
|
||||
{
|
||||
services.ntfy-sh = {
|
||||
enable = true;
|
||||
|
||||
|
@ -26,6 +27,7 @@ in {
|
|||
};
|
||||
};
|
||||
|
||||
systemd.services.ntfy-sh.serviceConfig.EnvironmentFile =
|
||||
[ config.age.secrets."ntfy_sh-environment_file".path ];
|
||||
systemd.services.ntfy-sh.serviceConfig.EnvironmentFile = [
|
||||
config.age.secrets."ntfy_sh-environment_file".path
|
||||
];
|
||||
}
|
||||
|
|
|
@ -3,15 +3,19 @@ _:
|
|||
let
|
||||
retired_host = "retired.dgnum.eu";
|
||||
|
||||
mkRetired = hosts:
|
||||
builtins.listToAttrs (builtins.map (name: {
|
||||
inherit name;
|
||||
value.to = retired_host;
|
||||
}) hosts);
|
||||
mkRetired =
|
||||
hosts:
|
||||
builtins.listToAttrs (
|
||||
builtins.map
|
||||
(name: {
|
||||
inherit name;
|
||||
value.to = retired_host;
|
||||
})
|
||||
hosts
|
||||
);
|
||||
|
||||
mkSub = domain: builtins.map (s: "${s}.${domain}");
|
||||
mkSubs = attrs:
|
||||
builtins.concatLists (builtins.attrValues (builtins.mapAttrs mkSub attrs));
|
||||
mkSubs = attrs: builtins.concatLists (builtins.attrValues (builtins.mapAttrs mkSub attrs));
|
||||
|
||||
redirections = {
|
||||
"calendrier.eleves.ens.fr".to = "calendrier.dgnum.eu";
|
||||
|
@ -23,9 +27,15 @@ let
|
|||
} // (mkRetired retired);
|
||||
|
||||
retired = mkSubs {
|
||||
"ens.fr" = [ "alevins" "www.climatenavigator" ];
|
||||
"ens.fr" = [
|
||||
"alevins"
|
||||
"www.climatenavigator"
|
||||
];
|
||||
"ens.wtf" = [ "photos" ];
|
||||
"rz.ens.wtf" = [ "s3" "cdn" ];
|
||||
"rz.ens.wtf" = [
|
||||
"s3"
|
||||
"cdn"
|
||||
];
|
||||
"beta.rz.ens.wtf" = [
|
||||
"todo"
|
||||
"minecraft"
|
||||
|
@ -39,14 +49,25 @@ let
|
|||
"rstudio"
|
||||
];
|
||||
};
|
||||
|
||||
in {
|
||||
services.nginx.virtualHosts = {
|
||||
${retired_host}.default = true;
|
||||
} // (builtins.mapAttrs (host:
|
||||
{ to, ssl ? true }: {
|
||||
globalRedirect = to;
|
||||
enableACME = ssl;
|
||||
forceSSL = ssl;
|
||||
}) redirections);
|
||||
in
|
||||
{
|
||||
services.nginx.virtualHosts =
|
||||
{
|
||||
${retired_host}.default = true;
|
||||
}
|
||||
// (builtins.mapAttrs
|
||||
(
|
||||
_:
|
||||
{
|
||||
to,
|
||||
ssl ? true,
|
||||
}:
|
||||
{
|
||||
globalRedirect = to;
|
||||
enableACME = ssl;
|
||||
forceSSL = ssl;
|
||||
}
|
||||
)
|
||||
redirections
|
||||
);
|
||||
}
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
let
|
||||
lib = import ../../../lib { };
|
||||
publicKeys = lib.getNodeKeys "web01";
|
||||
in lib.setDefault { inherit publicKeys; } [
|
||||
in
|
||||
lib.setDefault { inherit publicKeys; } [
|
||||
"acme-certs_secret"
|
||||
"matterbridge-config_file"
|
||||
"named-bind_dnskeys_conf"
|
||||
|
|
|
@ -1,20 +1,34 @@
|
|||
# Generated by npins. Do not modify; will be overwritten regularly
|
||||
let
|
||||
data = builtins.fromJSON (builtins.readFile ./sources.json);
|
||||
version = data.version;
|
||||
inherit (data) version;
|
||||
|
||||
mkSource = spec:
|
||||
assert spec ? type; let
|
||||
mkSource =
|
||||
spec:
|
||||
assert spec ? type;
|
||||
let
|
||||
path =
|
||||
if spec.type == "Git" then mkGitSource spec
|
||||
else if spec.type == "GitRelease" then mkGitSource spec
|
||||
else if spec.type == "PyPi" then mkPyPiSource spec
|
||||
else if spec.type == "Channel" then mkChannelSource spec
|
||||
else builtins.throw "Unknown source type ${spec.type}";
|
||||
if spec.type == "Git" then
|
||||
mkGitSource spec
|
||||
else if spec.type == "GitRelease" then
|
||||
mkGitSource spec
|
||||
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
|
||||
spec // { outPath = path; };
|
||||
|
||||
mkGitSource = { repository, revision, url ? null, hash, ... }:
|
||||
mkGitSource =
|
||||
{
|
||||
repository,
|
||||
revision,
|
||||
url ? null,
|
||||
hash,
|
||||
...
|
||||
}:
|
||||
assert repository ? type;
|
||||
# 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
|
||||
|
@ -23,19 +37,23 @@ let
|
|||
inherit url;
|
||||
sha256 = hash; # FIXME: check nix version & use SRI hashes
|
||||
})
|
||||
else assert repository.type == "Git"; builtins.fetchGit {
|
||||
url = repository.url;
|
||||
rev = revision;
|
||||
# hash = hash;
|
||||
};
|
||||
else
|
||||
assert repository.type == "Git";
|
||||
builtins.fetchGit {
|
||||
inherit (repository) url;
|
||||
rev = revision;
|
||||
# hash = hash;
|
||||
};
|
||||
|
||||
mkPyPiSource = { url, hash, ... }:
|
||||
mkPyPiSource =
|
||||
{ url, hash, ... }:
|
||||
builtins.fetchurl {
|
||||
inherit url;
|
||||
sha256 = hash;
|
||||
};
|
||||
|
||||
mkChannelSource = { url, hash, ... }:
|
||||
mkChannelSource =
|
||||
{ url, hash, ... }:
|
||||
builtins.fetchTarball {
|
||||
inherit url;
|
||||
sha256 = hash;
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
{ pkgs, sources, ... }:
|
||||
|
||||
let wp4nix = pkgs.callPackage sources.wp4nix { };
|
||||
in {
|
||||
let
|
||||
wp4nix = pkgs.callPackage sources.wp4nix { };
|
||||
in
|
||||
{
|
||||
imports = [ ./module.nix ];
|
||||
|
||||
services.wp-containers = {
|
||||
|
@ -9,26 +11,38 @@ in {
|
|||
|
||||
sites = {
|
||||
"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 ];
|
||||
};
|
||||
|
||||
"bds.wp.dgnum.eu" = {
|
||||
plugins = { inherit (wp4nix.plugins) user-role-editor; };
|
||||
plugins = {
|
||||
inherit (wp4nix.plugins) user-role-editor;
|
||||
};
|
||||
languages = [ pkgs.wordpressPackages.languages.fr_FR ];
|
||||
themes = { inherit (wp4nix.themes) gateway twentytwentythree; };
|
||||
themes = {
|
||||
inherit (wp4nix.themes) gateway twentytwentythree;
|
||||
};
|
||||
};
|
||||
|
||||
"bda.wp.dgnum.eu" = {
|
||||
plugins = { inherit (wp4nix.plugins) user-role-editor; };
|
||||
plugins = {
|
||||
inherit (wp4nix.plugins) user-role-editor;
|
||||
};
|
||||
languages = [ pkgs.wordpressPackages.languages.fr_FR ];
|
||||
};
|
||||
|
||||
"cineclub.wp.dgnum.eu" = {
|
||||
plugins = { inherit (wp4nix.plugins) user-role-editor; };
|
||||
plugins = {
|
||||
inherit (wp4nix.plugins) user-role-editor;
|
||||
};
|
||||
languages = [ pkgs.wordpressPackages.languages.fr_FR ];
|
||||
};
|
||||
};
|
||||
|
|
|
@ -1,4 +1,9 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
|
||||
let
|
||||
inherit (lib) mkEnableOption mkIf mkOption;
|
||||
|
@ -13,41 +18,52 @@ let
|
|||
mkHost = mkIp "10.31.41";
|
||||
mkLocal = mkIp "10.0.0";
|
||||
|
||||
mkConfig = { name, value, i }: {
|
||||
services.wordpress = {
|
||||
webserver = "nginx";
|
||||
sites.${name} = value;
|
||||
mkConfig =
|
||||
{
|
||||
name,
|
||||
value,
|
||||
i,
|
||||
}:
|
||||
{
|
||||
services.wordpress = {
|
||||
webserver = "nginx";
|
||||
sites.${name} = value;
|
||||
};
|
||||
|
||||
services.nginx.virtualHosts.${name} = {
|
||||
onlySSL = true;
|
||||
sslCertificate = "${certs.${name}.directory}/fullchain.pem";
|
||||
sslCertificateKey = "${certs.${name}.directory}/key.pem";
|
||||
sslTrustedCertificate = "${certs.${name}.directory}/chain.pem";
|
||||
};
|
||||
|
||||
networking = {
|
||||
hostName = mkName name;
|
||||
hosts.${mkLocal i} = [ name ];
|
||||
|
||||
firewall.allowedTCPPorts = [ 443 ];
|
||||
};
|
||||
|
||||
environment.systemPackages = [
|
||||
pkgs.wp-cli
|
||||
pkgs.neovim
|
||||
];
|
||||
|
||||
system.stateVersion = "23.11";
|
||||
};
|
||||
|
||||
services.nginx.virtualHosts.${name} = {
|
||||
onlySSL = true;
|
||||
sslCertificate = "${certs.${name}.directory}/fullchain.pem";
|
||||
sslCertificateKey = "${certs.${name}.directory}/key.pem";
|
||||
sslTrustedCertificate = "${certs.${name}.directory}/chain.pem";
|
||||
};
|
||||
|
||||
networking = {
|
||||
hostName = mkName name;
|
||||
hosts.${mkLocal i} = [ name ];
|
||||
|
||||
firewall.allowedTCPPorts = [ 443 ];
|
||||
};
|
||||
|
||||
environment.systemPackages = [ pkgs.wp-cli pkgs.neovim ];
|
||||
|
||||
system.stateVersion = "23.11";
|
||||
};
|
||||
|
||||
mkContainer = i: site: {
|
||||
name = mkName site.name;
|
||||
|
||||
value = {
|
||||
privateNetwork = true;
|
||||
|
||||
forwardPorts = [{
|
||||
containerPort = 443;
|
||||
hostPort = cfg.basePort + i;
|
||||
}];
|
||||
forwardPorts = [
|
||||
{
|
||||
containerPort = 443;
|
||||
hostPort = cfg.basePort + i;
|
||||
}
|
||||
];
|
||||
|
||||
bindMounts.certs = {
|
||||
hostPath = certs.${site.name}.directory;
|
||||
|
@ -69,13 +85,13 @@ let
|
|||
enableACME = true;
|
||||
forceSSL = true;
|
||||
|
||||
locations."/".proxyPass =
|
||||
"https://${mkHost i}:${builtins.toString (cfg.basePort + i)}";
|
||||
locations."/".proxyPass = "https://${mkHost i}:${builtins.toString (cfg.basePort + i)}";
|
||||
};
|
||||
};
|
||||
|
||||
siteList = lib.attrsToList cfg.sites;
|
||||
in {
|
||||
in
|
||||
{
|
||||
options.services.wp-containers = {
|
||||
enable = mkEnableOption "wordpress sites in containers";
|
||||
|
||||
|
@ -93,7 +109,6 @@ in {
|
|||
config = mkIf cfg.enable {
|
||||
containers = builtins.listToAttrs (lib.imap1 mkContainer siteList);
|
||||
|
||||
services.nginx.virtualHosts =
|
||||
builtins.listToAttrs (lib.imap1 mkVhost siteList);
|
||||
services.nginx.virtualHosts = builtins.listToAttrs (lib.imap1 mkVhost siteList);
|
||||
};
|
||||
}
|
||||
|
|
|
@ -11,8 +11,10 @@ lib.extra.mkConfig {
|
|||
];
|
||||
|
||||
extraConfig = {
|
||||
dgn-fail2ban.jails =
|
||||
lib.extra.enableAttrs' "enabled" [ "sshd-bruteforce" "sshd-timeout" ];
|
||||
dgn-fail2ban.jails = lib.extra.enableAttrs' "enabled" [
|
||||
"sshd-bruteforce"
|
||||
"sshd-timeout"
|
||||
];
|
||||
|
||||
services.netbird.enable = true;
|
||||
};
|
||||
|
|
|
@ -8,8 +8,14 @@
|
|||
|
||||
boot = {
|
||||
initrd = {
|
||||
availableKernelModules =
|
||||
[ "ata_piix" "uhci_hcd" "ehci_pci" "virtio_pci" "sr_mod" "virtio_blk" ];
|
||||
availableKernelModules = [
|
||||
"ata_piix"
|
||||
"uhci_hcd"
|
||||
"ehci_pci"
|
||||
"virtio_pci"
|
||||
"sr_mod"
|
||||
"virtio_blk"
|
||||
];
|
||||
kernelModules = [ ];
|
||||
};
|
||||
|
||||
|
@ -30,6 +36,5 @@
|
|||
};
|
||||
};
|
||||
|
||||
swapDevices =
|
||||
[{ device = "/dev/disk/by-uuid/d64ae21e-693c-4c77-b62c-97d5e2a960cb"; }];
|
||||
swapDevices = [ { device = "/dev/disk/by-uuid/d64ae21e-693c-4c77-b62c-97d5e2a960cb"; } ];
|
||||
}
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
let
|
||||
lib = import ../../../lib { };
|
||||
publicKeys = lib.getNodeKeys "web02";
|
||||
|
||||
in lib.setDefault { inherit publicKeys; } [
|
||||
]
|
||||
in
|
||||
lib.setDefault { inherit publicKeys; } [ ]
|
||||
|
|
|
@ -8,9 +8,7 @@
|
|||
];
|
||||
|
||||
# Jourdan
|
||||
par02 = [
|
||||
"vault01"
|
||||
];
|
||||
par02 = [ "vault01" ];
|
||||
|
||||
# VMs du SPI/NPS/Whatever
|
||||
dmi01 = [
|
||||
|
|
|
@ -26,15 +26,25 @@ let
|
|||
|
||||
groups = {
|
||||
# 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
|
||||
iso = [ "thubrecht" "mdebray" "raito" ];
|
||||
iso = [
|
||||
"thubrecht"
|
||||
"mdebray"
|
||||
"raito"
|
||||
];
|
||||
|
||||
# members of this group can access netbox's secret
|
||||
netbox = [];
|
||||
netbox = [ ];
|
||||
|
||||
bureau = [ "gdd" ];
|
||||
};
|
||||
|
||||
in { inherit groups members; }
|
||||
in
|
||||
{
|
||||
inherit groups members;
|
||||
}
|
||||
|
|
|
@ -1,27 +1,47 @@
|
|||
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};
|
||||
|
||||
filterIPv4 = ip: builtins.substring 0 7 ip != "192.168";
|
||||
filterIPv6 = _: true;
|
||||
|
||||
mkNet = _: value:
|
||||
let base = mkBase value; in
|
||||
base // {
|
||||
mkNet =
|
||||
_: value:
|
||||
let
|
||||
base = mkBase value;
|
||||
in
|
||||
base
|
||||
// {
|
||||
addresses =
|
||||
let
|
||||
_addresses = builtins.foldl'
|
||||
({ ipv4, ipv6 }: net: {
|
||||
ipv4 = ipv4 ++ getAddresses "ipv4" net;
|
||||
ipv6 = ipv6 ++ getAddresses "ipv6" net;
|
||||
})
|
||||
{ ipv4 = [ ]; ipv6 = [ ]; }
|
||||
(builtins.attrValues base.interfaces);
|
||||
_addresses =
|
||||
builtins.foldl'
|
||||
(
|
||||
{ ipv4, ipv6 }:
|
||||
net: {
|
||||
ipv4 = ipv4 ++ getAddresses "ipv4" net;
|
||||
ipv6 = ipv6 ++ getAddresses "ipv6" net;
|
||||
}
|
||||
)
|
||||
{
|
||||
ipv4 = [ ];
|
||||
ipv6 = [ ];
|
||||
}
|
||||
(builtins.attrValues base.interfaces);
|
||||
in
|
||||
_addresses // rec {
|
||||
_addresses
|
||||
// rec {
|
||||
publicV4 = builtins.filter filterIPv4 _addresses.ipv4;
|
||||
publicV6 = builtins.filter filterIPv6 _addresses.ipv6;
|
||||
public = publicV4 ++ publicV6;
|
||||
|
@ -34,8 +54,14 @@ builtins.mapAttrs mkNet {
|
|||
interfaces = {
|
||||
eno1 = {
|
||||
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" ];
|
||||
|
@ -49,8 +75,14 @@ builtins.mapAttrs mkNet {
|
|||
interfaces = {
|
||||
eno1 = {
|
||||
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" ];
|
||||
|
@ -64,7 +96,10 @@ builtins.mapAttrs mkNet {
|
|||
interfaces = {
|
||||
enp130s0f0 = {
|
||||
ipv4 = [
|
||||
{ address = "129.199.210.85"; prefixLength = 24; }
|
||||
{
|
||||
address = "129.199.210.85";
|
||||
prefixLength = 24;
|
||||
}
|
||||
];
|
||||
|
||||
gateways = [ "129.199.210.254" ];
|
||||
|
@ -77,7 +112,12 @@ builtins.mapAttrs mkNet {
|
|||
web01 = {
|
||||
interfaces = {
|
||||
ens3 = {
|
||||
ipv4 = [{ address = "129.199.129.53"; prefixLength = 24; }];
|
||||
ipv4 = [
|
||||
{
|
||||
address = "129.199.129.53";
|
||||
prefixLength = 24;
|
||||
}
|
||||
];
|
||||
|
||||
gateways = [ "129.199.129.1" ];
|
||||
};
|
||||
|
@ -89,7 +129,12 @@ builtins.mapAttrs mkNet {
|
|||
web02 = {
|
||||
interfaces = {
|
||||
ens3 = {
|
||||
ipv4 = [{ address = "129.199.129.235"; prefixLength = 24; }];
|
||||
ipv4 = [
|
||||
{
|
||||
address = "129.199.129.235";
|
||||
prefixLength = 24;
|
||||
}
|
||||
];
|
||||
|
||||
gateways = [ "129.199.129.1" ];
|
||||
};
|
||||
|
|
|
@ -11,14 +11,17 @@
|
|||
# }
|
||||
|
||||
let
|
||||
mkNode = _: attrs: {
|
||||
adminGroups = [ ];
|
||||
admins = [ ];
|
||||
mkNode =
|
||||
_: attrs:
|
||||
{
|
||||
adminGroups = [ ];
|
||||
admins = [ ];
|
||||
|
||||
deployment = { };
|
||||
deployment = { };
|
||||
|
||||
nixpkgs = "23.11";
|
||||
} // attrs;
|
||||
nixpkgs = "23.11";
|
||||
}
|
||||
// attrs;
|
||||
in
|
||||
|
||||
builtins.mapAttrs mkNode {
|
||||
|
|
|
@ -35,22 +35,25 @@
|
|||
{ lib, sources, ... }:
|
||||
|
||||
{
|
||||
imports = (lib.extra.mkImports ./. [
|
||||
"dgn-access-control"
|
||||
"dgn-acme"
|
||||
"dgn-console"
|
||||
"dgn-fail2ban"
|
||||
"dgn-hardware"
|
||||
"dgn-network"
|
||||
"dgn-ssh"
|
||||
"dgn-web"
|
||||
"dgn-vm-variant"
|
||||
]) ++ [
|
||||
"${sources.agenix}/modules/age.nix"
|
||||
"${sources.attic}/nixos/atticd.nix"
|
||||
] ++ ((import sources.nix-modules { inherit lib; }).importModules [
|
||||
"age-secrets"
|
||||
"services/crabfit"
|
||||
"services/forgejo-nix-runners"
|
||||
]);
|
||||
imports =
|
||||
(lib.extra.mkImports ./. [
|
||||
"dgn-access-control"
|
||||
"dgn-acme"
|
||||
"dgn-console"
|
||||
"dgn-fail2ban"
|
||||
"dgn-hardware"
|
||||
"dgn-network"
|
||||
"dgn-ssh"
|
||||
"dgn-web"
|
||||
"dgn-vm-variant"
|
||||
])
|
||||
++ [
|
||||
"${sources.agenix}/modules/age.nix"
|
||||
"${sources.attic}/nixos/atticd.nix"
|
||||
]
|
||||
++ ((import sources.nix-modules { inherit lib; }).importModules [
|
||||
"age-secrets"
|
||||
"services/crabfit"
|
||||
"services/forgejo-nix-runners"
|
||||
]);
|
||||
}
|
||||
|
|
|
@ -31,7 +31,13 @@
|
|||
# pris connaissance de la licence CeCILL, et que vous en avez accepté les
|
||||
# termes.
|
||||
|
||||
{ config, lib, meta, name, ... }:
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
meta,
|
||||
name,
|
||||
...
|
||||
}:
|
||||
|
||||
let
|
||||
inherit (lib)
|
||||
|
@ -40,10 +46,13 @@ let
|
|||
mkIf
|
||||
mkOption
|
||||
|
||||
types;
|
||||
types
|
||||
;
|
||||
|
||||
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);
|
||||
|
||||
cfg = config.dgn-access-control;
|
||||
|
@ -51,7 +60,9 @@ in
|
|||
|
||||
{
|
||||
options.dgn-access-control = {
|
||||
enable = mkEnableOption "DGNum access control." // { default = true; };
|
||||
enable = mkEnableOption "DGNum access control." // {
|
||||
default = true;
|
||||
};
|
||||
|
||||
users = mkOption {
|
||||
type = with types; attrsOf (listOf str);
|
||||
|
@ -72,8 +83,8 @@ in
|
|||
# Admins have root access to the node
|
||||
dgn-access-control.users.root = mkDefault admins;
|
||||
|
||||
users.users = builtins.mapAttrs
|
||||
(u: members: { openssh.authorizedKeys.keys = lib.extra.getAllKeys members; })
|
||||
cfg.users;
|
||||
users.users =
|
||||
builtins.mapAttrs (_: members: { openssh.authorizedKeys.keys = lib.extra.getAllKeys members; })
|
||||
cfg.users;
|
||||
};
|
||||
}
|
||||
|
|
|
@ -34,15 +34,15 @@
|
|||
{ config, lib, ... }:
|
||||
|
||||
let
|
||||
inherit (lib)
|
||||
mkEnableOption
|
||||
mkIf;
|
||||
inherit (lib) mkEnableOption mkIf;
|
||||
|
||||
cfg = config.dgn-acme;
|
||||
in
|
||||
|
||||
{
|
||||
options.dgn-acme.enable = mkEnableOption "ACME settings." // { default = true; };
|
||||
options.dgn-acme.enable = mkEnableOption "ACME settings." // {
|
||||
default = true;
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
security.acme = {
|
||||
|
|
|
@ -1,13 +1,20 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
|
||||
let
|
||||
inherit (lib) mkEnableOption mkOption mkIf;
|
||||
|
||||
cfg = config.dgn-console;
|
||||
|
||||
in {
|
||||
in
|
||||
{
|
||||
options.dgn-console = {
|
||||
enable = mkEnableOption "DGNum console setup." // { default = true; };
|
||||
enable = mkEnableOption "DGNum console setup." // {
|
||||
default = true;
|
||||
};
|
||||
|
||||
pg-upgrade-to = mkOption {
|
||||
type = lib.types.package;
|
||||
|
@ -18,7 +25,9 @@ in {
|
|||
config = mkIf cfg.enable {
|
||||
time.timeZone = "Europe/Paris";
|
||||
|
||||
console = { keyMap = "fr"; };
|
||||
console = {
|
||||
keyMap = "fr";
|
||||
};
|
||||
|
||||
environment.variables.EDITOR = "nvim";
|
||||
|
||||
|
@ -26,7 +35,7 @@ in {
|
|||
|
||||
# services.nscd.enableNsncd = false;
|
||||
nixpkgs.overlays = [
|
||||
(final: prev: {
|
||||
(_: _: {
|
||||
nsncd = pkgs.rustPlatform.buildRustPackage {
|
||||
pname = "nsncd";
|
||||
version = "unstable-2023-10-26";
|
||||
|
@ -70,29 +79,36 @@ in {
|
|||
|
||||
hardware.enableRedistributableFirmware = true;
|
||||
|
||||
environment.systemPackages = (with pkgs; [ neovim wget kitty.terminfo ])
|
||||
++ lib.optional (config.services.postgresql.enable
|
||||
&& config.services.postgresql.package != cfg.pg-upgrade-to)
|
||||
(pkgs.writeScriptBin "upgrade-pg-cluster" ''
|
||||
set -eux
|
||||
# XXX it's perhaps advisable to stop all services that depend on postgresql
|
||||
systemctl stop postgresql
|
||||
environment.systemPackages =
|
||||
(with pkgs; [
|
||||
neovim
|
||||
wget
|
||||
kitty.terminfo
|
||||
])
|
||||
++ lib.optional
|
||||
(config.services.postgresql.enable && config.services.postgresql.package != cfg.pg-upgrade-to)
|
||||
(
|
||||
pkgs.writeScriptBin "upgrade-pg-cluster" ''
|
||||
set -eux
|
||||
# XXX it's perhaps advisable to stop all services that depend on postgresql
|
||||
systemctl stop postgresql
|
||||
|
||||
export NEWDATA="/var/lib/postgresql/${cfg.pg-upgrade-to.psqlSchema}"
|
||||
export NEWDATA="/var/lib/postgresql/${cfg.pg-upgrade-to.psqlSchema}"
|
||||
|
||||
export NEWBIN="${cfg.pg-upgrade-to}/bin"
|
||||
export NEWBIN="${cfg.pg-upgrade-to}/bin"
|
||||
|
||||
export OLDDATA="${config.services.postgresql.dataDir}"
|
||||
export OLDBIN="${config.services.postgresql.package}/bin"
|
||||
export OLDDATA="${config.services.postgresql.dataDir}"
|
||||
export OLDBIN="${config.services.postgresql.package}/bin"
|
||||
|
||||
install -d -m 0700 -o postgres -g postgres "$NEWDATA"
|
||||
cd "$NEWDATA"
|
||||
sudo -u postgres $NEWBIN/initdb -D "$NEWDATA"
|
||||
install -d -m 0700 -o postgres -g postgres "$NEWDATA"
|
||||
cd "$NEWDATA"
|
||||
sudo -u postgres $NEWBIN/initdb -D "$NEWDATA"
|
||||
|
||||
sudo -u postgres $NEWBIN/pg_upgrade \
|
||||
--old-datadir "$OLDDATA" --new-datadir "$NEWDATA" \
|
||||
--old-bindir $OLDBIN --new-bindir $NEWBIN \
|
||||
"$@"
|
||||
'');
|
||||
sudo -u postgres $NEWBIN/pg_upgrade \
|
||||
--old-datadir "$OLDDATA" --new-datadir "$NEWDATA" \
|
||||
--old-bindir $OLDBIN --new-bindir $NEWBIN \
|
||||
"$@"
|
||||
''
|
||||
);
|
||||
};
|
||||
}
|
||||
|
|
|
@ -1,10 +1,19 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
|
||||
let
|
||||
inherit (lib)
|
||||
mkDefault mkEnableOption mkIf mkOption
|
||||
mkDefault
|
||||
mkEnableOption
|
||||
mkIf
|
||||
mkOption
|
||||
|
||||
types;
|
||||
types
|
||||
;
|
||||
|
||||
cfg = config.dgn-fail2ban;
|
||||
|
||||
|
@ -22,8 +31,7 @@ let
|
|||
};
|
||||
|
||||
filter = mkOption {
|
||||
type =
|
||||
types.nullOr (types.submodule { freeformType = configFormat.type; });
|
||||
type = types.nullOr (types.submodule { freeformType = configFormat.type; });
|
||||
|
||||
description = "Content of the filter used for this jail.";
|
||||
};
|
||||
|
@ -36,8 +44,8 @@ let
|
|||
};
|
||||
};
|
||||
};
|
||||
|
||||
in {
|
||||
in
|
||||
{
|
||||
options.dgn-fail2ban = {
|
||||
enable = mkEnableOption "fail2ban service.";
|
||||
|
||||
|
@ -50,9 +58,9 @@ in {
|
|||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
dgn-fail2ban.jails =
|
||||
builtins.mapAttrs (_: j: j // { enabled = mkDefault false; })
|
||||
(import ./jails.nix { });
|
||||
dgn-fail2ban.jails = builtins.mapAttrs (_: j: j // { enabled = mkDefault false; }) (
|
||||
import ./jails.nix { }
|
||||
);
|
||||
|
||||
services.fail2ban = {
|
||||
enable = true;
|
||||
|
|
|
@ -33,8 +33,7 @@
|
|||
|
||||
_: {
|
||||
nginx-spam = {
|
||||
filter.Definition.failregex = ''
|
||||
^<HOST>.*GET.*(matrix/server|\.php|admin|wp\-).* HTTP/\d.\d\" 404.*$'';
|
||||
filter.Definition.failregex = ''^<HOST>.*GET.*(matrix/server|\.php|admin|wp\-).* HTTP/\d.\d\" 404.*$'';
|
||||
|
||||
settings = {
|
||||
logpath = "/var/log/nginx/access.log";
|
||||
|
|
|
@ -1,11 +1,16 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
|
||||
let
|
||||
inherit (lib) mkEnableOption mkIf mkMerge;
|
||||
|
||||
cfg = config.dgn-hardware;
|
||||
|
||||
in {
|
||||
in
|
||||
{
|
||||
options.dgn-hardware = {
|
||||
enable = mkEnableOption "default hardware configuration." // {
|
||||
default = true;
|
||||
|
@ -19,45 +24,56 @@ in {
|
|||
useBcachefs = mkEnableOption "bcachefs configuration";
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable (mkMerge [
|
||||
{
|
||||
hardware.enableRedistributableFirmware = true;
|
||||
hardware.cpu.intel.updateMicrocode = true;
|
||||
config = mkIf cfg.enable (
|
||||
mkMerge [
|
||||
{
|
||||
hardware.enableRedistributableFirmware = true;
|
||||
hardware.cpu.intel.updateMicrocode = true;
|
||||
|
||||
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
|
||||
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
|
||||
|
||||
boot = {
|
||||
initrd.availableKernelModules =
|
||||
[ "ata_piix" "uhci_hcd" "ehci_pci" "virtio_pci" "ahci" "virtio_blk" ];
|
||||
kernelModules = [ "kvm-intel" ];
|
||||
kernelParams = [
|
||||
"cgroup_enable=cpu"
|
||||
"cgroup_enable=cpuset"
|
||||
"cgroup_enable=memory"
|
||||
"cgroup_memory=1"
|
||||
];
|
||||
};
|
||||
}
|
||||
|
||||
(mkIf cfg.useSystemd {
|
||||
boot.loader = {
|
||||
systemd-boot.enable = true;
|
||||
efi.canTouchEfiVariables = true;
|
||||
};
|
||||
})
|
||||
|
||||
(mkIf cfg.useBcachefs { boot.supportedFilesystems = [ "bcachefs" ]; })
|
||||
|
||||
(mkIf cfg.useZfs {
|
||||
boot = {
|
||||
supportedFilesystems = [ "zfs" ];
|
||||
|
||||
zfs = {
|
||||
forceImportRoot = false;
|
||||
extraPools = [ "fast01" "work01" ];
|
||||
package = pkgs.zfs_2_1;
|
||||
boot = {
|
||||
initrd.availableKernelModules = [
|
||||
"ata_piix"
|
||||
"uhci_hcd"
|
||||
"ehci_pci"
|
||||
"virtio_pci"
|
||||
"ahci"
|
||||
"virtio_blk"
|
||||
];
|
||||
kernelModules = [ "kvm-intel" ];
|
||||
kernelParams = [
|
||||
"cgroup_enable=cpu"
|
||||
"cgroup_enable=cpuset"
|
||||
"cgroup_enable=memory"
|
||||
"cgroup_memory=1"
|
||||
];
|
||||
};
|
||||
};
|
||||
})
|
||||
]);
|
||||
}
|
||||
|
||||
(mkIf cfg.useSystemd {
|
||||
boot.loader = {
|
||||
systemd-boot.enable = true;
|
||||
efi.canTouchEfiVariables = true;
|
||||
};
|
||||
})
|
||||
|
||||
(mkIf cfg.useBcachefs { boot.supportedFilesystems = [ "bcachefs" ]; })
|
||||
|
||||
(mkIf cfg.useZfs {
|
||||
boot = {
|
||||
supportedFilesystems = [ "zfs" ];
|
||||
|
||||
zfs = {
|
||||
forceImportRoot = false;
|
||||
extraPools = [
|
||||
"fast01"
|
||||
"work01"
|
||||
];
|
||||
package = pkgs.zfs_2_1;
|
||||
};
|
||||
};
|
||||
})
|
||||
]
|
||||
);
|
||||
}
|
||||
|
|
|
@ -1,12 +1,22 @@
|
|||
{ config, lib, meta, name, ... }:
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
meta,
|
||||
name,
|
||||
...
|
||||
}:
|
||||
|
||||
let
|
||||
inherit (lib) mapAttrs' mkEnableOption mkIf optionalAttrs;
|
||||
inherit (lib)
|
||||
mapAttrs'
|
||||
mkEnableOption
|
||||
mkIf
|
||||
optionalAttrs
|
||||
;
|
||||
|
||||
net = meta.network.${name};
|
||||
|
||||
mkAddress = { address, prefixLength, ... }:
|
||||
"${address}/${builtins.toString prefixLength}";
|
||||
mkAddress = { address, prefixLength, ... }: "${address}/${builtins.toString prefixLength}";
|
||||
mkRoute = gateway: {
|
||||
routeConfig = {
|
||||
Gateway = gateway;
|
||||
|
@ -38,12 +48,11 @@ let
|
|||
};
|
||||
|
||||
cfg = config.dgn-network;
|
||||
|
||||
in {
|
||||
options.dgn-network.enable =
|
||||
mkEnableOption "automatic network configuration based on metadata" // {
|
||||
default = true;
|
||||
};
|
||||
in
|
||||
{
|
||||
options.dgn-network.enable = mkEnableOption "automatic network configuration based on metadata" // {
|
||||
default = true;
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
networking = {
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
{ config, lib, ... }:
|
||||
let
|
||||
inherit (lib)
|
||||
mkEnableOption
|
||||
mkIf;
|
||||
inherit (lib) mkEnableOption mkIf;
|
||||
|
||||
cfg = config.dgn-vmVariant;
|
||||
in
|
||||
|
||||
{
|
||||
options.dgn-vmVariant.enable = mkEnableOption "ACME settings." // { default = true; };
|
||||
options.dgn-vmVariant.enable = mkEnableOption "ACME settings." // {
|
||||
default = true;
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
virtualisation.vmVariant = {
|
||||
|
@ -16,4 +16,3 @@ in
|
|||
};
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -4,7 +4,8 @@ let
|
|||
inherit (lib) mkEnableOption mkIf;
|
||||
|
||||
cfg = config.dgn-web;
|
||||
in {
|
||||
in
|
||||
{
|
||||
options.dgn-web = {
|
||||
enable = mkEnableOption "sane defaults for web services.";
|
||||
};
|
||||
|
@ -21,6 +22,9 @@ in {
|
|||
recommendedZstdSettings = true;
|
||||
};
|
||||
|
||||
networking.firewall.allowedTCPPorts = [ 80 443 ];
|
||||
networking.firewall.allowedTCPPorts = [
|
||||
80
|
||||
443
|
||||
];
|
||||
};
|
||||
}
|
||||
|
|
|
@ -1,20 +1,34 @@
|
|||
# Generated by npins. Do not modify; will be overwritten regularly
|
||||
let
|
||||
data = builtins.fromJSON (builtins.readFile ./sources.json);
|
||||
version = data.version;
|
||||
inherit (data) version;
|
||||
|
||||
mkSource = spec:
|
||||
assert spec ? type; let
|
||||
mkSource =
|
||||
spec:
|
||||
assert spec ? type;
|
||||
let
|
||||
path =
|
||||
if spec.type == "Git" then mkGitSource spec
|
||||
else if spec.type == "GitRelease" then mkGitSource spec
|
||||
else if spec.type == "PyPi" then mkPyPiSource spec
|
||||
else if spec.type == "Channel" then mkChannelSource spec
|
||||
else builtins.throw "Unknown source type ${spec.type}";
|
||||
if spec.type == "Git" then
|
||||
mkGitSource spec
|
||||
else if spec.type == "GitRelease" then
|
||||
mkGitSource spec
|
||||
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
|
||||
spec // { outPath = path; };
|
||||
|
||||
mkGitSource = { repository, revision, url ? null, hash, ... }:
|
||||
mkGitSource =
|
||||
{
|
||||
repository,
|
||||
revision,
|
||||
url ? null,
|
||||
hash,
|
||||
...
|
||||
}:
|
||||
assert repository ? type;
|
||||
# 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
|
||||
|
@ -23,19 +37,23 @@ let
|
|||
inherit url;
|
||||
sha256 = hash; # FIXME: check nix version & use SRI hashes
|
||||
})
|
||||
else assert repository.type == "Git"; builtins.fetchGit {
|
||||
url = repository.url;
|
||||
rev = revision;
|
||||
# hash = hash;
|
||||
};
|
||||
else
|
||||
assert repository.type == "Git";
|
||||
builtins.fetchGit {
|
||||
inherit (repository) url;
|
||||
rev = revision;
|
||||
# hash = hash;
|
||||
};
|
||||
|
||||
mkPyPiSource = { url, hash, ... }:
|
||||
mkPyPiSource =
|
||||
{ url, hash, ... }:
|
||||
builtins.fetchurl {
|
||||
inherit url;
|
||||
sha256 = hash;
|
||||
};
|
||||
|
||||
mkChannelSource = { url, hash, ... }:
|
||||
mkChannelSource =
|
||||
{ url, hash, ... }:
|
||||
builtins.fetchTarball {
|
||||
inherit url;
|
||||
sha256 = hash;
|
||||
|
|
|
@ -118,6 +118,18 @@
|
|||
"url": "https://releases.nixos.org/nixpkgs/nixpkgs-24.05pre578430.5ad9903c1612/nixexprs.tar.xz",
|
||||
"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": {
|
||||
"type": "Git",
|
||||
"repository": {
|
||||
|
|
|
@ -8,19 +8,25 @@ let
|
|||
coreutils
|
||||
nvd
|
||||
git
|
||||
jq;
|
||||
jq
|
||||
;
|
||||
};
|
||||
|
||||
mkShellScript = name: (pkgs.substituteAll ({
|
||||
inherit name;
|
||||
src = ./. + "/${name}.sh";
|
||||
dir = "/bin/";
|
||||
isExecutable = true;
|
||||
mkShellScript =
|
||||
name:
|
||||
(pkgs.substituteAll (
|
||||
{
|
||||
inherit name;
|
||||
src = ./. + "/${name}.sh";
|
||||
dir = "/bin/";
|
||||
isExecutable = true;
|
||||
|
||||
checkPhase = ''
|
||||
${pkgs.stdenv.shellDryRun} "$target"
|
||||
'';
|
||||
} // substitutions));
|
||||
checkPhase = ''
|
||||
${pkgs.stdenv.shellDryRun} "$target"
|
||||
'';
|
||||
}
|
||||
// substitutions
|
||||
));
|
||||
|
||||
scripts = [
|
||||
"check-deployment"
|
||||
|
|
53
shell.nix
53
shell.nix
|
@ -1,52 +1 @@
|
|||
/*
|
||||
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;
|
||||
}
|
||||
(import ./.).shells.default
|
||||
|
|
Loading…
Reference in a new issue