Better addressing?
This commit is contained in:
parent
b5c1a43863
commit
f35e402b4d
3 changed files with 394 additions and 261 deletions
42
flake.nix
42
flake.nix
|
|
@ -10,67 +10,48 @@
|
||||||
|
|
||||||
outputs = { self, nixpkgs, deploy-rs, disko, nixos-anywhere, ... }:
|
outputs = { self, nixpkgs, deploy-rs, disko, nixos-anywhere, ... }:
|
||||||
let
|
let
|
||||||
# Default architecture if a system doesn’t override it
|
|
||||||
defaultSystem = "x86_64-linux";
|
defaultSystem = "x86_64-linux";
|
||||||
|
|
||||||
# pkgs per-system so cross-arch doesn’t explode later
|
|
||||||
pkgsFor = system: import nixpkgs { inherit system; };
|
pkgsFor = system: import nixpkgs { inherit system; };
|
||||||
|
|
||||||
lib = nixpkgs.lib;
|
lib = nixpkgs.lib;
|
||||||
|
|
||||||
# World spec & addressing
|
|
||||||
meta = import ./meta.nix;
|
meta = import ./meta.nix;
|
||||||
addressing = import ./lib/addressing { inherit lib; };
|
addressing = import ./lib/addressing { inherit lib; };
|
||||||
|
|
||||||
# Optional for now; meta.systems can be {} until the systems submodule lands
|
|
||||||
systemsFromMeta = meta.systems or { };
|
systemsFromMeta = meta.systems or { };
|
||||||
|
|
||||||
# Precomputed full network view
|
|
||||||
network = addressing.mkNetworkFromSpec meta;
|
network = addressing.mkNetworkFromSpec meta;
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
########################
|
|
||||||
# Library exports
|
|
||||||
########################
|
|
||||||
|
|
||||||
lib.metanix = {
|
lib.metanix = {
|
||||||
inherit meta addressing network;
|
inherit meta addressing network;
|
||||||
};
|
};
|
||||||
|
|
||||||
########################
|
|
||||||
# NixOS configurations
|
|
||||||
########################
|
|
||||||
|
|
||||||
nixosConfigurations =
|
nixosConfigurations =
|
||||||
lib.mapAttrs
|
lib.mapAttrs
|
||||||
(name: sysCfg:
|
(name: sysCfg:
|
||||||
let
|
let
|
||||||
# System for this host, fallback to default
|
|
||||||
system = sysCfg.system or defaultSystem;
|
system = sysCfg.system or defaultSystem;
|
||||||
pkgs = pkgsFor system;
|
|
||||||
in
|
in
|
||||||
lib.nixosSystem {
|
lib.nixosSystem {
|
||||||
inherit system;
|
inherit system;
|
||||||
|
|
||||||
# Make meta/addressing/world visible to modules
|
|
||||||
specialArgs = {
|
specialArgs = {
|
||||||
inherit lib pkgs meta addressing system;
|
inherit lib meta addressing system network;
|
||||||
modulesPath = builtins.toString <nixpkgs/nixos/modules>;
|
modulesPath = "${nixpkgs}/nixos/modules";
|
||||||
};
|
};
|
||||||
|
|
||||||
modules =
|
modules =
|
||||||
(sysCfg.modules or [ ]) ++ [
|
(sysCfg.modules or [ ]) ++ [
|
||||||
# Core Metanix wiring
|
|
||||||
./modules/metanix/core.nix
|
./modules/metanix/core.nix
|
||||||
./modules/metanix/networkd.nix
|
./modules/metanix/networkd.nix
|
||||||
|
|
||||||
# Identity binding: “this box is <name> in Metanix”
|
|
||||||
{
|
{
|
||||||
networking.hostName = sysCfg.hostName or name;
|
networking.hostName = sysCfg.hostName or name;
|
||||||
metanix.thisHost = sysCfg.metanixName or name;
|
metanix.thisHost = sysCfg.metanixName or name;
|
||||||
}
|
}
|
||||||
|
|
||||||
# Optional Disko integration per host
|
|
||||||
(if sysCfg ? diskoConfig then
|
(if sysCfg ? diskoConfig then
|
||||||
{
|
{
|
||||||
imports = [
|
imports = [
|
||||||
|
|
@ -84,10 +65,6 @@
|
||||||
})
|
})
|
||||||
systemsFromMeta;
|
systemsFromMeta;
|
||||||
|
|
||||||
########################
|
|
||||||
# deploy-rs
|
|
||||||
########################
|
|
||||||
|
|
||||||
deploy = {
|
deploy = {
|
||||||
nodes =
|
nodes =
|
||||||
lib.mapAttrs
|
lib.mapAttrs
|
||||||
|
|
@ -97,7 +74,10 @@
|
||||||
hostInfo = if hasNetworkHost then network.hosts.${name} else null;
|
hostInfo = if hasNetworkHost then network.hosts.${name} else null;
|
||||||
|
|
||||||
defaultHostname =
|
defaultHostname =
|
||||||
if hasNetworkHost then hostInfo.fqdn else "${name}.${meta.domain}";
|
if hasNetworkHost && hostInfo ? fqdn then
|
||||||
|
hostInfo.fqdn
|
||||||
|
else
|
||||||
|
name;
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
hostname = sysCfg.deployHost or defaultHostname;
|
hostname = sysCfg.deployHost or defaultHostname;
|
||||||
|
|
@ -112,12 +92,10 @@
|
||||||
systemsFromMeta;
|
systemsFromMeta;
|
||||||
};
|
};
|
||||||
|
|
||||||
checks.${defaultSystem}.deploy =
|
checks =
|
||||||
deploy-rs.lib.${defaultSystem}.deployChecks self.deploy;
|
builtins.mapAttrs
|
||||||
|
(system: deployLib: deployLib.deployChecks self.deploy)
|
||||||
########################
|
deploy-rs.lib;
|
||||||
# nixos-anywhere helper
|
|
||||||
########################
|
|
||||||
|
|
||||||
apps.${defaultSystem}.nixos-anywhere = {
|
apps.${defaultSystem}.nixos-anywhere = {
|
||||||
type = "app";
|
type = "app";
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
{ lib ? import <nixpkgs/lib> { } }:
|
{ lib, ... }:
|
||||||
|
|
||||||
let
|
let
|
||||||
inherit (lib)
|
inherit (lib)
|
||||||
|
|
@ -6,27 +6,26 @@ let
|
||||||
attrNames
|
attrNames
|
||||||
concatMapAttrs
|
concatMapAttrs
|
||||||
concatStringsSep
|
concatStringsSep
|
||||||
|
filterAttrs
|
||||||
listToAttrs
|
listToAttrs
|
||||||
|
mapAttrs'
|
||||||
nameValuePair
|
nameValuePair
|
||||||
optionalAttrs
|
optionalAttrs
|
||||||
imap1
|
imap1
|
||||||
mapAttrs'
|
|
||||||
imap0
|
imap0
|
||||||
length
|
length
|
||||||
filter
|
filter
|
||||||
findFirst
|
findFirst
|
||||||
toLower;#
|
toLower
|
||||||
|
unique;
|
||||||
|
|
||||||
mkInitials =
|
mkInitials =
|
||||||
name:
|
name:
|
||||||
let
|
let
|
||||||
lower = toLower name; # was builtins.toLower
|
lower = toLower name;
|
||||||
noApos = builtins.replaceStrings [ "'" ] [ " " ] lower;
|
noApos = builtins.replaceStrings [ "'" ] [ " " ] lower;
|
||||||
words = filter (w: w != "") (builtins.split " +" noApos);
|
words = filter (w: w != "") (builtins.split " +" noApos);
|
||||||
letters =
|
letters = concatStringsSep "" (builtins.map (w: builtins.substring 0 1 w) words);
|
||||||
concatStringsSep ""
|
|
||||||
(builtins.map (w: builtins.substring 0 1 w) words);
|
|
||||||
in
|
in
|
||||||
if letters == "" then "loc" else builtins.substring 0 3 letters;
|
if letters == "" then "loc" else builtins.substring 0 3 letters;
|
||||||
|
|
||||||
|
|
@ -38,7 +37,7 @@ let
|
||||||
in
|
in
|
||||||
"${base}-${hash}";
|
"${base}-${hash}";
|
||||||
|
|
||||||
# Manual elemIndex so we don't care what nixpkgs version you're on
|
# Manual elemIndex so we do not care what nixpkgs version you are on.
|
||||||
elemIndex =
|
elemIndex =
|
||||||
name: list:
|
name: list:
|
||||||
let
|
let
|
||||||
|
|
@ -180,9 +179,9 @@ let
|
||||||
mkRoleRangeNamed =
|
mkRoleRangeNamed =
|
||||||
{ location, typeName, roleName }:
|
{ location, typeName, roleName }:
|
||||||
let
|
let
|
||||||
_ = assertMsg (subnetTypes ? typeName)
|
_ = assertMsg (builtins.hasAttr typeName subnetTypes)
|
||||||
"metatron-addressing: unknown subnet type '${typeName}'";
|
"metatron-addressing: unknown subnet type '${typeName}'";
|
||||||
__ = assertMsg (roles ? roleName)
|
__ = assertMsg (builtins.hasAttr roleName roles)
|
||||||
"metatron-addressing: unknown role '${roleName}'";
|
"metatron-addressing: unknown role '${roleName}'";
|
||||||
|
|
||||||
type = subnetTypes.${typeName};
|
type = subnetTypes.${typeName};
|
||||||
|
|
@ -193,9 +192,9 @@ let
|
||||||
mkIpNamed =
|
mkIpNamed =
|
||||||
{ location, typeName, roleName, host }:
|
{ location, typeName, roleName, host }:
|
||||||
let
|
let
|
||||||
_ = assertMsg (subnetTypes ? typeName)
|
_ = assertMsg (builtins.hasAttr typeName subnetTypes)
|
||||||
"metatron-addressing: unknown subnet type '${typeName}'";
|
"metatron-addressing: unknown subnet type '${typeName}'";
|
||||||
__ = assertMsg (roles ? roleName)
|
__ = assertMsg (builtins.hasAttr roleName roles)
|
||||||
"metatron-addressing: unknown role '${roleName}'";
|
"metatron-addressing: unknown role '${roleName}'";
|
||||||
|
|
||||||
type = subnetTypes.${typeName};
|
type = subnetTypes.${typeName};
|
||||||
|
|
@ -217,7 +216,7 @@ let
|
||||||
mkSubnetNamed =
|
mkSubnetNamed =
|
||||||
{ location, typeName }:
|
{ location, typeName }:
|
||||||
let
|
let
|
||||||
_ = assertMsg (subnetTypes ? typeName)
|
_ = assertMsg (builtins.hasAttr typeName subnetTypes)
|
||||||
"metatron-addressing: unknown subnet type '${typeName}'";
|
"metatron-addressing: unknown subnet type '${typeName}'";
|
||||||
type = subnetTypes.${typeName};
|
type = subnetTypes.${typeName};
|
||||||
in
|
in
|
||||||
|
|
@ -236,18 +235,59 @@ let
|
||||||
mkVlanNamed =
|
mkVlanNamed =
|
||||||
{ location, typeName }:
|
{ location, typeName }:
|
||||||
let
|
let
|
||||||
_ = assertMsg (subnetTypes ? typeName)
|
_ = assertMsg (builtins.hasAttr typeName subnetTypes)
|
||||||
"metatron-addressing: unknown subnet type '${typeName}'";
|
"metatron-addressing: unknown subnet type '${typeName}'";
|
||||||
type = subnetTypes.${typeName};
|
type = subnetTypes.${typeName};
|
||||||
in
|
in
|
||||||
mkVlan { inherit location type; };
|
mkVlan { inherit location type; };
|
||||||
|
|
||||||
# locationName → numeric id (0, 1, 2, …)
|
asList = value:
|
||||||
|
if value == null then [ ]
|
||||||
|
else if builtins.isList value then value
|
||||||
|
else [ value ];
|
||||||
|
|
||||||
|
scopeFromCfg = cfg: {
|
||||||
|
owners =
|
||||||
|
asList (cfg.owners or null)
|
||||||
|
++ asList (cfg.owner or null);
|
||||||
|
admins =
|
||||||
|
asList (cfg.admins or null)
|
||||||
|
++ asList (cfg.admin or null);
|
||||||
|
users = asList (cfg.users or null);
|
||||||
|
domain = cfg.domain or null;
|
||||||
|
};
|
||||||
|
|
||||||
|
mergeScopes = parent: child:
|
||||||
|
let
|
||||||
|
c = scopeFromCfg child;
|
||||||
|
in
|
||||||
|
{
|
||||||
|
owners = unique (parent.owners ++ c.owners);
|
||||||
|
admins = unique (parent.admins ++ c.admins);
|
||||||
|
users = unique (parent.users ++ c.users);
|
||||||
|
domain = if c.domain != null then c.domain else parent.domain;
|
||||||
|
};
|
||||||
|
|
||||||
|
emptyScope = {
|
||||||
|
owners = [ ];
|
||||||
|
admins = [ ];
|
||||||
|
users = [ ];
|
||||||
|
domain = null;
|
||||||
|
};
|
||||||
|
|
||||||
|
materializeScope = scope:
|
||||||
|
{
|
||||||
|
inherit (scope) owners admins users;
|
||||||
|
}
|
||||||
|
// optionalAttrs (scope.domain != null) {
|
||||||
|
inherit (scope) domain;
|
||||||
|
};
|
||||||
|
|
||||||
|
# locationName -> numeric id (0, 1, 2, ...)
|
||||||
locationIdForSpec =
|
locationIdForSpec =
|
||||||
spec:
|
spec:
|
||||||
let
|
let
|
||||||
locations =
|
locations = spec.locations or (throw "metatron-addressing: spec.locations is required");
|
||||||
spec.locations or(throw "metatron-addressing: spec.locations is required");
|
|
||||||
locationNames = attrNames locations;
|
locationNames = attrNames locations;
|
||||||
in
|
in
|
||||||
name:
|
name:
|
||||||
|
|
@ -259,42 +299,29 @@ let
|
||||||
else
|
else
|
||||||
idx;
|
idx;
|
||||||
|
|
||||||
# Just the host map: { deimos = { ip-address = "..."; fqdn = "..."; ... }; ... }
|
hostRole = path: hostCfg:
|
||||||
mkHostsFromSpec =
|
hostCfg.role or (throw "metatron-addressing: host '${path}' is missing required field 'role' for address generation");
|
||||||
spec:
|
|
||||||
let
|
|
||||||
locations =
|
|
||||||
spec.locations or (throw "metatron-addressing: spec.locations is required");
|
|
||||||
locationId = locationIdForSpec spec;
|
|
||||||
domain =
|
|
||||||
spec.domain or (throw "metatron-addressing: spec.domain is required for FQDN generation");
|
|
||||||
in
|
|
||||||
concatMapAttrs
|
|
||||||
(locationName: locationCfg:
|
|
||||||
let
|
|
||||||
loc = locationId locationName;
|
|
||||||
locCode = mkLocationCode locationName;
|
|
||||||
|
|
||||||
# Only treat attributes that are attrsets with a `hosts` attr as subnets
|
hostMapForSubnet =
|
||||||
subnets =
|
{ loc, locCode, locationName, networkName, typeName, subnetCfg, scope }:
|
||||||
lib.filterAttrs (_: v: builtins.isAttrs v && v ? hosts) locationCfg;
|
|
||||||
in
|
|
||||||
concatMapAttrs
|
|
||||||
(typeName: subnetCfg:
|
|
||||||
let
|
let
|
||||||
hostsForSubnet = subnetCfg.hosts or { };
|
hostsForSubnet = subnetCfg.hosts or { };
|
||||||
|
hostNames = filter (hn: builtins.substring 0 1 hn != "_") (attrNames hostsForSubnet);
|
||||||
|
|
||||||
# Only treat non-underscore-prefixed keys as hosts
|
subnetSlug =
|
||||||
hostNames =
|
if builtins.hasAttr typeName subnetSlugs
|
||||||
filter (hn: builtins.substring 0 1 hn != "_") (attrNames hostsForSubnet);
|
then subnetSlugs.${typeName}
|
||||||
|
else typeName;
|
||||||
in
|
in
|
||||||
listToAttrs (imap1
|
listToAttrs (imap1
|
||||||
(idx: hostName:
|
(idx: hostName:
|
||||||
let
|
let
|
||||||
|
path = "${locationName}.${networkName}.${typeName}.${hostName}";
|
||||||
hostCfg = hostsForSubnet.${hostName};
|
hostCfg = hostsForSubnet.${hostName};
|
||||||
roleName = hostCfg.role;
|
hostScope = mergeScopes scope hostCfg;
|
||||||
|
roleName = hostRole path hostCfg;
|
||||||
|
|
||||||
# Count how many hosts of this role exist up to *and including* this one
|
# Count how many hosts of this role exist up to and including this one.
|
||||||
roleIndex =
|
roleIndex =
|
||||||
let
|
let
|
||||||
prefix = lib.lists.sublist 0 idx hostNames;
|
prefix = lib.lists.sublist 0 idx hostNames;
|
||||||
|
|
@ -308,15 +335,10 @@ let
|
||||||
ip = mkIpNamed {
|
ip = mkIpNamed {
|
||||||
location = loc;
|
location = loc;
|
||||||
inherit typeName;
|
inherit typeName;
|
||||||
roleName = hostCfg.role;
|
roleName = roleName;
|
||||||
host = hostId;
|
host = hostId;
|
||||||
};
|
};
|
||||||
|
|
||||||
subnetSlug =
|
|
||||||
if builtins.hasAttr typeName subnetSlugs
|
|
||||||
then subnetSlugs.${typeName}
|
|
||||||
else typeName;
|
|
||||||
|
|
||||||
roleSlug =
|
roleSlug =
|
||||||
if builtins.hasAttr roleName roleSlugs
|
if builtins.hasAttr roleName roleSlugs
|
||||||
then roleSlugs.${roleName}
|
then roleSlugs.${roleName}
|
||||||
|
|
@ -324,19 +346,21 @@ let
|
||||||
|
|
||||||
hostnameBase = "${roleSlug}-${builtins.toString hostId}";
|
hostnameBase = "${roleSlug}-${builtins.toString hostId}";
|
||||||
hostname = hostCfg.hostname or hostnameBase;
|
hostname = hostCfg.hostname or hostnameBase;
|
||||||
|
|
||||||
fqdn = "${hostname}.${subnetSlug}.${locCode}.${domain}";
|
|
||||||
in
|
in
|
||||||
nameValuePair hostName (
|
nameValuePair hostName (
|
||||||
{
|
{
|
||||||
ip-address = ip;
|
ip-address = ip;
|
||||||
inherit hostname fqdn;
|
inherit hostname;
|
||||||
|
|
||||||
# New context fields:
|
|
||||||
location = locationName;
|
location = locationName;
|
||||||
|
network = networkName;
|
||||||
subnetType = typeName;
|
subnetType = typeName;
|
||||||
subnetKey = "${locationName}-${typeName}";
|
subnetKey = "${locationName}-${networkName}-${typeName}";
|
||||||
}
|
}
|
||||||
|
// optionalAttrs (hostScope.domain != null) {
|
||||||
|
fqdn = "${hostname}.${subnetSlug}.${locCode}.${hostScope.domain}";
|
||||||
|
}
|
||||||
|
// materializeScope hostScope
|
||||||
// optionalAttrs (hostCfg ? hw-address) {
|
// optionalAttrs (hostCfg ? hw-address) {
|
||||||
inherit (hostCfg) hw-address;
|
inherit (hostCfg) hw-address;
|
||||||
}
|
}
|
||||||
|
|
@ -349,35 +373,70 @@ let
|
||||||
// optionalAttrs (hostCfg ? interface) {
|
// optionalAttrs (hostCfg ? interface) {
|
||||||
inherit (hostCfg) interface;
|
inherit (hostCfg) interface;
|
||||||
}
|
}
|
||||||
)
|
// optionalAttrs (hostCfg ? tags) {
|
||||||
)
|
inherit (hostCfg) tags;
|
||||||
hostNames))
|
}
|
||||||
subnets)
|
))
|
||||||
locations;
|
hostNames);
|
||||||
|
|
||||||
# Subnet map: { "home-dmz" = "10.1.0.0/19"; "home-main" = "..."; ... }
|
mkHostsFromSpec =
|
||||||
mkSubnetsFromSpec =
|
|
||||||
spec:
|
spec:
|
||||||
let
|
let
|
||||||
locations =
|
locations = spec.locations or (throw "metatron-addressing: spec.locations is required");
|
||||||
spec.locations or (throw "metatron-addressing: spec.locations is required");
|
|
||||||
locationId = locationIdForSpec spec;
|
locationId = locationIdForSpec spec;
|
||||||
domain =
|
|
||||||
spec.domain or (throw "metatron-addressing: spec.domain is required");
|
|
||||||
in
|
in
|
||||||
concatMapAttrs
|
concatMapAttrs
|
||||||
(locationName: locationCfg:
|
(locationName: locationCfg:
|
||||||
let
|
let
|
||||||
loc = locationId locationName;
|
loc = locationId locationName;
|
||||||
locCode = mkLocationCode locationName;
|
locCode = mkLocationCode locationName;
|
||||||
|
locationScope = mergeScopes emptyScope locationCfg;
|
||||||
|
networks = locationCfg.networks or { };
|
||||||
|
in
|
||||||
|
concatMapAttrs
|
||||||
|
(networkName: networkCfg:
|
||||||
|
let
|
||||||
|
networkScope = mergeScopes locationScope networkCfg;
|
||||||
|
subnets = networkCfg.subnets or { };
|
||||||
|
in
|
||||||
|
concatMapAttrs
|
||||||
|
(typeName: subnetCfg:
|
||||||
|
let
|
||||||
|
subnetScope = mergeScopes networkScope subnetCfg;
|
||||||
|
in
|
||||||
|
hostMapForSubnet {
|
||||||
|
inherit loc locCode locationName networkName typeName subnetCfg;
|
||||||
|
scope = subnetScope;
|
||||||
|
})
|
||||||
|
subnets)
|
||||||
|
networks)
|
||||||
|
locations;
|
||||||
|
|
||||||
# Only attributes with `hosts` are subnets
|
mkSubnetsFromSpec =
|
||||||
subnets =
|
spec:
|
||||||
lib.filterAttrs (_: v: builtins.isAttrs v && v ? hosts) locationCfg;
|
let
|
||||||
|
locations = spec.locations or (throw "metatron-addressing: spec.locations is required");
|
||||||
|
locationId = locationIdForSpec spec;
|
||||||
|
in
|
||||||
|
concatMapAttrs
|
||||||
|
(locationName: locationCfg:
|
||||||
|
let
|
||||||
|
loc = locationId locationName;
|
||||||
|
locCode = mkLocationCode locationName;
|
||||||
|
locationScope = mergeScopes emptyScope locationCfg;
|
||||||
|
networks = locationCfg.networks or { };
|
||||||
|
in
|
||||||
|
concatMapAttrs
|
||||||
|
(networkName: networkCfg:
|
||||||
|
let
|
||||||
|
networkScope = mergeScopes locationScope networkCfg;
|
||||||
|
subnets = networkCfg.subnets or { };
|
||||||
in
|
in
|
||||||
mapAttrs'
|
mapAttrs'
|
||||||
(typeName: subnetCfg:
|
(typeName: subnetCfg:
|
||||||
let
|
let
|
||||||
|
subnetScope = mergeScopes networkScope subnetCfg;
|
||||||
|
|
||||||
cidr = mkSubnetNamed { location = loc; inherit typeName; };
|
cidr = mkSubnetNamed { location = loc; inherit typeName; };
|
||||||
|
|
||||||
subnetSlug =
|
subnetSlug =
|
||||||
|
|
@ -385,8 +444,6 @@ let
|
||||||
then subnetSlugs.${typeName}
|
then subnetSlugs.${typeName}
|
||||||
else typeName;
|
else typeName;
|
||||||
|
|
||||||
zone = "${subnetSlug}.${locCode}.${domain}";
|
|
||||||
|
|
||||||
vlan =
|
vlan =
|
||||||
subnetCfg.vlan or
|
subnetCfg.vlan or
|
||||||
subnetCfg._vlan or
|
subnetCfg._vlan or
|
||||||
|
|
@ -411,28 +468,25 @@ let
|
||||||
};
|
};
|
||||||
in
|
in
|
||||||
nameValuePair
|
nameValuePair
|
||||||
"${locationName}-${typeName}"
|
"${locationName}-${networkName}-${typeName}"
|
||||||
(
|
(
|
||||||
{
|
{
|
||||||
inherit cidr locationName typeName zone vlan;
|
inherit cidr locationName networkName typeName vlan;
|
||||||
}
|
}
|
||||||
|
// optionalAttrs (subnetScope.domain != null) {
|
||||||
|
zone = "${subnetSlug}.${locCode}.${subnetScope.domain}";
|
||||||
|
}
|
||||||
|
// materializeScope subnetScope
|
||||||
// optionalAttrs (dhcpCfg != null) {
|
// optionalAttrs (dhcpCfg != null) {
|
||||||
dhcp = dhcpCfg;
|
dhcp = dhcpCfg;
|
||||||
dhcpRange = dhcpRange;
|
dhcpRange = dhcpRange;
|
||||||
}
|
}
|
||||||
))
|
))
|
||||||
subnets)
|
subnets)
|
||||||
|
networks)
|
||||||
locations;
|
locations;
|
||||||
|
|
||||||
# Combined view, if you want both
|
mkNetworkFromSpec = spec: {
|
||||||
mkNetworkFromSpec =
|
|
||||||
spec:
|
|
||||||
let
|
|
||||||
domain =
|
|
||||||
spec.domain or (throw "metatron-addressing: spec.domain is required");
|
|
||||||
in
|
|
||||||
{
|
|
||||||
inherit domain;
|
|
||||||
hosts = mkHostsFromSpec spec;
|
hosts = mkHostsFromSpec spec;
|
||||||
subnets = mkSubnetsFromSpec spec;
|
subnets = mkSubnetsFromSpec spec;
|
||||||
};
|
};
|
||||||
|
|
@ -448,12 +502,15 @@ in
|
||||||
mkIpNamed
|
mkIpNamed
|
||||||
mkSubnet
|
mkSubnet
|
||||||
mkSubnetNamed
|
mkSubnetNamed
|
||||||
|
mkVlan
|
||||||
|
mkVlanNamed
|
||||||
mkHostsFromSpec
|
mkHostsFromSpec
|
||||||
mkSubnetsFromSpec
|
mkSubnetsFromSpec
|
||||||
mkNetworkFromSpec
|
mkNetworkFromSpec
|
||||||
mkRoleRange
|
mkRoleRange
|
||||||
mkRoleRangeNamed;
|
mkRoleRangeNamed
|
||||||
|
mergeScopes;
|
||||||
|
|
||||||
# Shorthand; you were calling mkHosts before
|
# Shorthand; you were calling mkHosts before.
|
||||||
mkHosts = mkNetworkFromSpec;
|
mkHosts = mkNetworkFromSpec;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
224
meta.nix
224
meta.nix
|
|
@ -3,22 +3,23 @@
|
||||||
|
|
||||||
locations = {
|
locations = {
|
||||||
cloud = {
|
cloud = {
|
||||||
owner = "yaro";
|
domain = "kasear.net";
|
||||||
dmz = {
|
|
||||||
hosts = {
|
networks.default.subnets = {
|
||||||
|
dmz.hosts = {
|
||||||
eris = {
|
eris = {
|
||||||
role = "router";
|
role = "router";
|
||||||
aliases = [ "frontend.kasear.net" ];
|
aliases = [
|
||||||
|
"frontend.kasear.net"
|
||||||
|
];
|
||||||
};
|
};
|
||||||
|
|
||||||
deimos-cloud = {
|
deimos-cloud = {
|
||||||
role = "server";
|
role = "server";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
|
||||||
|
|
||||||
infra = {
|
infra.hosts = {
|
||||||
hosts = {
|
|
||||||
metatron = {
|
metatron = {
|
||||||
role = "coreServer";
|
role = "coreServer";
|
||||||
};
|
};
|
||||||
|
|
@ -26,15 +27,28 @@
|
||||||
loki-cloud = {
|
loki-cloud = {
|
||||||
role = "adminWorkstation";
|
role = "adminWorkstation";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
io-cloud = {
|
||||||
|
role = "router";
|
||||||
|
};
|
||||||
|
|
||||||
|
europa-cloud = {
|
||||||
|
role = "router";
|
||||||
|
};
|
||||||
|
|
||||||
|
vpn-container = {
|
||||||
|
role = "server";
|
||||||
|
dns = false;
|
||||||
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
home = {
|
norfolk = {
|
||||||
dmz = {
|
domain = "kasear.net";
|
||||||
vlan = 1;
|
|
||||||
|
|
||||||
hosts = {
|
networks.default.subnets = {
|
||||||
|
dmz.hosts = {
|
||||||
io = {
|
io = {
|
||||||
role = "router";
|
role = "router";
|
||||||
aliases = [ "external.kasear.net" ];
|
aliases = [ "external.kasear.net" ];
|
||||||
|
|
@ -58,7 +72,6 @@
|
||||||
"test.kasear.net"
|
"test.kasear.net"
|
||||||
"vault.kasear.net"
|
"vault.kasear.net"
|
||||||
"vikali.kasear.net"
|
"vikali.kasear.net"
|
||||||
"vpn.kasear.net"
|
|
||||||
"www.kasear.net"
|
"www.kasear.net"
|
||||||
"yaro.kasear.net"
|
"yaro.kasear.net"
|
||||||
];
|
];
|
||||||
|
|
@ -69,27 +82,60 @@
|
||||||
dns = false;
|
dns = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
cloud-container = { role = "server"; dns = false; };
|
cloud-container = {
|
||||||
default-container = { role = "server"; dns = false; };
|
role = "server";
|
||||||
foregejo-container = { role = "server"; dns = false; };
|
dns = false;
|
||||||
majike-container = { role = "server"; dns = false; };
|
};
|
||||||
media-container = { role = "server"; dns = false; };
|
|
||||||
vault-container = { role = "server"; dns = false; };
|
default-container = {
|
||||||
vikali-container = { role = "server"; dns = false; };
|
role = "server";
|
||||||
vpn-container = { role = "server"; dns = false; };
|
dns = false;
|
||||||
yaro-container = { role = "server"; dns = false; };
|
};
|
||||||
|
|
||||||
|
foregejo-container = {
|
||||||
|
role = "server";
|
||||||
|
dns = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
majike-container = {
|
||||||
|
role = "server";
|
||||||
|
dns = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
media-container = {
|
||||||
|
role = "server";
|
||||||
|
dns = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
vault-container = {
|
||||||
|
role = "server";
|
||||||
|
dns = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
vikali-container = {
|
||||||
|
role = "server";
|
||||||
|
dns = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
yaro-container = {
|
||||||
|
role = "server";
|
||||||
|
dns = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
norfolk-dmz-dhcp-start = {
|
||||||
|
role = "pool";
|
||||||
|
hostId = 1;
|
||||||
|
dns = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
norfolk-dmz-dhcp-end = {
|
||||||
|
role = "pool";
|
||||||
|
hostId = 250;
|
||||||
|
dns = false;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
main = {
|
main.hosts = {
|
||||||
vlan = 10;
|
|
||||||
|
|
||||||
dhcp = {
|
|
||||||
start = 1;
|
|
||||||
end = 250;
|
|
||||||
};
|
|
||||||
|
|
||||||
hosts = {
|
|
||||||
europa = {
|
europa = {
|
||||||
role = "router";
|
role = "router";
|
||||||
aliases = [ "internal.kasear.net" ];
|
aliases = [ "internal.kasear.net" ];
|
||||||
|
|
@ -106,6 +152,11 @@
|
||||||
hw-address = "54:af:97:02:2f:15";
|
hw-address = "54:af:97:02:2f:15";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
loki = {
|
||||||
|
role = "adminWorkstation";
|
||||||
|
hw-address = "70:85:c2:f4:1a:58";
|
||||||
|
};
|
||||||
|
|
||||||
luna = {
|
luna = {
|
||||||
role = "infraDevice";
|
role = "infraDevice";
|
||||||
hw-address = "30:23:03:48:4c:75";
|
hw-address = "30:23:03:48:4c:75";
|
||||||
|
|
@ -114,7 +165,6 @@
|
||||||
phobos = {
|
phobos = {
|
||||||
role = "server";
|
role = "server";
|
||||||
hw-address = "10:98:36:a9:4a:26";
|
hw-address = "10:98:36:a9:4a:26";
|
||||||
interface = "eno2";
|
|
||||||
aliases = [
|
aliases = [
|
||||||
"pbx.kasear.net"
|
"pbx.kasear.net"
|
||||||
"private.kasear.net"
|
"private.kasear.net"
|
||||||
|
|
@ -137,28 +187,39 @@
|
||||||
role = "phone";
|
role = "phone";
|
||||||
hw-address = "80:5e:c0:de:3d:66";
|
hw-address = "80:5e:c0:de:3d:66";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
norfolk-main-dhcp-start = {
|
||||||
|
role = "pool";
|
||||||
|
hostId = 1;
|
||||||
|
dns = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
norfolk-main-dhcp-end = {
|
||||||
|
role = "pool";
|
||||||
|
hostId = 250;
|
||||||
|
dns = false;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
guest = {
|
guest.hosts = {
|
||||||
vlan = 20;
|
|
||||||
|
|
||||||
dhcp = {
|
|
||||||
start = 1;
|
|
||||||
end = 250;
|
|
||||||
};
|
|
||||||
|
|
||||||
hosts = {
|
|
||||||
europa-guest = {
|
europa-guest = {
|
||||||
role = "router";
|
role = "router";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
norfolk-guest-dhcp-start = {
|
||||||
|
role = "pool";
|
||||||
|
hostId = 1;
|
||||||
|
dns = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
norfolk-guest-dhcp-end = {
|
||||||
|
role = "pool";
|
||||||
|
hostId = 250;
|
||||||
|
dns = false;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
iot = {
|
iot.hosts = {
|
||||||
vlan = 30;
|
|
||||||
|
|
||||||
hosts = {
|
|
||||||
europa-iot = {
|
europa-iot = {
|
||||||
role = "router";
|
role = "router";
|
||||||
};
|
};
|
||||||
|
|
@ -183,6 +244,11 @@
|
||||||
hw-address = "08:84:9d:74:4d:c6";
|
hw-address = "08:84:9d:74:4d:c6";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
loki-iot = {
|
||||||
|
role = "adminWorkstation";
|
||||||
|
hw-address = "70:85:c2:f4:1a:58";
|
||||||
|
};
|
||||||
|
|
||||||
camera1 = {
|
camera1 = {
|
||||||
role = "camera";
|
role = "camera";
|
||||||
hw-address = "9c:8e:cd:38:95:1f";
|
hw-address = "9c:8e:cd:38:95:1f";
|
||||||
|
|
@ -204,18 +270,26 @@
|
||||||
role = "appliance";
|
role = "appliance";
|
||||||
hw-address = "04:e4:b6:23:81:fc";
|
hw-address = "04:e4:b6:23:81:fc";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
mercury-iot = {
|
||||||
|
role = "mobile";
|
||||||
|
hw-address = "ac:3e:b1:77:65:2e";
|
||||||
|
};
|
||||||
|
|
||||||
|
norfolk-iot-dhcp-start = {
|
||||||
|
role = "pool";
|
||||||
|
hostId = 1;
|
||||||
|
dns = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
norfolk-iot-dhcp-end = {
|
||||||
|
role = "pool";
|
||||||
|
hostId = 250;
|
||||||
|
dns = false;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
storage = {
|
storage.hosts = {
|
||||||
vlan = 40;
|
|
||||||
|
|
||||||
dhcp = {
|
|
||||||
start = 1;
|
|
||||||
end = 250;
|
|
||||||
};
|
|
||||||
|
|
||||||
hosts = {
|
|
||||||
europa-storage = {
|
europa-storage = {
|
||||||
role = "router";
|
role = "router";
|
||||||
};
|
};
|
||||||
|
|
@ -224,13 +298,30 @@
|
||||||
role = "nas";
|
role = "nas";
|
||||||
aliases = [ "storage.kasear.net" ];
|
aliases = [ "storage.kasear.net" ];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
loki-storage = {
|
||||||
|
role = "adminWorkstation";
|
||||||
|
hw-address = "00:07:43:13:c4:90";
|
||||||
|
};
|
||||||
|
|
||||||
|
norfolk-storage-dhcp-start = {
|
||||||
|
role = "pool";
|
||||||
|
hostId = 1;
|
||||||
|
dns = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
norfolk-storage-dhcp-end = {
|
||||||
|
role = "pool";
|
||||||
|
hostId = 250;
|
||||||
|
dns = false;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
management = {
|
management.hosts = {
|
||||||
vlan = 70;
|
europa-management = {
|
||||||
|
role = "router";
|
||||||
|
};
|
||||||
|
|
||||||
hosts = {
|
|
||||||
deimos-idrac = {
|
deimos-idrac = {
|
||||||
role = "oobMgmt";
|
role = "oobMgmt";
|
||||||
hw-address = "10:98:36:a0:2c:b3";
|
hw-address = "10:98:36:a0:2c:b3";
|
||||||
|
|
@ -245,13 +336,20 @@
|
||||||
role = "oobMgmt";
|
role = "oobMgmt";
|
||||||
hw-address = "14:18:77:51:4b:b5";
|
hw-address = "14:18:77:51:4b:b5";
|
||||||
};
|
};
|
||||||
};
|
|
||||||
};
|
norfolk-management-dhcp-start = {
|
||||||
};
|
role = "pool";
|
||||||
|
hostId = 1;
|
||||||
|
dns = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
# You can add these later if you want to match the bigger design:
|
norfolk-management-dhcp-end = {
|
||||||
# systems = { };
|
role = "pool";
|
||||||
# consumers = { };
|
hostId = 250;
|
||||||
# policy = { };
|
dns = false;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue