Compare commits

...

21 Commits

Author SHA1 Message Date
60e1bbfd08 WIP: Add bluemap
Co-authored-by: Daniel Olsen <daniel.olsen99@gmail.com>
2024-06-09 07:33:43 +02:00
ceaa67fc19 WIP: fix loki 2024-06-08 20:58:25 +02:00
375e0f1486 treewide: fix issues for 24.05 upgrade 2024-06-08 20:58:10 +02:00
218ee776c7 Merge pull request 'packages/mediawiki-extensions: use stable url' () from fix-mediawiki-extensions-url into main
Reviewed-on: 
2024-05-26 02:45:04 +02:00
3a972f03f7 flake: move mediawiki-extensions back to packages 2024-05-26 02:42:31 +02:00
96024efa28 flake: move mediawiki-extensions to legacyPackages 2024-05-26 02:42:31 +02:00
af54cc2df4 packages/mediawiki/pluggable-auth: fix typo 2024-05-26 02:42:31 +02:00
6f6721ce07 packages/mediawiki-extensions: use stable url 2024-05-26 02:42:28 +02:00
1c35da0295 Merge pull request 'bekkalokk: add snappymail' () from bekkalokk-snappymail into main
Reviewed-on: 
2024-05-26 01:52:17 +02:00
5fb1b805a8 bekkalokk: add snappymail 2024-05-26 01:07:27 +02:00
a38a12c429 flake.lock: update pvv-nettsiden 2024-05-19 22:27:59 +02:00
898e362a9f Merge pull request 'bekkalokk/website: add sp metadata for all domains' () from add-sp-metadata-for-all-website-domains into main
Reviewed-on: 
2024-05-14 05:27:44 +02:00
c267820426 overlays/nginx-test: drop 2024-05-13 07:04:00 +02:00
a57b5f07f9 Merge pull request 'gitea: setup mail' () from gitea-setup-mail into main
Reviewed-on: 
2024-05-12 02:27:37 +02:00
bcf2ceed32 gitea: setup mail 2024-05-12 02:26:13 +02:00
0a3d1e3696 overlays/nginx-test
just start replacing shit, we're not even testing the actual config now
This sucks
nginx should make a proper validation tool that doesnt do DNS request on every hostname mentioned in the config file.
Not to mention trying to actually listen on the ip-address and port
Why?? Why is TEST failing because it can't bind to the SAME address nginx is probably in production listening on already??
2024-05-12 02:22:12 +02:00
45eea1a791 update flake.lock 2024-05-12 02:22:12 +02:00
200224d2c1 Merge pull request 'bekkalokk: misc gitea cleanup' () from misc-gitea-cleanup into main
Reviewed-on: 
2024-05-12 02:12:55 +02:00
b7b1c73bfa bekkalokk/gitea: use systemd unit for gitea customization 2024-04-16 01:02:21 +02:00
70603145cf bekkalokk/website: add sp metadata for all domains 2024-04-14 17:06:01 +02:00
5bed292a01 bekkalokk/gitea: move user import stuff to separate nix file 2024-04-11 21:47:44 +02:00
26 changed files with 518 additions and 1895 deletions
.sops.yamlflake.lockflake.nix
hosts
modules
overlays
packages/mediawiki-extensions
default.nix
delete-batch
pluggable-auth
simple-saml-php
update-mediawiki-extensions.py
user-merge
visual-editor
secrets

@@ -10,6 +10,7 @@ keys:
- &host_ildkule age1x28hmzvuv6f2n66c0jtqcca3h9rput8d7j5uek6jcpx8n9egd52sqpejq0
- &host_bekkalokk age12nj59tguy9wg882updc2vjdusx5srnxmjyfaqve4zx6jnnsaw3qsyjq6zd
- &host_bicep age1sl43gc9cw939z5tgha2lpwf0xxxgcnlw7w4xem4sqgmt2pt264vq0dmwx2
- &host_buskerud age1tmn5qahlyf0e579e4camckdyxrexjzffv54hdzdnrw7lzqs7kyqq0f2fr3
creation_rules:
# Global secrets
@@ -60,3 +61,10 @@ creation_rules:
- *user_felixalb
pgp:
- *user_oysteikt
- path_regex: secrets/buskerud/[^/]+\.yaml$
key_groups:
- age:
- *host_buskerud
- *user_danio
- *user_eirikwit

122
flake.lock generated

