223 lines
5.8 KiB
Nix
223 lines
5.8 KiB
Nix
{
|
|
config,
|
|
lib,
|
|
shb,
|
|
...
|
|
}:
|
|
let
|
|
cfg = config.shb.pinchflat;
|
|
|
|
inherit (lib) types;
|
|
in
|
|
{
|
|
imports = [
|
|
../../lib/module.nix
|
|
../blocks/nginx.nix
|
|
];
|
|
|
|
options.shb.pinchflat = {
|
|
enable = lib.mkEnableOption "the Pinchflat service.";
|
|
|
|
subdomain = lib.mkOption {
|
|
type = lib.types.str;
|
|
description = "Subdomain under which Pinchflat will be served.";
|
|
default = "pinchflat";
|
|
};
|
|
|
|
domain = lib.mkOption {
|
|
type = lib.types.str;
|
|
description = "domain under which Pinchflat will be served.";
|
|
example = "mydomain.com";
|
|
};
|
|
|
|
ssl = lib.mkOption {
|
|
description = "Path to SSL files";
|
|
type = lib.types.nullOr shb.contracts.ssl.certs;
|
|
default = null;
|
|
};
|
|
|
|
port = lib.mkOption {
|
|
type = lib.types.port;
|
|
description = "Port Pinchflat listens to incoming requests.";
|
|
default = 8945;
|
|
};
|
|
|
|
secretKeyBase = lib.mkOption {
|
|
description = ''
|
|
Used to sign/encrypt cookies and other secrets.
|
|
|
|
Make sure the secret is at least 64 characters long.
|
|
'';
|
|
type = types.submodule {
|
|
options = shb.contracts.secret.mkRequester {
|
|
restartUnits = [ "pinchflat.service" ];
|
|
};
|
|
};
|
|
};
|
|
|
|
mediaDir = lib.mkOption {
|
|
description = "Path where videos are stored.";
|
|
type = lib.types.str;
|
|
};
|
|
|
|
timeZone = lib.mkOption {
|
|
type = lib.types.oneOf [
|
|
lib.types.str
|
|
shb.secretFileType
|
|
];
|
|
description = "Timezone of this instance.";
|
|
example = "America/Los_Angeles";
|
|
};
|
|
|
|
ldap = lib.mkOption {
|
|
description = ''
|
|
Setup LDAP integration.
|
|
'';
|
|
default = { };
|
|
type = types.submodule {
|
|
options = {
|
|
enable = lib.mkEnableOption "LDAP integration." // {
|
|
default = cfg.sso.enable;
|
|
};
|
|
|
|
userGroup = lib.mkOption {
|
|
type = types.str;
|
|
description = "Group users must belong to be able to login.";
|
|
default = "pinchflat_user";
|
|
};
|
|
};
|
|
};
|
|
};
|
|
|
|
sso = lib.mkOption {
|
|
description = ''
|
|
Setup SSO integration.
|
|
'';
|
|
default = { };
|
|
type = types.submodule {
|
|
options = {
|
|
enable = lib.mkEnableOption "SSO integration.";
|
|
|
|
authEndpoint = lib.mkOption {
|
|
type = lib.types.str;
|
|
description = "Endpoint to the SSO provider.";
|
|
example = "https://authelia.example.com";
|
|
};
|
|
|
|
authorization_policy = lib.mkOption {
|
|
type = types.enum [
|
|
"one_factor"
|
|
"two_factor"
|
|
];
|
|
description = "Require one factor (password) or two factor (device) authentication.";
|
|
default = "one_factor";
|
|
};
|
|
};
|
|
};
|
|
};
|
|
|
|
backup = lib.mkOption {
|
|
description = ''
|
|
Backup media directory `shb.mediaDir`.
|
|
'';
|
|
default = { };
|
|
type = lib.types.submodule {
|
|
options = shb.contracts.backup.mkRequester {
|
|
user = "pinchflat";
|
|
sourceDirectories = [
|
|
cfg.mediaDir
|
|
];
|
|
sourceDirectoriesText = "[ config.shb.pinchflat.mediaDir ]";
|
|
};
|
|
};
|
|
};
|
|
|
|
dashboard = lib.mkOption {
|
|
description = ''
|
|
Dashboard contract consumer
|
|
'';
|
|
default = { };
|
|
type = lib.types.submodule {
|
|
options = shb.contracts.dashboard.mkRequester {
|
|
externalUrl = "https://${cfg.subdomain}.${cfg.domain}";
|
|
externalUrlText = "https://\${config.shb.pinchflat.subdomain}.\${config.shb.pinchflat.domain}";
|
|
internalUrl = "http://127.0.0.1:${toString cfg.port}";
|
|
};
|
|
};
|
|
};
|
|
};
|
|
|
|
config = lib.mkIf cfg.enable {
|
|
systemd.tmpfiles.rules = [
|
|
"d '/run/pinchflat' 0750 root root - -"
|
|
];
|
|
|
|
# Pinchflat relies on the global value so for now this is the only way to pass the option in.
|
|
time.timeZone = lib.mkDefault cfg.timeZone;
|
|
services.pinchflat = {
|
|
inherit (cfg) enable port mediaDir;
|
|
secretsFile = "/run/pinchflat/secrets.env";
|
|
extraConfig = {
|
|
ENABLE_PROMETHEUS = true;
|
|
# TZ = "as"; # I consider where you live to be sensible so it should be passed as a secret.
|
|
};
|
|
};
|
|
|
|
# This should be using a contract instead of setting the option directly.
|
|
shb.lldap = lib.mkIf config.shb.lldap.enable {
|
|
ensureGroups = {
|
|
${cfg.ldap.userGroup} = { };
|
|
};
|
|
};
|
|
|
|
systemd.services.pinchflat-pre = {
|
|
script = shb.replaceSecrets {
|
|
userConfig = {
|
|
SECRET_KEY_BASE.source = cfg.secretKeyBase.result.path;
|
|
# TZ = cfg.secretKeyBase.result.path; # Uncomment when PR is merged.
|
|
};
|
|
resultPath = "/run/pinchflat/secrets.env";
|
|
generator = shb.toEnvVar;
|
|
};
|
|
serviceConfig.Type = "oneshot";
|
|
wantedBy = [ "multi-user.target" ];
|
|
before = [ "pinchflat.service" ];
|
|
requiredBy = [ "pinchflat.service" ];
|
|
};
|
|
|
|
shb.nginx.vhosts = [
|
|
(
|
|
{
|
|
inherit (cfg) subdomain domain ssl;
|
|
|
|
upstream = "http://127.0.0.1:${toString cfg.port}";
|
|
autheliaRules = lib.optionals (cfg.sso.enable) [
|
|
{
|
|
domain = "${cfg.subdomain}.${cfg.domain}";
|
|
policy = cfg.sso.authorization_policy;
|
|
subject = [ "group:${cfg.ldap.userGroup}" ];
|
|
}
|
|
];
|
|
}
|
|
// lib.optionalAttrs cfg.sso.enable {
|
|
inherit (cfg.sso) authEndpoint;
|
|
}
|
|
)
|
|
];
|
|
|
|
services.prometheus.scrapeConfigs = [
|
|
{
|
|
job_name = "pinchflat";
|
|
static_configs = [
|
|
{
|
|
targets = [ "127.0.0.1:${toString cfg.port}" ];
|
|
labels = {
|
|
"hostname" = config.networking.hostName;
|
|
"domain" = cfg.domain;
|
|
};
|
|
}
|
|
];
|
|
}
|
|
];
|
|
};
|
|
}
|