aboutsummaryrefslogblamecommitdiff
path: root/modules/private/databases/openldap_replication.nix
blob: df4101be7c7e3398f10db7cd48fadca46b1d1256 (plain) (tree)
1
2
3
4
5
6
7
8
9
                           



                                                                       



                                                            




















































































































                                                                                      
                                                                                                                                                   








































                                                                                                              
{ pkgs, config, lib, ... }:
let
  cfg = config.myServices.databasesReplication.openldap;
  eldiron_schemas = pkgs.callPackage ./openldap/eldiron_schemas.nix {};
  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
    ${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 -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;
  };
}