+{ pkgs, config, myconfig, lib, ... }:
+let
+ cfg = config.myServices.databasesReplication.openldap;
+ eldiron_schemas = pkgs.callPackage ./openldap/eldiron_schemas.nix {};
+ ldapConfig = hcfg: name: pkgs.writeText "slapd.conf" ''
+ ${eldiron_schemas}
+ pidfile /run/slapd_${name}/slapd.pid
+ argsfile /run/slapd_${name}/slapd.args
+
+ moduleload back_hdb
+ backend hdb
+ database hdb
+
+ suffix "${hcfg.base}"
+ rootdn "cn=root,${hcfg.base}"
+ directory ${cfg.base}/${name}/openldap
+
+ index objectClass eq
+ index uid pres,eq
+ index entryUUID eq
+
+ include ${config.secrets.location}/openldap_replication/${name}/replication_config
+ '';
+in
+{
+ options.myServices.databasesReplication.openldap = {
+ enable = lib.mkEnableOption "Enable openldap replication";
+ base = lib.mkOption {
+ type = lib.types.path;
+ description = ''
+ Base path to put the replications
+ '';
+ };
+ hosts = lib.mkOption {
+ default = {};
+ description = ''
+ Hosts to backup
+ '';
+ type = lib.types.attrsOf (lib.types.submodule {
+ options = {
+ package = lib.mkOption {
+ type = lib.types.package;
+ default = pkgs.openldap;
+ description = ''
+ Openldap package for this host
+ '';
+ };
+ url = lib.mkOption {
+ type = lib.types.str;
+ description = ''
+ Host to connect to
+ '';
+ };
+ base = lib.mkOption {
+ type = lib.types.str;
+ description = ''
+ Base DN to replicate
+ '';
+ };
+ dn = lib.mkOption {
+ type = lib.types.str;
+ description = ''
+ DN to use
+ '';
+ };
+ password = lib.mkOption {
+ type = lib.types.str;
+ description = ''
+ Password to use
+ '';
+ };
+ };
+ });
+ };
+ };
+
+ config = lib.mkIf cfg.enable {
+ users.users.openldap = {
+ description = "Openldap database user";
+ group = "openldap";
+ uid = config.ids.uids.openldap;
+ extraGroups = [ "keys" ];
+ };
+ users.groups.openldap.gid = config.ids.gids.openldap;
+
+ secrets.keys = lib.flatten (lib.mapAttrsToList (name: hcfg: [
+ {
+ dest = "openldap_replication/${name}/replication_config";
+ user = "openldap";
+ group = "openldap";
+ permissions = "0400";
+ text = ''
+ syncrepl rid=000
+ provider=${hcfg.url}
+ type=refreshAndPersist
+ searchbase="${hcfg.base}"
+ retry="5 10 300 +"
+ attrs="*,+"
+ schemachecking=off
+ bindmethod=simple
+ binddn="${hcfg.dn}"
+ credentials="${hcfg.password}"
+ '';
+ }
+ {
+ dest = "openldap_replication/${name}/replication_password";
+ user = "openldap";
+ group = "openldap";
+ permissions = "0400";
+ text = hcfg.password;
+ }
+ ]) cfg.hosts);
+
+ services.cron = {
+ enable = true;
+ systemCronJobs = lib.flatten (lib.mapAttrsToList (name: hcfg:
+ let
+ dataDir = "${cfg.base}/${name}/openldap";
+ backupDir = "${cfg.base}/${name}/openldap_backup";
+ backup_script = pkgs.writeScript "backup_openldap_${name}" ''
+ #!${pkgs.stdenv.shell}
+
+ ${hcfg.package}/bin/slapcat -b "${hcfg.base}" -f ${ldapConfig hcfg name} -l ${backupDir}/$(${pkgs.coreutils}/bin/date -Iseconds).ldif
+ '';
+ u = pkgs.callPackage ./utils.nix {};
+ cleanup_script = pkgs.writeScript "cleanup_openldap_${name}" (u.exponentialDumps "ldif" backupDir);
+ in [
+ "0 22,4,10,16 * * * root ${backup_script}"
+ "0 3 * * * root ${cleanup_script}"
+ ]) cfg.hosts);
+ };
+
+ system.activationScripts = lib.attrsets.mapAttrs' (name: hcfg:
+ lib.attrsets.nameValuePair "openldap_replication_${name}" {
+ deps = [ "users" "groups" ];
+ text = ''
+ install -m 0700 -o openldap -g openldap -d ${cfg.base}/${name}/openldap
+ install -m 0700 -o openldap -g openldap -d ${cfg.base}/${name}/openldap_backup
+ '';
+ }) cfg.hosts;
+
+ systemd.services = lib.attrsets.mapAttrs' (name: hcfg:
+ let
+ dataDir = "${cfg.base}/${name}/openldap";
+ in
+ lib.attrsets.nameValuePair "openldap_backup_${name}" {
+ description = "Openldap replication for ${name}";
+ wantedBy = [ "multi-user.target" ];
+ after = [ "network.target" ];
+ unitConfig.RequiresMountsFor = dataDir;
+
+ preStart = ''
+ mkdir -p /run/slapd_${name}
+ chown -R "openldap:openldap" /run/slapd_${name}
+ '';
+
+ serviceConfig = {
+ ExecStart = "${hcfg.package}/libexec/slapd -d 0 -u openldap -g openldap -f ${ldapConfig hcfg name}";
+ };
+ }) cfg.hosts;
+ };
+}
+
+