{ description = "Skynet LDAP backend"; inputs = { nixpkgs.url = "nixpkgs/nixos-23.05"; naersk.url = "github:nix-community/naersk"; utils.url = "github:numtide/flake-utils"; }; outputs = { self, nixpkgs, utils, naersk }: utils.lib.eachDefaultSystem (system: let pkgs = nixpkgs.legacyPackages."${system}"; naersk-lib = naersk.lib."${system}"; package_name = "skynet_ldap_backend"; package_update = "update_groups"; desc = "Skynet LDAP backend"; in rec { # `nix build` packages."${package_name}" = naersk-lib.buildPackage { pname = "${package_name}"; root = ./.; buildInputs = [ pkgs.openssl pkgs.pkg-config ]; }; defaultPackage = packages."${package_name}"; # `nix run` apps."${package_name}" = utils.lib.mkApp { drv = packages."${package_name}"; }; defaultApp = apps."${package_name}"; # `nix develop` devShell = pkgs.mkShell { nativeBuildInputs = with pkgs; [ rustc cargo ]; }; nixosModule = { lib, pkgs, config, ... }: with lib; let cfg = config.services."${package_name}"; enviroment_config = { # non secret ldap stuff LDAP_HOST = cfg.ldap.host; LDAP_ADMIN = cfg.ldap.admin; # basic dserver stuff DATABASE = "${cfg.home}/database.db"; HOST_PORT = cfg.host_port; # special categories of users USERS_ADMIN = lib.strings.concatStringsSep "," cfg.users.admin; USERS_COMMITTEE = lib.strings.concatStringsSep "," cfg.users.committee; USERS_LIFETIME = lib.strings.concatStringsSep "," cfg.users.lifetime; USERS_BANNED = lib.strings.concatStringsSep "," cfg.users.banned; }; in { options.services."${package_name}" = { enable = mkEnableOption "enable ${package_name}"; # keep really secret stuff in this envFile = mkOption rec { type = types.str; description = "The env file"; }; ldap = { host = mkOption rec { type = types.str; description = "LDAP Host"; }; admin = mkOption rec { type = types.str; description = "LDAP admin account dn"; }; }; users = { admin = mkOption rec { type = types.listOf types.str; default = []; description = "array of admins"; }; committee = mkOption rec { type = types.listOf types.str; default = []; description = "array of committee members"; }; lifetime = mkOption rec { type = types.listOf types.str; default = []; description = "array of lifetime users"; }; banned = mkOption rec { type = types.listOf types.str; default = []; description = "array of banned users"; }; }; host_port = mkOption rec { type = types.str; default = "127.0.0.1:8087"; description = "host/port for teh server tro run on"; }; # specific for teh program running user = mkOption rec { type = types.str; default = "${package_name}"; description = "The user to run the service"; }; home = mkOption rec { type = types.str; default = "/etc/skynet/${package_name}"; description = "The home for the user"; }; }; config = mkIf cfg.enable { users.groups."${cfg.user}" = { }; users.users."${cfg.user}" = { createHome = true; isSystemUser = true; home = "${cfg.home}"; group = "${cfg.user}"; }; systemd.services."${cfg.user}" = { description = desc; wantedBy = [ "multi-user.target" ]; after = [ "network-online.target" ]; wants = [ ]; environment = enviroment_config; serviceConfig = { # because we are storing data we need a home for it User = "${cfg.user}"; Group = "${cfg.user}"; Restart = "always"; ExecStart = "${self.defaultPackage."${system}"}/bin/${package_name}"; EnvironmentFile = "${cfg.envFile}"; }; }; # for updating the data systemd.services."${cfg.user}_update" = { description = "${desc} Update groups"; wantedBy = [ ]; after = [ "network-online.target" ]; environment = enviroment_config; serviceConfig = { Type = "oneshot"; DynamicUser = true; ExecStart = "${self.defaultPackage."${system}"}/bin/${package_update}"; EnvironmentFile = "${cfg.envFile}"; }; }; systemd.timers."${cfg.user}_update" = { description = "Run the update script for ${desc}"; wantedBy = [ "timers.target" ]; partOf = [ "${cfg.user}_update.service" ]; timerConfig = { # every hour OnCalendar = "*-*-* *:00:00"; Unit = "${cfg.user}_update.service"; }; }; }; }; }); }