@@ -7,11 +7,11 @@
]
},
"locked": {
"lastModified": 1712798444,
"narHash": "sha256-aAksVB7zMfBQTz0q2Lw3o78HM3Bg2FRziX2D6qnh+sk=",
"lastModified": 1716431128,
"narHash": "sha256-t3T8HlX3udO6f4ilLcN+j5eC3m2gqsouzSGiriKK6vk=",
"owner": "nix-community",
"repo": "disko",
"rev": "a297cb1cb0337ee10a7a0f9517954501d8f6f74d",
"rev": "7ffc4354dfeb37c8c725ae1465f04a9b45ec8606",
"type": "github"
},
"original": {
@@ -20,18 +20,58 @@
"type": "github"
}
},
"fix-python": {
"inputs": {
"flake-utils": "flake-utils",
"nixpkgs": [
"grzegorz",
"nixpkgs"
]
},
"locked": {
"lastModified": 1713887124,
"narHash": "sha256-hGTSm0p9xXUYDgsAAr/ORZICo6T6u33vLfX3tILikaQ=",
"owner": "GuillaumeDesforges",
"repo": "fix-python",
"rev": "f7f4b33e22414071fc1f9cbf68072c413c3a7fdf",
"type": "github"
},
"original": {
"owner": "GuillaumeDesforges",
"repo": "fix-python",
"type": "github"
}
},
"flake-utils": {
"inputs": {
"systems": "systems"
},
"locked": {
"lastModified": 1689068808,
"narHash": "sha256-6ixXo3wt24N/melDWjq70UuHQLxGV8jZvooRanIHXw0=",
"owner": "numtide",
"repo": "flake-utils",
"rev": "919d646de7be200f3bf08cb76ae1f09402b6f9b4",
"type": "github"
},
"original": {
"id": "flake-utils",
"type": "indirect"
}
},
"grzegorz": {
"inputs": {
"fix-python": "fix-python",
"nixpkgs": [
"nixpkgs-unstable"
]
},
"locked": {
"lastModified": 1712875951,
"narHash": "sha256-4kcRd2Q2XM4r+U2zp+LADjrzazKpWvs0WrMKPktEEkc=",
"lastModified": 1716065905,
"narHash": "sha256-08uhxBzfakfhl/ooc+gMzDupWKYvTeyQZwuvB1SBS7A=",
"owner": "Programvareverkstedet",
"repo": "grzegorz",
"rev": "9eaba26b1671e8810cb135997c867ac3550e685a",
"rev": "0481aef6553ae9aee86e4edb4ca0ed4f2eba2058",
"type": "github"
},
"original": {
@@ -47,11 +87,11 @@
]
},
"locked": {
"lastModified": 1711853301,
"narHash": "sha256-KxRNyW/fgq690bt3B+Nz4EKLoubybcuASYyMa41bAPE=",
"lastModified": 1716115695,
"narHash": "sha256-aI65l4x+U5v3i/nfn6N3eW5IZodmf4pyAByE7vTJh8I=",
"owner": "Programvareverkstedet",
"repo": "grzegorz-clients",
"rev": "c38f2f22a6d47ae2da015351a45d13cbc1eb48e4",
"rev": "b9444658fbb39cd1bf1c61ee5a1d5f0641c49abe",
"type": "github"
},
"original": {
@@ -67,15 +107,16 @@
]
},
"locked": {
"lastModified": 1710311999,
"narHash": "sha256-s0pT1NyrMgeolUojXXcnXQDymN7m80GTF7itCv0ZH20=",
"lastModified": 1717234745,
"narHash": "sha256-MFyKRdw4WQD6V3vRGbP6MYbtJhZp712zwzjW6YiOBYM=",
"owner": "dali99",
"repo": "nixos-matrix-modules",
"rev": "6c9b67974b839740e2a738958512c7a704481157",
"rev": "d7dc42c9bbb155c5e4aa2f0985d0df75ce978456",
"type": "github"
},
"original": {
"owner": "dali99",
"ref": "v0.6.0",
"repo": "nixos-matrix-modules",
"type": "github"
}
@@ -87,11 +128,11 @@
]
},
"locked": {
"lastModified": 1712621190,
"narHash": "sha256-O8xtza+wPplTmSm0EAPk8Ud9sJ6huVNY6jU21FYHCp4=",
"lastModified": 1714416973,
"narHash": "sha256-aZUcvXjdETUC6wVQpWDVjLUzwpDAEca8yR0ITDeK39o=",
"ref": "refs/heads/main",
"rev": "812c1fc4061d534a8c7d35271ce32b6c76a9f385",
"revCount": 5,
"rev": "2b23c0ba8aae68d3cb6789f0f6e4891cef26cc6d",
"revCount": 6,
"type": "git",
"url": "https://git.pvv.ntnu.no/oysteikt/nix-gitea-themes.git"
},
@@ -102,26 +143,26 @@
},
"nixpkgs": {
"locked": {
"lastModified": 1712848736,
"narHash": "sha256-CzZwhqyLlebljv1zFS2KWVH/3byHND0LfaO1jKsGuVo=",
"lastModified": 1716586607,
"narHash": "sha256-PzpeC/xi0+YTGJS5rdbcOqVgIryuWHkimMVXoCIidgA=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "1d6a23f11e44d0fb64b3237569b87658a9eb5643",
"rev": "03309929e115bba1339308814f8b6e63f250fedf",
"type": "github"
},
"original": {
"id": "nixpkgs",
"ref": "nixos-23.11-small",
"ref": "nixos-24.05-small",
"type": "indirect"
}
},
"nixpkgs-stable": {
"locked": {
"lastModified": 1712437997,
"narHash": "sha256-g0whLLwRvgO2FsyhY8fNk+TWenS3jg5UdlWL4uqgFeo=",
"lastModified": 1716061101,
"narHash": "sha256-H0eCta7ahEgloGIwE/ihkyGstOGu+kQwAiHvwVoXaA0=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "e38d7cb66ea4f7a0eb6681920615dfcc30fc2920",
"rev": "e7cc61784ddf51c81487637b3031a6dd2d6673a2",
"type": "github"
},
"original": {
@@ -133,11 +174,11 @@
},
"nixpkgs-unstable": {
"locked": {
"lastModified": 1712837137,
"narHash": "sha256-9joaU/GD35J9Utb0ipelQbOcvsw5eoYTmSarLV3MbNk=",
"lastModified": 1716660083,
"narHash": "sha256-QO7cdjtDhx72KEw6m0NOtuE5FS4asaRExZ65uFR/q8g=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "681d4a87b26b1dcaae7ffe6cf88c9912c575415f",
"rev": "6de51d98ec2ae46730f11845e221aab9d2470a8a",
"type": "github"
},
"original": {
@@ -173,11 +214,11 @@
]
},
"locked": {
"lastModified": 1712834399,
"narHash": "sha256-deNJvqboPk3bEoRZ/FyZnxscsf2BpS3/52JM4qXCNSA=",
"lastModified": 1716150352,
"narHash": "sha256-c13lzYbLmbrcbEdPTYZYtlX2Qsz1W+2sLsIMGShPgwo=",
"ref": "refs/heads/master",
"rev": "216e153f89f1dbdc4c98a7c1db2a40e52becc901",
"revCount": 451,
"rev": "2cab4df4b119e08a1f90ea1c944652cd78b4d478",
"revCount": 459,
"type": "git",
"url": "https://git.pvv.ntnu.no/Projects/nettsiden.git"
},
@@ -208,11 +249,11 @@
"nixpkgs-stable": "nixpkgs-stable"
},
"locked": {
"lastModified": 1712617241,
"narHash": "sha256-a4hbls4vlLRMciv62YrYT/Xs/3Cubce8WFHPUDWwzf8=",
"lastModified": 1716400300,
"narHash": "sha256-0lMkIk9h3AzOHs1dCL9RXvvN4PM8VBKb+cyGsqOKa4c=",
"owner": "Mic92",
"repo": "sops-nix",
"rev": "538c114cfdf1f0458f507087b1dcf018ce1c0c4c",
"rev": "b549832718b8946e875c016a4785d204fcfc2e53",
"type": "github"
},
"original": {
@@ -220,6 +261,21 @@
"repo": "sops-nix",
"type": "github"
}
},
"systems": {
"locked": {
"lastModified": 1681028828,
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
"owner": "nix-systems",
"repo": "default",
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
"type": "github"
},
"original": {
"owner": "nix-systems",
"repo": "default",
"type": "github"
}
}
},
"root": "root",

