summaryrefslogtreecommitdiffstats
path: root/3modules/tv/identity.nix
blob: 584b27165e4e04ce80cd382a7ab0458410b84e15 (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
{ config, lib, pkgs, ... }:

with import ../../4lib/tv { inherit lib pkgs; };
let
  cfg = config.tv.identity;

  out = {
    options.tv.identity = api;
    config = mkIf cfg.enable imp;
  };

  api = {
    enable = mkEnableOption "tv.identity";

    self = mkOption {
      type = types.host;
    };

    #others = mkOption {
    #  type = types.host;
    #  default = filterAttrs (name: _host: name != cfg.self.name) cfg.hosts;
    #};

    hosts = mkOption {
      type = with types; attrsOf host;
      apply = mapAttrs (name: value: value // { inherit name; });
    };

    search = mkOption {
      type = types.hostname;
    };
  };

  imp = {
    networking.extraHosts =
      concatStringsSep "\n" (flatten (
        # TODO deepMap ["hosts" "nets"] (hostname: host: netname: net:
        mapAttrsToList (hostname: host:
          mapAttrsToList (netname: net:
            let
              aliases = toString (unique (longs ++ shorts));
              longs = (splitByProvider net.aliases).hosts;
              shorts = map (removeSuffix ".${cfg.search}") longs;
            in
            map (addr: "${addr} ${aliases}") net.addrs
          ) host.nets
        ) cfg.hosts
      ));
  };

  # TODO move domain name providers to a dedicated module
  # providers : tree label providername
  providers = {
    internet = "hosts";
    retiolum = "hosts";
    de.viljetic = "regfish";
    de.krebsco = "ovh";
  };

  # splitByProvider : [alias] -> set providername [alias]
  splitByProvider = foldl (acc: alias: insert (providerOf alias) alias acc) {};

  # providerOf : alias -> providername
  providerOf = alias:
    tree-get (splitString "." alias) providers;

  # insert : k -> v -> set k [v] -> set k [v]
  insert = name: value: set:
    set // { ${name} = set.${name} or [] ++ [value]; };

  # tree k v = set k (either v (tree k v))

  # tree-get : [k] -> tree k v -> v
  tree-get = path: x:
    let
      y = x.${last path};
    in
    if typeOf y != "set"
      then y
      else tree-get (init path) y;
in
out