summaryrefslogtreecommitdiff
path: root/services/mysql.nix
blob: 83a50337fd0d5f56ab3d7a266d4ea328280349bb (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
{
  pkgs,
  config,
  lib,
  ...
}:
let
  cfg = config.wilkuu.services.mysql;

  create_users_ensure =
    uname:
    (lib.genAttrs (lib.map (dn: "${dn}.*") (
      lib.attrNames (lib.filterAttrs (_: dcfg: (builtins.elem uname dcfg.allowedUsers)) cfg.databases)
    )) (_: "ALL PRIVILEGES"));

  priviledge_clause =
    name: db: priv:
    ("GRANT ${priv} ON ${db} TO ${name};");

  add-user-clauses =
    name: ucfg:
    if (!isNull ucfg.sopsPlaceholder) then
      (
        ''
          -- Clauses for user ${name}
          ALTER USER IF EXISTS '${name}'@'%' IDENTIFIED BY '${ucfg.sopsPlaceholder}'; 
          CREATE USER IF NOT EXISTS '${name}'@'%' IDENTIFIED BY '${ucfg.sopsPlaceholder}';  
        ''
        + (lib.concatMapAttrsStringSep "\n" (priviledge_clause "'name'@'%'") (create_users_ensure name))
      )
    else
      " -- Ommitted user ${name}";

  add-unix-user-clauses =
    name:
    ''
      -- Clauses for user ${name}
      ALTER USER IF EXISTS '${name}'@'localhost' IDENTIFIED VIA unix_socket; 
      CREATE USER IF NOT EXISTS '${name}'@'localhost' IDENTIFIED VIA unix_socket;  
    ''
    + (lib.concatMapAttrsStringSep "\n" (priviledge_clause "'${name}'@'localhost'") (
      create_users_ensure name
    ));

in
{
  options.wilkuu.services.mysql = {
    enable = lib.mkEnableOption "Enable database for containers";
    port =
      with lib;
      mkOption {
        type = types.port;
        default = 3306;
      };
    databases =
      with lib;
      mkOption {
        type = types.attrsOf (
          types.submodule {
            options = {
              enable = mkEnableOption "Enable the database";
              allowedUsers = mkOption {
                type = types.listOf types.str;
              };
            };
          }
        );
        default = { };
      };
    users =
      with lib;
      mkOption {
        type = types.attrsOf (
          types.submodule {
            options = {
              scramPassword = mkOption {
                type = types.nullOr types.str;
                default = null;
              };
              sopsPlaceholder = mkOption {
                type = types.nullOr types.str;
                default = null;
              };
              allowedRanges = mkOption {
                type = types.listOf types.str;
              };
            };
          }
        );
        default = { };
      };
    unix_users = lib.mkOption {
      type = lib.types.listOf lib.types.str;
      description = "Users that can identify using the unix socket";
      default = [ ];
      example = [ "wakapi" ];
    };
  };
  # config.sops.secrets = lib.mkIf cfg.enable {
  #   "database/root_pass" = {
  #     sopsFile = ../secrets/${config.networking.hostName}/secrets.yaml;
  #   };
  # };
  config.sops.templates."init-mysql" = lib.mkIf cfg.enable {
    owner = config.systemd.services.mysql.serviceConfig.User;
    content = (
      lib.concatLines (
        (builtins.attrValues (builtins.mapAttrs add-user-clauses cfg.users))
        ++ (map add-unix-user-clauses cfg.unix_users)
        ++ [ "FLUSH PRIVILEGES;" ]
      )
    );
  };

  config.services.mysql = {
    enable = cfg.enable;
    ensureDatabases = builtins.attrNames cfg.databases;
    initialScript = config.sops.templates."init-mysql".path;
    package = pkgs.mariadb;
    settings = {
      mysqld = {
        # socket="/var/lib/mysql/mysql.sock";
        log_error = "/var/log/mysql_err.log";
        log_warnings = 2;
      };
    };
  };

  # config.host-config.utilpkgs = lib.mkIf (cfg.enable) (
  #   with pkgs;
  #   [
  #     mycli
  #   ]
  # );
}