@@ -2,7 +2,7 @@
description = "PVV System flake";
inputs = {
nixpkgs.url = "nixpkgs/nixos-23.11-small";
nixpkgs.url = "nixpkgs/nixos-24.05-small";
nixpkgs-unstable.url = "nixpkgs/nixos-unstable-small";
sops-nix.url = "github:Mic92/sops-nix";
@@ -17,7 +17,7 @@
pvv-calendar-bot.url = "git+https://git.pvv.ntnu.no/Projects/calendar-bot.git";
pvv-calendar-bot.inputs.nixpkgs.follows = "nixpkgs";
matrix-next.url = "github:dali99/nixos-matrix-modules";
matrix-next.url = "github:dali99/nixos-matrix-modules/v0.6.0";
matrix-next.inputs.nixpkgs.follows = "nixpkgs";
nix-gitea-themes.url = "git+https://git.pvv.ntnu.no/oysteikt/nix-gitea-themes.git";
@@ -65,9 +65,7 @@
pkgs = import nixpkgs {
inherit system;
overlays = [
(import ./overlays/nginx-test.nix
(builtins.attrNames self.nixosConfigurations.${name}.config.security.acme.certs)
)
# Global overlays go here
] ++ config.overlays or [ ];
};
}
@@ -142,8 +140,13 @@
simplesamlphp = pkgs.callPackage ./packages/simplesamlphp { };
# mediawiki-extensions = pkgs.callPackage ./packages/mediawiki-extensions { };
} // nixlib.genAttrs allMachines
} //
(nixlib.pipe null [
(_: pkgs.callPackage ./packages/mediawiki-extensions { })
(nixlib.flip builtins.removeAttrs ["override" "overrideDerivation"])
(nixlib.mapAttrs' (name: nixlib.nameValuePair "mediawiki-${name}"))
])
// nixlib.genAttrs allMachines
(machine: self.nixosConfigurations.${machine}.config.system.build.toplevel);
};
};

