]> git.immae.eu Git - perso/Immae/Config/Nix.git/blobdiff - systems/backup-2/databases/openldap_replication.nix
Squash changes containing private information
[perso/Immae/Config/Nix.git] / systems / backup-2 / databases / openldap_replication.nix
diff --git a/systems/backup-2/databases/openldap_replication.nix b/systems/backup-2/databases/openldap_replication.nix
new file mode 100644 (file)
index 0000000..b962224
--- /dev/null
@@ -0,0 +1,165 @@
+{ pkgs, config, lib, openldap, ... }:
+let
+  cfg = config.myServices.databasesReplication.openldap;
+  ldapConfig = hcfg: name: pkgs.writeText "slapd.conf" ''
+    include ${pkgs.openldap}/etc/schema/core.schema
+    include ${pkgs.openldap}/etc/schema/cosine.schema
+    include ${pkgs.openldap}/etc/schema/inetorgperson.schema
+    include ${pkgs.openldap}/etc/schema/nis.schema
+    include ${openldap.immae-schema}
+    pidfile   /run/slapd_${name}/slapd.pid
+    argsfile  /run/slapd_${name}/slapd.args
+
+    moduleload  back_mdb
+    backend     mdb
+    database    mdb
+
+    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.fullPaths."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.listToAttrs (lib.flatten (lib.mapAttrsToList (name: hcfg: [
+      (lib.nameValuePair "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}"
+          '';
+      })
+      (lib.nameValuePair "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 -Iminutes).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;
+  };
+}
+
+