let
  mkDefaultInterface = _: attrs: { ipv4 = [ ]; ipv6 = [ ]; gateways = [ ]; } // attrs;

  mkBase = config: config // { interfaces = builtins.mapAttrs mkDefaultInterface (config.interfaces or { }); };

  getAddresses = version: interface: builtins.map (builtins.getAttr "address") interface.${version};

  filterIPv4 = ip: builtins.substring 0 7 ip != "192.168";
  filterIPv6 = _: true;

  mkNet = _: value:
    let base = mkBase value; in
    base // {
      addresses =
        let
          _addresses = builtins.foldl'
            ({ ipv4, ipv6 }: net: {
              ipv4 = ipv4 ++ getAddresses "ipv4" net;
              ipv6 = ipv6 ++ getAddresses "ipv6" net;
            })
            { ipv4 = [ ]; ipv6 = [ ]; }
            (builtins.attrValues base.interfaces);
        in
        _addresses // rec {
          publicV4 = builtins.filter filterIPv4 _addresses.ipv4;
          publicV6 = builtins.filter filterIPv6 _addresses.ipv6;
          public = publicV4 ++ publicV6;
        };
    };
in

builtins.mapAttrs mkNet {
  compute01 = {
    interfaces = {
      eno1 = {
        ipv4 = [
          { address = "129.199.146.147"; prefixLength = 24; }
          { address = "192.168.1.147"; prefixLength = 24; }
        ];

        gateways = [ "129.199.146.254" ];
      };
    };

    hostId = "8df60941";
  };

  storage01 = {
    interfaces = {
      eno1 = {
        ipv4 = [
          { address = "129.199.146.148"; prefixLength = 24; }
          { address = "192.168.1.148"; prefixLength = 24; }
        ];

        gateways = [ "129.199.146.254" ];
      };
    };

    hostId = "d4e7c369";
  };

  web01 = {
    interfaces = {
      ens3 = {
        ipv4 = [{ address = "129.199.129.53"; prefixLength = 24; }];

        gateways = [ "129.199.129.1" ];
      };
    };

    hostId = "050df79e";
  };
}