self: { config, pkgs, lib, system, ... }: let cfg = config.services.actual-importer; appConfig = (pkgs.formats.yaml {}).generate "actual-importer.config.yaml" cfg.config; app = pkgs.writeShellApplication { name = "actual-importer"; runtimeInputs = [self.packages.${system}.default]; text = '' actual-importer "$@" -c "${appConfig}"; ''; }; in with lib; { options.services.actual-importer = { enable = mkEnableOption "actual-importer"; server = { enable = mkEnableOption "actual-importer server"; port = mkOption { type = types.port; description = "The port on which importer will be listening on"; default = 3000; example = 8080; }; openFirewall = mkOption { type = types.bool; description = "Whether the configured port should be opened on firewall"; default = false; example = true; }; }; config = mkOption { type = types.attrs; description = "The actual-importer config which will be eventually converted to yaml"; example = { defaultProfile = "my-bank"; profiles = { my-bank = { parser = "pl.ing"; encoding = "utf8"; }; }; defaultServer = "main-server"; servers = { mainServer = { url = "https://my-server.com"; budget = "db353760-33d5-4a2a-ab73-5070a6863fe5"; account = "60b953ad-ce6c-4427-b727-bf37b4b6dd1b"; password = "$__file:/etc/passwords/actual.key"; data = "/tmp/actual"; }; }; }; }; }; config = mkIf cfg.enable { environment.systemPackages = [app]; systemd.services.actual-importer-server = mkIf cfg.server.enable { enable = true; description = "ActualBudget importer server"; wants = ["network.target"]; after = ["network.target"]; wantedBy = ["multi-user.target"]; serviceConfig = { ExecStart = "${self.packages.${system}.default}/bin/actual-importer serve ${toString cfg.server.port} -c ${appConfig}"; }; }; networking.firewall.allowedTCPPorts = mkIf cfg.server.openFirewall [cfg.server.port]; }; }