Commit e962dc50 authored by lschuetze's avatar lschuetze Committed by glyph
Browse files

sabnzbd: secrets management



Co-authored-by: default avatarSandro <sandro.jaeckel@gmail.com>
parent b0839dac
Loading
Loading
Loading
Loading
+19 −0
Original line number Diff line number Diff line
import sys
import os.path
from configobj import ConfigObj, ParseError

base = ConfigObj()

for path in sys.argv[1:]:
    if os.path.isfile(path):
        with open(path) as f:
            try:
              update = ConfigObj(f)
              base.merge(update)
            except ParseError as e:
              raise Exception(f"Failed to merge {path}") from e
    else:
        raise Exception(f"Instructed to merge {path} but not found or not a file")

for line in base.write():
    print(line)
+43 −1
Original line number Diff line number Diff line
@@ -145,6 +145,35 @@ in
        '';
      };

      secretFiles = mkOption {
        type = with types; listOf path;
        description = ''
          Path to a list of ini file containing confidential settings such as credentials.
          Settings here will be merged with the rest of the configuration (with
          the secret settings taking precedence in case of conflicts, and files
          that occur later in this list taking precedence over those that
          occur earlier).
          Recommended settings:
          - misc.api_key, misc.nzb_key, misc.username, misc.password
          - misc.email_account, misc.email_pwd if email alerts are enabled
          - servers.<name>.username, servers.<name>.password
        '';
        default = [ ];
      };

      allowConfigWrite = mkOption {
        type = types.bool;
        description = ''
          By default we create the sabnzbd configuration read-only,
          which keeps the nixos configuration as the single source
          of truth. If you want to enable configuration of
          sabnzbd via the web interface or use options that require
          a writeable configuration, such as quota tracking, enable
          this option.
        '';
        default = lib.versionOlder config.system.stateVersion "25.11";
      };

      settings = mkOption {
        description = ''
          The sabnzbd configuration (see also
@@ -481,7 +510,9 @@ in

    systemd.services.sabnzbd =
      let
        publicIniQuoted = lib.escapeShellArg publicSettingsIni;
        files =
          (lib.optional cfg.allowConfigWrite sabnzbdIniPath) ++ [ publicSettingsIni ] ++ cfg.secretFiles;
        iniPathQuoted = lib.escapeShellArg sabnzbdIniPath;
      in
      {
        description = "sabnzbd server";
@@ -495,6 +526,17 @@ in
          StateDirectory = cfg.stateDir;
          ExecStart = "${lib.getExe cfg.package} -d -f ${iniPathQuoted}";
        };
        preStart = ''
          set -euo pipefail

          ${lib.toShellVar "files" files}

          ${lib.getExe (pkgs.python3.withPackages (py: [ py.configobj ]))} \
            ${./config_merge.py} \
            "''${files[@]}" | \
          install -D -m ${if cfg.allowConfigWrite then "600" else "400"} \
            -o '${cfg.user}' -g '${cfg.group}' /dev/stdin ${iniPathQuoted}
        '';
      };

    networking.firewall = mkIf cfg.openFirewall {