summaryrefslogtreecommitdiffstats
path: root/krebs/3modules/hosts.nix
blob: fa83ec9e2cd65b3b02efde49829c99c0590fc61d (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
{ config, lib, pkgs, ... }:
with lib; let
  check = hostname: any (domain: hasSuffix ".${domain}" hostname) domains;
  domains = attrNames (filterAttrs (_: slib.eq "hosts") config.krebs.dns.providers);
  # we need this import because we have infinite recursion otherwise
  slib = import ../../lib/lib.nix { inherit lib; };
in {

  options = {
    krebs.hosts = mkOption {
      default = {};
      type = types.attrsOf slib.types.host;
    };
  };

  config = lib.mkIf config.krebs.enable {
    networking.hosts =
      filterAttrs
        (_name: value: value != [])
        (zipAttrsWith
          (_: concatLists)
          (concatMap
            (host:
              concatMap
                (net: let
                  aliases = longs ++ shorts;
                  longs = filter check net.aliases;
                  shorts = let s = ".${config.krebs.dns.search-domain}"; in
                    optionals
                      (config.krebs.dns.search-domain != null)
                      (map (removeSuffix s)
                           (filter (hasSuffix s)
                                   longs));
                in
                  map (addr: { ${addr} = aliases; }) net.addrs)
                (attrValues host.nets))
            (attrValues config.krebs.hosts)));

    nixpkgs.config.packageOverrides = super: let
      # nameValuePair name value : { "name" : name, "value" : value }

      # addr : str
      # aliase : str
      # hostname : str
      # netname : str

      # addrAliases : nameValuePair addr [alias]

      # hostNetAliases : host -> { ${netname} : [addrAliases] }
      hostNetAliases = host:
        mapAttrs (_: net: filter (x: x.name != null && x.value != []) [
          { name = net.ip4.addr or null; value = net.aliases; }
          { name = net.ip4.addr or null; value = (map (alias: "4.${alias}") net.aliases); }
          { name = net.ip6.addr or null; value = net.aliases; }
          { name = net.ip6.addr or null; value = (map (alias: "6.${alias}") net.aliases); }
        ]) host.nets;

      # netAliases : { ${netname} : [addrAliases] }
      netAliases =
        foldl'
          (result: host:
            foldl'
              # λ netAliases -> [addrAliases] -> netAliases
              (result: { name, value }: result // {
                ${name} = result.${name} or [] ++ value;
              })
              result
              (mapAttrsToList nameValuePair (hostNetAliases host))
          )
          {}
          (attrValues config.krebs.hosts);

      # writeHosts : str -> [addrAliases] -> package
      writeHosts = name: addrAliases: super.writeText name ''
        ${concatMapStringsSep
            "\n"
            ({ name, value }: "${name} ${toString value}")
            addrAliases}
      '';
    in
      {
        # hosts file for all krebs networks
        krebs-hosts =
          writeHosts "krebs-hosts" (concatLists [
            netAliases.internet
            netAliases.retiolum
            netAliases.wiregrill
          ]);

        # combined hosts file for all networks (even custom ones)
        krebs-hosts_combined =
          writeHosts "krebs-hosts_combined"
            (concatLists (attrValues netAliases));
      }
      //
      slib.genAttrs' (attrNames netAliases) (netname: rec {
        name = "krebs-hosts-${netname}";
        value = writeHosts name netAliases.${netname};
      });
  };

}