forked from fabian/nix
		
	
		
			
				
	
	
		
			186 lines
		
	
	
	
		
			5.2 KiB
		
	
	
	
		
			Nix
		
	
	
	
	
	
			
		
		
	
	
			186 lines
		
	
	
	
		
			5.2 KiB
		
	
	
	
		
			Nix
		
	
	
	
	
	
{
 | 
						|
  config,
 | 
						|
  lib,
 | 
						|
  ...
 | 
						|
}:
 | 
						|
with lib; {
 | 
						|
  options.local.sys.nets = with lib.types;
 | 
						|
    mkOption {
 | 
						|
      readOnly = true;
 | 
						|
 | 
						|
      type = attrsOf (submodule ({config, ...}: {
 | 
						|
        options = let
 | 
						|
          v4config = config.v4;
 | 
						|
          v6config = config.v6;
 | 
						|
        in {
 | 
						|
          hosts = mkOption {
 | 
						|
            default = {};
 | 
						|
 | 
						|
            type = attrsOf (submodule {
 | 
						|
              options = {
 | 
						|
                v4 = mkOption {
 | 
						|
                  default = null;
 | 
						|
 | 
						|
                  type = nullOr (submodule ({config, ...}: {
 | 
						|
                    options = {
 | 
						|
                      suffix = mkOption {
 | 
						|
                        type = str;
 | 
						|
                      };
 | 
						|
 | 
						|
                      address = mkOption {
 | 
						|
                        type = str;
 | 
						|
                        readOnly = true;
 | 
						|
                      };
 | 
						|
 | 
						|
                      cidr = mkOption {
 | 
						|
                        type = str;
 | 
						|
                        readOnly = true;
 | 
						|
                      };
 | 
						|
 | 
						|
                      single = mkOption {
 | 
						|
                        type = str;
 | 
						|
                        readOnly = true;
 | 
						|
                      };
 | 
						|
                    };
 | 
						|
 | 
						|
                    config = {
 | 
						|
                      address =
 | 
						|
                        if v4config.bits == 0
 | 
						|
                        then config.suffix
 | 
						|
                        else if v4config.bits == 32
 | 
						|
                        then v4config.subnet
 | 
						|
                        else "${v4config.prefix}.${config.suffix}";
 | 
						|
 | 
						|
                      cidr = "${config.address}/${toString v4config.bits}";
 | 
						|
                      single = "${config.address}/32";
 | 
						|
                    };
 | 
						|
                  }));
 | 
						|
                };
 | 
						|
 | 
						|
                v6 = mkOption {
 | 
						|
                  default = null;
 | 
						|
 | 
						|
                  type = nullOr (submodule ({config, ...}: {
 | 
						|
                    options = {
 | 
						|
                      suffix = mkOption {
 | 
						|
                        type = str;
 | 
						|
                      };
 | 
						|
 | 
						|
                      address = mkOption {
 | 
						|
                        type = str;
 | 
						|
                        readOnly = true;
 | 
						|
                      };
 | 
						|
 | 
						|
                      cidr = mkOption {
 | 
						|
                        type = str;
 | 
						|
                        readOnly = true;
 | 
						|
                      };
 | 
						|
 | 
						|
                      single = mkOption {
 | 
						|
                        type = str;
 | 
						|
                        readOnly = true;
 | 
						|
                      };
 | 
						|
                    };
 | 
						|
 | 
						|
                    config = {
 | 
						|
                      address = let
 | 
						|
                        hextets = fragment: length (splitString ":" fragment);
 | 
						|
                        separator =
 | 
						|
                          if doubleColon
 | 
						|
                          then "::"
 | 
						|
                          else ":";
 | 
						|
                        doubleColon = hextets v6config.prefix + hextets config.suffix < 8;
 | 
						|
 | 
						|
                        joined =
 | 
						|
                          if v6config.bits == 128
 | 
						|
                          then v6config.prefix
 | 
						|
                          else if v6config.bits == 0
 | 
						|
                          then config.suffix
 | 
						|
                          else "${v6config.prefix}${separator}${config.suffix}";
 | 
						|
                      in
 | 
						|
                        joined;
 | 
						|
 | 
						|
                      cidr = "${config.address}/${toString v6config.bits}";
 | 
						|
                      single = "${config.address}/128";
 | 
						|
                    };
 | 
						|
                  }));
 | 
						|
                };
 | 
						|
              };
 | 
						|
            });
 | 
						|
          };
 | 
						|
 | 
						|
          v4 = mkOption {
 | 
						|
            default = null;
 | 
						|
 | 
						|
            type = nullOr (submodule ({config, ...}: {
 | 
						|
              options = {
 | 
						|
                bits = mkOption {
 | 
						|
                  type = enum [0 8 16 24 32];
 | 
						|
                };
 | 
						|
 | 
						|
                prefix = mkOption {
 | 
						|
                  type = str;
 | 
						|
                };
 | 
						|
 | 
						|
                subnet = mkOption {
 | 
						|
                  type = str;
 | 
						|
                  readOnly = true;
 | 
						|
                };
 | 
						|
 | 
						|
                cidr = mkOption {
 | 
						|
                  type = str;
 | 
						|
                  readOnly = true;
 | 
						|
                };
 | 
						|
              };
 | 
						|
 | 
						|
              config = {
 | 
						|
                cidr = "${config.subnet}/${toString config.bits}";
 | 
						|
                subnet =
 | 
						|
                  if config.bits != 0
 | 
						|
                  then config.prefix + strings.replicate (4 - config.bits / 8) ".0"
 | 
						|
                  else "0.0.0.0";
 | 
						|
              };
 | 
						|
            }));
 | 
						|
          };
 | 
						|
 | 
						|
          v6 = mkOption {
 | 
						|
            default = null;
 | 
						|
 | 
						|
            type = nullOr (submodule ({config, ...}: {
 | 
						|
              options = {
 | 
						|
                bits = mkOption {
 | 
						|
                  type =
 | 
						|
                    addCheck (ints.between 0 128) (b: mod b 4 == 0)
 | 
						|
                    // {
 | 
						|
                      description = "IPv6 subnet bits at nibble boundary";
 | 
						|
                    };
 | 
						|
                };
 | 
						|
 | 
						|
                prefix = mkOption {
 | 
						|
                  type = str;
 | 
						|
                };
 | 
						|
 | 
						|
                subnet = mkOption {
 | 
						|
                  type = str;
 | 
						|
                  readOnly = true;
 | 
						|
                };
 | 
						|
 | 
						|
                cidr = mkOption {
 | 
						|
                  type = str;
 | 
						|
                  readOnly = true;
 | 
						|
                };
 | 
						|
              };
 | 
						|
 | 
						|
              config = {
 | 
						|
                cidr = "${config.subnet}/${toString config.bits}";
 | 
						|
                subnet =
 | 
						|
                  if config.bits == 128 || length (splitString "::" config.prefix) > 1
 | 
						|
                  then config.prefix
 | 
						|
                  else "${config.prefix}::";
 | 
						|
              };
 | 
						|
            }));
 | 
						|
          };
 | 
						|
        };
 | 
						|
      }));
 | 
						|
    };
 | 
						|
}
 |