@@ -6,6 +6,7 @@ let
in {
imports = [
./ci.nix
./import-users.nix
];
sops.secrets = {
@@ -13,9 +14,10 @@ in {
owner = "gitea";
group = "gitea";
};
"gitea/passwd-ssh-key" = { };
"gitea/ssh-known-hosts" = { };
"gitea/import-user-env" = { };
"gitea/email-password" = {
owner = "gitea";
group = "gitea";
};
};
services.gitea = {
@@ -26,18 +28,28 @@ in {
database = {
type = "postgres";
host = "postgres.pvv.ntnu.no";
port = config.services.postgresql.port;
port = config.services.postgresql.settings.port;
passwordFile = config.sops.secrets."gitea/database".path;
createDatabase = false;
};
mailerPasswordFile = config.sops.secrets."gitea/email-password".path;
settings = {
server = {
DOMAIN = domain;
ROOT_URL = "https://${domain}/";
PROTOCOL = "http+unix";
SSH_PORT = sshPort;
START_SSH_SERVER = true;
START_SSH_SERVER = true;
};
mailer = {
ENABLED = true;
FROM = "gitea@pvv.ntnu.no";
PROTOCOL = "smtp";
SMTP_ADDR = "smtp.pvv.ntnu.no";
SMTP_PORT = 587;
USER = "gitea@pvv.ntnu.no";
};
indexer.REPO_INDEXER_ENABLED = true;
service.DISABLE_REGISTRATION = true;
@@ -52,8 +64,6 @@ in {
};
};
services.gitea-themes.monokai = pkgs.gitea-theme-monokai;
environment.systemPackages = [ cfg.package ];
services.nginx.virtualHosts."${domain}" = {
@@ -70,38 +80,28 @@ in {
networking.firewall.allowedTCPPorts = [ sshPort ];
# Automatically import users
systemd.services.gitea-import-users = {
enable = true;
preStart=''${pkgs.rsync}/bin/rsync -e "${pkgs.openssh}/bin/ssh -o UserKnownHostsFile=$CREDENTIALS_DIRECTORY/ssh-known-hosts -i $CREDENTIALS_DIRECTORY/sshkey" -a pvv@smtp.pvv.ntnu.no:/etc/passwd /tmp/passwd-import'';
serviceConfig = {
ExecStart = pkgs.writers.writePython3 "gitea-import-users" { libraries = [ pkgs.python3Packages.requests ]; } (builtins.readFile ./gitea-import-users.py);
LoadCredential=[
"sshkey:${config.sops.secrets."gitea/passwd-ssh-key".path}"
"ssh-known-hosts:${config.sops.secrets."gitea/ssh-known-hosts".path}"
];
DynamicUser="yes";
EnvironmentFile=config.sops.secrets."gitea/import-user-env".path;
};
};
# Extra customization
systemd.timers.gitea-import-users = {
requires = [ "gitea.service" ];
after = [ "gitea.service" ];
wantedBy = [ "timers.target" ];
timerConfig = {
OnCalendar = "*-*-* 02:00:00";
Persistent = true;
Unit = "gitea-import-users.service";
};
};
services.gitea-themes.monokai = pkgs.gitea-theme-monokai;
system.activationScripts.linkGiteaLogo.text = let
logo-svg = ../../../../assets/logo_blue_regular.svg;
logo-png = ../../../../assets/logo_blue_regular.png;
in ''
install -Dm444 ${logo-svg} ${cfg.stateDir}/custom/public/img/logo.svg
install -Dm444 ${logo-png} ${cfg.stateDir}/custom/public/img/logo.png
install -Dm444 ${./loading.apng} ${cfg.stateDir}/custom/public/img/loading.png
'';
systemd.services.install-gitea-customization = {
description = "Install extra customization in gitea's CUSTOM_DIR";
wantedBy = [ "gitea.service" ];
requiredBy = [ "gitea.service" ];
serviceConfig = {
Type = "oneshot";
User = cfg.user;
Group = cfg.group;
};
script = let
logo-svg = ../../../../assets/logo_blue_regular.svg;
logo-png = ../../../../assets/logo_blue_regular.png;
in ''
install -Dm444 ${logo-svg} ${cfg.customDir}/public/img/logo.svg
install -Dm444 ${logo-png} ${cfg.customDir}/public/img/logo.png
install -Dm444 ${./loading.apng} ${cfg.customDir}/public/img/loading.png
'';
};
}

@@ -0,0 +1,38 @@
{ config, pkgs, lib, ... }:
let
cfg = config.services.gitea;
in
{
sops.secrets = {
"gitea/passwd-ssh-key" = { };
"gitea/ssh-known-hosts" = { };
"gitea/import-user-env" = { };
};
systemd.services.gitea-import-users = lib.mkIf cfg.enable {
enable = true;
preStart=''${pkgs.rsync}/bin/rsync -e "${pkgs.openssh}/bin/ssh -o UserKnownHostsFile=$CREDENTIALS_DIRECTORY/ssh-known-hosts -i $CREDENTIALS_DIRECTORY/sshkey" -a pvv@smtp.pvv.ntnu.no:/etc/passwd /tmp/passwd-import'';
serviceConfig = {
ExecStart = pkgs.writers.writePython3 "gitea-import-users" {
libraries = with pkgs.python3Packages; [ requests ];
} (builtins.readFile ./gitea-import-users.py);
LoadCredential=[
"sshkey:${config.sops.secrets."gitea/passwd-ssh-key".path}"
"ssh-known-hosts:${config.sops.secrets."gitea/ssh-known-hosts".path}"
];
DynamicUser="yes";
EnvironmentFile=config.sops.secrets."gitea/import-user-env".path;
};
};
systemd.timers.gitea-import-users = lib.mkIf cfg.enable {
requires = [ "gitea.service" ];
after = [ "gitea.service" ];
wantedBy = [ "timers.target" ];
timerConfig = {
OnCalendar = "*-*-* 02:00:00";
Persistent = true;
Unit = "gitea-import-users.service";
};
};
}

@@ -3,14 +3,14 @@
#######################
# TODO: remove these once nixos 24.05 gets released
#######################
imports = [
./krb5.nix
./pam.nix
];
disabledModules = [
"config/krb5/default.nix"
"security/pam.nix"
];
# imports = [
# ./krb5.nix
# ./pam.nix
# ];
# disabledModules = [
# "config/krb5/default.nix"
# "security/pam.nix"
# ];
#######################
security.krb5 = {

@@ -1,88 +0,0 @@
{ pkgs, lib, ... }:
# Based on
# - https://web.mit.edu/kerberos/krb5-1.12/doc/admin/conf_files/krb5_conf.html
# - https://manpages.debian.org/unstable/heimdal-docs/krb5.conf.5heimdal.en.html
let
inherit (lib) boolToString concatMapStringsSep concatStringsSep filter
isAttrs isBool isList mapAttrsToList mdDoc mkOption singleton splitString;
inherit (lib.types) attrsOf bool coercedTo either int listOf oneOf path
str submodule;
in
{ }: {
type = let
section = attrsOf relation;
relation = either (attrsOf value) value;
value = either (listOf atom) atom;
atom = oneOf [int str bool];
in submodule {
freeformType = attrsOf section;
options = {
include = mkOption {
default = [ ];
description = mdDoc ''
Files to include in the Kerberos configuration.
'';
type = coercedTo path singleton (listOf path);
};
includedir = mkOption {
default = [ ];
description = mdDoc ''
Directories containing files to include in the Kerberos configuration.
'';
type = coercedTo path singleton (listOf path);
};
module = mkOption {
default = [ ];
description = mdDoc ''
Modules to obtain Kerberos configuration from.
'';
type = coercedTo path singleton (listOf path);
};
};
};
generate = let
indent = str: concatMapStringsSep "\n" (line: " " + line) (splitString "\n" str);
formatToplevel = args @ {
include ? [ ],
includedir ? [ ],
module ? [ ],
...
}: let
sections = removeAttrs args [ "include" "includedir" "module" ];
in concatStringsSep "\n" (filter (x: x != "") [
(concatStringsSep "\n" (mapAttrsToList formatSection sections))
(concatMapStringsSep "\n" (m: "module ${m}") module)
(concatMapStringsSep "\n" (i: "include ${i}") include)
(concatMapStringsSep "\n" (i: "includedir ${i}") includedir)
]);
formatSection = name: section: ''
[${name}]
${indent (concatStringsSep "\n" (mapAttrsToList formatRelation section))}
'';
formatRelation = name: relation:
if isAttrs relation
then ''
${name} = {
${indent (concatStringsSep "\n" (mapAttrsToList formatValue relation))}
}''
else formatValue name relation;
formatValue = name: value:
if isList value
then concatMapStringsSep "\n" (formatAtom name) value
else formatAtom name value;
formatAtom = name: atom: let
v = if isBool atom then boolToString atom else toString atom;
in "${name} = ${v}";
in
name: value: pkgs.writeText name ''
${formatToplevel value}
'';
}

@@ -1,90 +0,0 @@
{ config, lib, pkgs, ... }:
let
inherit (lib) mdDoc mkIf mkOption mkPackageOption mkRemovedOptionModule;
inherit (lib.types) bool;
mkRemovedOptionModule' = name: reason: mkRemovedOptionModule ["krb5" name] reason;
mkRemovedOptionModuleCfg = name: mkRemovedOptionModule' name ''
The option `krb5.${name}' has been removed. Use
`security.krb5.settings.${name}' for structured configuration.
'';
cfg = config.security.krb5;
format = import ./krb5-conf-format.nix { inherit pkgs lib; } { };
in {
imports = [
(mkRemovedOptionModuleCfg "libdefaults")
(mkRemovedOptionModuleCfg "realms")
(mkRemovedOptionModuleCfg "domain_realm")
(mkRemovedOptionModuleCfg "capaths")
(mkRemovedOptionModuleCfg "appdefaults")
(mkRemovedOptionModuleCfg "plugins")
(mkRemovedOptionModuleCfg "config")
(mkRemovedOptionModuleCfg "extraConfig")
(mkRemovedOptionModule' "kerberos" ''
The option `krb5.kerberos' has been moved to `security.krb5.package'.
'')
];
options = {
security.krb5 = {
enable = mkOption {
default = false;
description = mdDoc "Enable and configure Kerberos utilities";
type = bool;
};
package = mkPackageOption pkgs "krb5" {
example = "heimdal";
};
settings = mkOption {
default = { };
type = format.type;
description = mdDoc ''
Structured contents of the {file}`krb5.conf` file. See
{manpage}`krb5.conf(5)` for details about configuration.
'';
example = {
include = [ "/run/secrets/secret-krb5.conf" ];
includedir = [ "/run/secrets/secret-krb5.conf.d" ];
libdefaults = {
default_realm = "ATHENA.MIT.EDU";
};
realms = {
"ATHENA.MIT.EDU" = {
admin_server = "athena.mit.edu";
kdc = [
"athena01.mit.edu"
"athena02.mit.edu"
];
};
};
domain_realm = {
"mit.edu" = "ATHENA.MIT.EDU";
};
logging = {
kdc = "SYSLOG:NOTICE";
admin_server = "SYSLOG:NOTICE";
default = "SYSLOG:NOTICE";
};
};
};
};
};
config = mkIf cfg.enable {
environment = {
systemPackages = [ cfg.package ];
etc."krb5.conf".source = format.generate "krb5.conf" cfg.settings;
};
};
meta.maintainers = builtins.attrValues {
inherit (lib.maintainers) dblsaiko h7x4;
};
}

File diff suppressed because it is too large Load Diff

@@ -2,6 +2,7 @@
{
imports = [
./roundcube.nix
./snappymail.nix
];
services.nginx.virtualHosts."webmail.pvv.ntnu.no" = {
@@ -10,9 +11,11 @@
kTLS = true;
locations = {
"= /".return = "302 https://webmail.pvv.ntnu.no/roundcube";
"/afterlogic_lite".return = "302 https://webmail.pvv.ntnu.no/roundcube";
"/squirrelmail".return = "302 https://webmail.pvv.ntnu.no/roundcube";
"/rainloop".return = "302 https://webmail.pvv.ntnu.no/roundcube";
"/rainloop".return = "302 https://snappymail.pvv.ntnu.no/";
"/snappymail".return = "302 https://snappymail.pvv.ntnu.no/";
};
};
}

@@ -0,0 +1,18 @@
{ config, lib, pkgs, ... }:
let
cfg = config.services.snappymail;
in {
imports = [ ../../../../modules/snappymail.nix ];
services.snappymail = {
enable = true;
hostname = "snappymail.pvv.ntnu.no";
};
services.nginx.virtualHosts.${cfg.hostname} = {
forceSSL = true;
enableACME = true;
kTLS = true;
};
}

@@ -18,7 +18,12 @@ in {
restartUnits = [ "phpfpm-pvv-nettsiden.service" ];
});
services.idp.sp-remote-metadata = [ "https://${cfg.domainName}/simplesaml/" ];
services.idp.sp-remote-metadata = [
"https://www.pvv.ntnu.no/simplesaml/"
"https://pvv.ntnu.no/simplesaml/"
"https://www.pvv.org/simplesaml/"
"https://pvv.org/simplesaml/"
];
services.pvv-nettsiden = {
enable = true;

@@ -6,6 +6,12 @@
../../misc/metrics-exporters.nix
];
sops.defaultSopsFile = ../../secrets/buskerud/buskerud.yaml;
sops.age.sshKeyPaths = [ "/etc/ssh/ssh_host_ed25519_key" ];
sops.age.keyFile = "/var/lib/sops-nix/key.txt";
sops.age.generateKey = true;
# buskerud does not support efi?
# boot.loader.systemd-boot.enable = true;
# boot.loader.efi.canTouchEfiVariables = true;

@@ -0,0 +1,21 @@
{config, ...}:
{
sops.secrets."bluemap_ssh_key" = {
owner = "root";
mode = "0400";
};
services.bluemap = {
enable = true;
eula = true;
defaultWorld = "/var/lib/bluemap/vanilla";
host = "minecraft.pvv.ntnu.no";
};
systemd.services."render-bluemap-maps".preStart = ''
rsync -e 'ssh -i ${config.sops.secrets."bluemap_ssh_key".path} -o "StrictHostKeyChecking accept-new"' \
root@innovation.pvv.ntnu.no:/var/backups/minecraft/current/ \
/var/lib/bluemap/vanilla"
'';
}

@@ -50,7 +50,7 @@ in {
boltdb_shipper = {
active_index_directory = "/var/lib/loki/boltdb-shipper-index";
cache_location = "/var/lib/loki/boltdb-shipper-cache";
shared_store = "filesystem";
# shared_store = "filesystem";
cache_ttl = "24h";
};
filesystem = {
@@ -59,14 +59,15 @@ in {
};
limits_config = {
enforce_metric_name = false;
allow_structured_metadata = false;
# enforce_metric_name = false;
reject_old_samples = true;
reject_old_samples_max_age = "72h";
};
compactor = {
working_directory = "/var/lib/loki/compactor";
shared_store = "filesystem";
# shared_store = "filesystem";
};
# ruler = {

103
modules/snappymail.nix Normal file

@@ -0,0 +1,103 @@
{ config, pkgs, lib, ... }:
let
inherit (lib) mkDefault mkEnableOption mkForce mkIf mkOption mkPackageOption generators types;
cfg = config.services.snappymail;
maxUploadSize = "256M";
in {
options.services.snappymail = {
enable = mkEnableOption "Snappymail";
package = mkPackageOption pkgs "snappymail" { };
dataDir = mkOption {
type = types.str;
default = "/var/lib/snappymail";
description = "State directory for snappymail";
};
hostname = mkOption {
type = types.nullOr types.str;
default = null;
example = "mail.example.com";
description = "Enable nginx with this hostname, null disables nginx";
};
user = mkOption {
type = types.str;
default = "snappymail";
description = "System user under which snappymail runs";
};
group = mkOption {
type = types.str;
default = "snappymail";
description = "System group under which snappymail runs";
};
};
config = mkIf cfg.enable {
users.users = mkIf (cfg.user == "snappymail") {
snappymail = {
description = "Snappymail service";
group = cfg.group;
home = cfg.dataDir;
isSystemUser = true;
};
};
users.groups = mkIf (cfg.group == "snappymail") {
snappymail = {};
};
services.phpfpm.pools.snappymail = {
user = cfg.user;
group = cfg.group;
phpOptions = generators.toKeyValue {} {
upload_max_filesize = maxUploadSize;
post_max_size = maxUploadSize;
memory_limit = maxUploadSize;
};
settings = {
"listen.owner" = config.services.nginx.user;
"listen.group" = config.services.nginx.group;
"pm" = "ondemand";
"pm.max_children" = 32;
"pm.process_idle_timeout" = "10s";
"pm.max_requests" = 500;
};
};
services.nginx = mkIf (cfg.hostname != null) {
virtualHosts."${cfg.hostname}" = {
locations."/".extraConfig = ''
index index.php;
autoindex on;
autoindex_exact_size off;
autoindex_localtime on;
'';
locations."^~ /data".extraConfig = ''
deny all;
'';
locations."~ \\.php$".extraConfig = ''
include ${config.services.nginx.package}/conf/fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_pass unix:${config.services.phpfpm.pools.snappymail.socket};
'';
extraConfig = ''
client_max_body_size ${maxUploadSize};
'';
root = if (cfg.package == pkgs.snappymail) then
pkgs.snappymail.override {
dataPath = cfg.dataDir;
}
else cfg.package;
};
};
};
}

@@ -1,28 +0,0 @@
acme-certs: final: prev:
let
lib = final.lib;
crt = "${final.path}/nixos/tests/common/acme/server/acme.test.cert.pem";
key = "${final.path}/nixos/tests/common/acme/server/acme.test.key.pem";
in {
writers = prev.writers // {
writeNginxConfig = name: text: final.runCommandLocal name {
nginxConfig = prev.writers.writeNginxConfig name text;
nativeBuildInputs = [ final.bubblewrap ];
} ''
ln -s "$nginxConfig" "$out"
set +o pipefail
bwrap \
--ro-bind "${crt}" "/etc/certs/nginx.crt" \
--ro-bind "${key}" "/etc/certs/nginx.key" \
--ro-bind "/nix" "/nix" \
--ro-bind "/etc/hosts" "/etc/hosts" \
--dir "/run/nginx" \
--dir "/tmp" \
--dir "/var/log/nginx" \
${lib.concatMapStrings (name: "--ro-bind \"${crt}\" \"/var/lib/acme/${name}/fullchain.pem\" \\") acme-certs}
${lib.concatMapStrings (name: "--ro-bind \"${key}\" \"/var/lib/acme/${name}/key.pem\" \\") acme-certs}
${lib.concatMapStrings (name: "--ro-bind \"${crt}\" \"/var/lib/acme/${name}/chain.pem\" \\") acme-certs}
${lib.getExe' final.nginx "nginx"} -t -c "$out" |& grep "syntax is ok"
'';
};
}

@@ -1,8 +1,8 @@
{ pkgs, lib }:
lib.makeScope pkgs.newScope (self: {
DeleteBatch = self.callPackage ./delete-batch { };
PluggableAuth = self.callPackage ./pluggable-auth { };
SimpleSAMLphp = self.callPackage ./simple-saml-php { };
UserMerge = self.callPackage ./user-merge { };
VisualEditor = self.callPackage ./visual-editor { };
})
{
DeleteBatch = pkgs.callPackage ./delete-batch { };
PluggableAuth = pkgs.callPackage ./pluggable-auth { };
SimpleSAMLphp = pkgs.callPackage ./simple-saml-php { };
UserMerge = pkgs.callPackage ./user-merge { };
VisualEditor = pkgs.callPackage ./visual-editor { };
}

@@ -1,7 +1,13 @@
{ fetchzip }:
let
commit = "a53af3b8269ed19ede3cf1fa811e7ec8cb00af92";
project-name = "UserMerge";
tracking-branch = "REL1_41";
in
fetchzip {
name = "mediawiki-delete-batch";
url = "https://extdist.wmflabs.org/dist/extensions/DeleteBatch-REL1_41-5774fdd.tar.gz";
hash = "sha256-ROkn93lf0mNXBvij9X2pMhd8LXZ0azOz7ZRaqZvhh8k=";
url = "https://gerrit.wikimedia.org/r/plugins/gitiles/mediawiki/extensions/${project-name}/+archive/${commit}.tar.gz";
hash = "sha256-0ofCZhhv4aVTGq469Fdu7k0oVQu3kG3HFa8zaBbUr/M=";
stripRoot = false;
passthru = { inherit project-name tracking-branch; };
}

@@ -1,7 +1,13 @@
{ fetchzip }:
let
commit = "d5b3ad8f03b65d3746e025cdd7fe3254ad6e4026";
project-name = "PluggableAuth";
tracking-branch = "REL1_41";
in
fetchzip {
name = "mediawiki-pluggable-auth-source";
url = "https://extdist.wmflabs.org/dist/extensions/PluggableAuth-REL1_41-d5b3ad8.tar.gz";
hash = "sha256-OLlkKeSlfNgWXWwDdINrYRZpYuSGRwzZHgU8EYW6rYU=";
url = "https://gerrit.wikimedia.org/r/plugins/gitiles/mediawiki/extensions/${project-name}/+archive/${commit}.tar.gz";
hash = "sha256-mLepavgeaNUGYxrrCKVpybGO2ecjc3B5IU8q+gZTx2U=";
stripRoot = false;
passthru = { inherit project-name tracking-branch; };
}

@@ -1,7 +1,13 @@
{ fetchzip }:
let
commit = "9ae0678d77a9175285a1cfadd5adf28379dbdb3d";
project-name = "SimpleSAMLphp";
tracking-branch = "REL1_41";
in
fetchzip {
name = "mediawiki-simple-saml-php-source";
url = "https://extdist.wmflabs.org/dist/extensions/SimpleSAMLphp-REL1_41-9ae0678.tar.gz";
hash = "sha256-AmCaG5QXMJvi3N6zFyWylwYDt8GvyIk/0GFpM1Y0vkY=";
url = "https://gerrit.wikimedia.org/r/plugins/gitiles/mediawiki/extensions/${project-name}/+archive/${commit}.tar.gz";
hash = "sha256-s6Uw1fNzGBF0HEMl0LIRLhJkOHugrCE0aTnqawYi/pE=";
stripRoot = false;
passthru = { inherit project-name tracking-branch; };
}

@@ -7,36 +7,54 @@ import re
import subprocess
from collections import defaultdict
from pprint import pprint
from dataclasses import dataclass
import bs4
import requests
BASE_URL = "https://extdist.wmflabs.org/dist/extensions"
BASE_URL = "https://gerrit.wikimedia.org/r/plugins/gitiles/mediawiki/extensions"
def fetch_plugin_list(skip_master=True) -> dict[str, list[str]]:
content = requests.get(BASE_URL).text
@dataclass
class PluginMetadata:
project_name: str
tracking_branch: str
commit: str
def get_metadata(file_content: str) -> dict[str,str] | None:
commit_search = re.search(f'commit = "([^"]*?)";', file_content)
tracking_branch_search = re.search(f'tracking-branch = "([^"]+?)";', file_content)
project_name_search = re.search(f'project-name = "([^"]+?)";', file_content)
if commit_search is None:
print("Could not find commit in file:")
print(file_content)
return None
if tracking_branch_search is None:
print("Could not find tracking branch in file:")
print(file_content)
return None
if project_name_search is None:
print("Could not find project name in file:")
print(file_content)
return None
return PluginMetadata(
commit = commit_search.group(1),
tracking_branch = tracking_branch_search.group(1),
project_name = project_name_search.group(1),
)
def get_newest_commit(project_name: str, tracking_branch: str) -> str:
content = requests.get(f"{BASE_URL}/{project_name}/+log/refs/heads/{tracking_branch}/").text
soup = bs4.BeautifulSoup(content, features="html.parser")
result = defaultdict(list)
for a in soup.find_all('a'):
if skip_master and 'master' in a.text:
continue
split = a.text.split('-')
result[split[0]].append(a.text)
return result
a = soup.find('li').findChild('a')
commit_sha = a['href'].split('/')[-1]
return commit_sha
def update(package_file: Path, plugin_list: dict[str, list[str]]) -> None:
assert package_file.is_file()
with open(package_file) as file:
content = file.read()
tarball = re.search(f'url = "{BASE_URL}/(.+\.tar\.gz)";', content).group(1)
split = tarball.split('-')
updated_tarball = plugin_list[split[0]][-1]
_hash = re.search(f'hash = "(.+?)";', content).group(1)
def get_nix_hash(tar_gz_url: str) -> str:
out, err = subprocess.Popen(
["nix-prefetch-url", "--unpack", "--type", "sha256", f"{BASE_URL}/{updated_tarball}"],
["nix-prefetch-url", "--unpack", "--type", "sha256", tar_gz_url],
stdout=subprocess.PIPE,
stderr=subprocess.PIPE
).communicate()
@@ -46,21 +64,43 @@ def update(package_file: Path, plugin_list: dict[str, list[str]]) -> None:
stderr=subprocess.PIPE
).communicate()
updated_hash = out.decode().strip()
return out.decode().strip()
if tarball == updated_tarball and _hash == updated_hash:
def set_commit_and_hash(file_content: str, commit: str, sha256: str) -> str:
result = file_content
result = re.sub('commit = "[^"]*";', f'commit = "{commit}";', result)
result = re.sub('hash = "[^"]*";', f'hash = "{sha256}";', result)
return result
def update(package_file: Path) -> None:
with open(package_file) as file:
file_content = file.read()
metadata = get_metadata(file_content)
if metadata is None:
return
if metadata.commit == "":
metadata.commit = "<none>"
new_commit = get_newest_commit(metadata.project_name, metadata.tracking_branch)
if new_commit == metadata.commit:
return
print(f"Updating: {tarball} ({_hash[7:14]}) -> {updated_tarball} ({updated_hash[7:14]})")
new_url = f"{BASE_URL}/{metadata.project_name}/+archive/{new_commit}.tar.gz"
new_hash = get_nix_hash(new_url)
print(f"Updating {metadata.project_name}: {metadata.commit} -> {new_commit}")
new_file_content = set_commit_and_hash(file_content, new_commit, new_hash)
updated_text = re.sub(f'url = "{BASE_URL}/.+?\.tar\.gz";', f'url = "{BASE_URL}/{updated_tarball}";', content)
updated_text = re.sub('hash = ".+";', f'hash = "{updated_hash}";', updated_text)
with open(package_file, 'w') as file:
file.write(updated_text)
file.write(new_file_content)
if __name__ == "__main__":
plugin_list = fetch_plugin_list()
for direntry in os.scandir(Path(__file__).parent):
if direntry.is_dir():
update(Path(direntry) / "default.nix", plugin_list)
package_file = Path(direntry) / "default.nix"
assert package_file.is_file()
update(package_file)

@@ -1,7 +1,13 @@
{ fetchzip }:
let
commit = "a53af3b8269ed19ede3cf1fa811e7ec8cb00af92";
project-name = "UserMerge";
tracking-branch = "REL1_41";
in
fetchzip {
name = "mediawiki-user-merge-source";
url = "https://extdist.wmflabs.org/dist/extensions/UserMerge-REL1_41-a53af3b.tar.gz";
hash = "sha256-TxUkEqMW79thYl1la2r+w9laRnd3uSYYg1xDB+1he1g=";
url = "https://gerrit.wikimedia.org/r/plugins/gitiles/mediawiki/extensions/${project-name}/+archive/${commit}.tar.gz";
hash = "sha256-0ofCZhhv4aVTGq469Fdu7k0oVQu3kG3HFa8zaBbUr/M=";
stripRoot = false;
passthru = { inherit project-name tracking-branch; };
}

@@ -1,7 +1,13 @@
{ fetchzip }:
let
commit = "bb92d4b0bb81cebd73a3dbabfb497213dac349f2";
project-name = "VisualEditor";
tracking-branch = "REL1_40";
in
fetchzip {
name = "mediawiki-visual-editor-source";
url = "https://extdist.wmflabs.org/dist/extensions/VisualEditor-REL1_40-5f8c97e.tar.gz";
hash = "sha256-oBMmEDKsFxrD0tpN2dy264IXK164BrZWrNK3v3FNX6w=";
url = "https://gerrit.wikimedia.org/r/plugins/gitiles/mediawiki/extensions/${project-name}/+archive/${commit}.tar.gz";
hash = "sha256-lShpSoR+NLfdd5i7soM6J40pq+MzCMG0M1tSYsS+jAg=";
stripRoot = false;
passthru = { inherit project-name tracking-branch; };
}

@@ -1,6 +1,7 @@
gitea:
password: ENC[AES256_GCM,data:hlNzdU1ope0t50/3aztyLeXjMHd2vFPpwURX+Iu8f49DOqgSnEMtV+KtLA==,iv:qljRnSnchL5cFmaUAfCH9GQYQxcy5cyWejgk1x6bFgI=,tag:tIhboFU5kZsj5oAQR3hLbw==,type:str]
database: ENC[AES256_GCM,data:UlS33IdCEyeSvT6ngpmnkBWHuSEqsB//DT+3b7C+UwbD8UXWJlsLf1X8/w==,iv:mPRW5ldyZaHP+y/0vC2JGSLZmlkhgmkvXPk4LazkSDs=,tag:gGk6Z/nbPvzE1zG+tJC8Sw==,type:str]
email-password: ENC[AES256_GCM,data:KRwC+aL1aPvJuXt91Oq1ttATMnFTnuUy,iv:ats8TygB/2pORkaTZzPOLufZ9UmvVAKoRcWNvYF1z6w=,tag:Do0fA+4cZ3+l7JJyu8hjBg==,type:str]
passwd-ssh-key: ENC[AES256_GCM,data:L0lF0wvpayss1NU9m3A45cH0bCMQzODTFVrq6EPd1JHx54wIcoaRBYLmxXKXASzBlCg9zlwXMUIk3OQcS3kdzMKL0iqcSL2iicAcKjFIHyrWLqXgwV5pRSP/tRPcVw8KW8gz0bh33EgESs5ReddZ3VZ0Cy1s2YupMRQvBXr89k1+Hv70OWB6P06hvxhv/zKcMGI1N/dWLroMgrQuT9imw4+/Q1RqwzTYeEU+eUn24AM9GjcBg4qf3OI+6g0nXUat/upIYE28iF5J3lbUSmDSmirBLc8xgHLdOyyJPTObWYWYxlSL78T7IqiMm9lI3rtBlpJDDcn/YxZpVqN5bg2154GISNK+uR0TVSLdJ+drdGHIfIX3G78XSxf2L9rbJyRn8MQlgStfdBIQicLavQKVMrmj+XQfvEMez23WbPLjH4oViBQFI+GrOHOGy/f16cz8Sn4n+69OcsOeTxs3tKYdfq6r1XLYSJ/fe/zvxBpaZiyGXljsuyEdIyBL2A8D6uSXe3Nd3/DAdBtceFfIdN1olCdutixzVWgxaJnrel161z5A/4w=,iv:Uy46yY3jFYSvpxrgCHxRMUksnWfhf5DViLMvCXVMMl4=,tag:wFEJ5+icFrOKkc56gY0A5g==,type:str]
ssh-known-hosts: ENC[AES256_GCM,data:zlRLoelQeumMxGqPmgMTB69X1RVWXIs2jWwc67lk0wrdNOHUs5UzV5TUA1JnQ43RslBU92+js7DkyvE5enGzw7zZE5F1ZYdGv/eCgvkTMC9BoLfzHzP6OzayPLYEt3xJ5PRocN8JUAD55cuu4LgsuebuydHPi2oWOfpbSUBKSeCh6dvk5Pp1XRDprPS5SzGLW8Xjq98QlzmfGv50meI9CDJZVF9Wq/72gkyfgtb3YVdr,iv:AF06TBitHegfWk6w07CdkHklh4ripQCmA45vswDQgss=,tag:zKh7WVXMJN2o9ZIwIkby3Q==,type:str]
import-user-env: ENC[AES256_GCM,data:vfaqjGEnUM9VtOPvBurz7nFwzGZt3L2EqijrQej4wiOcGCrRA4tN6kBV6NmhHqlFPsw=,iv:viPGkyOOacCWcgTu25da4qH7DC4wz2qdeC1W2WcMUdI=,tag:BllNqGQoaxqUo3lTz9LGnw==,type:str]
@@ -60,8 +61,8 @@ sops:
akVjeTNTeGorZjJQOVlMeCtPRUVYL3MK+VMvGxrbzGz4Q3sdaDDWjal+OiK+JYKX
GHiMXVHQJZu/RrlxMjHKN6V3iaqxZpuvLAEJ2Lzy5EOHPtuiiRyeHQ==
-----END AGE ENCRYPTED FILE-----
lastmodified: "2024-04-14T21:58:31Z"
mac: ENC[AES256_GCM,data:+o7YvaaKTjN/uZT5mv3z9FgIbXwG4NPJePWwRmtkBINn9X+vrCmYOXqWhKw7qfInn4Ftcg0FA7cYFZe5Pv8MNp+f8v1yoiLrVX12cxmEYtqTXJz7pNeD2st1YjGJKihNi2/fyCCf4YBCGN+8Ze//HeVf7/tfWNB+ysyC9g9Tze4=,iv:C6XBCVXn8GuNeaWGdJRnUIh1us0i8fSoxu9Sx7Feb58=,tag:W0RLPPv7eP5kCNrhMG3z7A==,type:str]
lastmodified: "2024-05-12T00:24:29Z"
mac: ENC[AES256_GCM,data:/fh5yc09YTLT62oWVsz2CwW/mhEUI7uRh5fDRgLNeeBc/4bvM3z83xmy9veehmQhhCWjju2/CtYhaihm3bUPN4hu3wVzviIxvrS9lTcBUG+F/AH4SnF5Z1CGWb94Gqi/6OhQRIpA6azjISyv8lTAQ4TCqcOC4fz/c9KjqQ/CiGY=,iv:HjzzMRFz3+kZ4iDLn9kI80BwMDALkRX5gyOHARZSgDA=,tag:1ez7NiIavshfp4CTZNkW/Q==,type:str]
pgp:
- created_at: "2023-05-21T00:28:40Z"
enc: |

@@ -0,0 +1,39 @@
bluemap_ssh_key: ENC[AES256_GCM,data:2kv/cDEEQMHJdwTmmTxtyxOZz8duggaT61U69IuiOJ2yuwqkujOHZ2gkCtGa1VyFPn6wg4OTiSA/Loz+QmTSKz+8HqvY/Lybks+offDZ1mukL5NiWLUVmNZdfdHaMeEyiZsxiMoWEgFtMiKvgmdMMPa/BCHZCMCxMWFAcuiZgbhGyGukdo0wQd5RcEDaY4JZ7q95ndAn4K7gi9q1K7MLOvI5t2hGibj8DrqriXqg9mahsiFZdKWxjf3tBX0MzS85wAtleQWXmH5FRvECmdOj3OSp92JMqU/WDlQih3xjnw1Ci3L/hdwgGLHZTf/RzuPpGh2OD26A7gUjOFh+M5z2dVVtZ40F8tQFxpQxkkJBsqTNbDKuw7/KPpZUJkn4UYBkhzraG/62md/9sS9+GjTHBhfYQYHbDU8ZbPO5ZSoZfshRDUuP0qYXiQw7cxA5BQIhwYdn26uy2ghiHsP713Tz91ESVjlCZLLduGySWEQNAxSdzFu9yEyp4xdl8l9udlnxVV2/5Xm5kQEdiUMwiBpUhrghdEl6lOzome5h,iv:uiYaQgOnhFvWze/oHGSpAu8+m89l4tGCgRauDzU3ZqE=,tag:eCYgCH+e8hNYpBIFWFOTbA==,type:str]
sops:
kms: []
gcp_kms: []
azure_kv: []
hc_vault: []
age:
- recipient: age1tmn5qahlyf0e579e4camckdyxrexjzffv54hdzdnrw7lzqs7kyqq0f2fr3
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSAvL2dqdHFwWURFSWJEUkVl
eXR2cTQyTXpzUEFra0drdUgzRUNmSXA4eGc0CmRoWnp5UUUyQy9kK0dHVjF3WkFp
M0loS1RXeWxHSGNTQUljS05jaDBxMDQKLS0tIDhyUGdvcE1iMWxJeWhYb3JFTi9q
Y0RrVHNhcVU3WFd2NitlQ3l4Ry9JTkEKALBawjOt7hChok/cHRa38HkB0KVEKvik
r2jO26j9AUU5mqjR/dIko3jvfcXoNUNRYrMwaBfRa6AFnNBoN3g0ng==
-----END AGE ENCRYPTED FILE-----
- recipient: age17tagmpwqjk3mdy45rfesrfey6h863x8wfq38wh33tkrlrywxducs0k6tpq
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBzV1R0cWxoTXNKNnpsUjE5
c01Oc3J5M2F2cDVKOTNma0J3eFVwa0pXQmpjCkdxRjJZTlFWSlh2UFR2emx4OVVY
T3gzSWdXNTlyS0VJSXRnTXZweER6V00KLS0tIGdFU3oxZ3lzQTBjU0hyYjV5M2cr
VnUvcGZDbEZuZitQS1g1NmRtb3JnNDAKV6otQlYUSF5ScyYL6LlstPU1pkLMY8r0
/NEuN9A7l2m9Wy8iItx+ZhwGp9pEPsgdsQLJQtJFfaA6lNuFhbgqfg==
-----END AGE ENCRYPTED FILE-----
- recipient: age1ju7rd26llahz3g8tz7cy5ld52swj8gsmg0flrmrxngc0nj0avq3ssh0sn5
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBNbmpMaWhpQTQzR05Cd0cw
b3dJRXVoUmFzZGxMeC9tVk9acndMemlrTHhzCkVtMHJ1bE94T25wRmpTZnpHbUdq
NzQ4T0pLZW56TEV2emQ5RHVXTDAvdmsKLS0tIFJ0OWxNYkIxOVBVV1hmZDdoeEhm
blB3M2JIMmk3Tmh6WjIzQjlHSW9GNDAKB3gdJL9AlF4fsCMujd/6HnieDwhCZnex
QDU87yTePHAppnqLp+ZuVdSbqcsnQclmbm92M3S6LuKpoDhGxeHrEw==
-----END AGE ENCRYPTED FILE-----
lastmodified: "2024-06-08T23:34:34Z"
mac: ENC[AES256_GCM,data:CLsz6UgS1LO/5SArmT7utald3TzQUWwEiSRw3dF1RaCwyb0Fc16/5DxJSk0KGLiJRlDXses/ynSjoyaBdTagijJPKQZCpx3fHZFqEJk6Wne4zQ4EoFbY1SpPrkhGVGMYaUg/H/NapoAEiq619YudR9W6GqF8ZkauXE76wls63FM=,iv:I09LFoSkeMAWHmvXtIF4+FURZ4tOQGCXQqbNrKz5t7s=,tag:xauT9sah+26A9pRrwXlsiQ==,type:str]
pgp: []
unencrypted_suffix: _unencrypted
version: 3.8.1