Compare commits

..

No commits in common. "b487ec8ae7f841210defac4ba0e8457b02fc844e" and "2449bc2d477e7a36dd3c5f0ab77303ad327bde3a" have entirely different histories.

32 changed files with 279 additions and 14 deletions

View file

@ -8,6 +8,11 @@
system.stateVersion = "25.11"; system.stateVersion = "25.11";
meta = {
domains.validate = true;
ports.validate = true;
};
custom = { custom = {
persistence.enable = true; persistence.enable = true;

View file

@ -8,6 +8,11 @@
system.stateVersion = "25.11"; system.stateVersion = "25.11";
meta = {
domains.validate = true;
ports.validate = true;
};
custom = custom =
let let
privateDomain = config.custom.networking.overlay.domain; privateDomain = config.custom.networking.overlay.domain;

View file

@ -8,6 +8,11 @@
system.stateVersion = "25.11"; system.stateVersion = "25.11";
meta = {
domains.validate = true;
ports.validate = true;
};
custom = custom =
let let
sproutedDomain = "sprouted.cloud"; sproutedDomain = "sprouted.cloud";

View file

@ -83,16 +83,16 @@
]; ];
windowrule = [ windowrule = [
# No borders on floating window when it's the only window # No borders on floating window when it's the only window
"bordersize 0, floating:1, onworkspace:w[1]" "border_size 0, match:float 1, match:workspace w[1]"
# No borders on tiled window when it's the only tiled window # No borders on tiled window when it's the only tiled window
"bordersize 0, floating:0, onworkspace:w[t1]" "border_size 0, match:float 0, match:workspace w[t1]"
# No rounding on tiled window when it's the only tiled window on a normal workspace # No rounding on tiled window when it's the only tiled windonoinitialfocus, class:(jetbrains-)(.*), floating:1w on a normal workspace
"rounding 0, floating:0, onworkspace:w[t1]s[false]" "rounding 0, match:float 0, match:workspace w[t1]s[false]"
"idleinhibit fullscreen, class:.*" "idle_inhibit fullscreen, match:class .*"
# Fix flickering in JetBrains-IDEs # Fix flickering in JetBrains-IDEs
"noinitialfocus, class:(jetbrains-)(.*), floating:1" "no_initial_focus on, match:class (jetbrains-)(.*), match:float 1"
]; ];
}; };
}; };

View file

@ -0,0 +1,62 @@
{
config,
self,
lib,
...
}:
let
cfg = config.meta.domains;
in
{
options.meta.domains = {
local = lib.mkOption {
type = lib.types.listOf lib.types.nonEmptyStr;
default = [ ];
};
global = lib.mkOption {
type = lib.types.listOf lib.types.nonEmptyStr;
default =
self.nixosConfigurations
|> lib.attrValues
|> lib.map (host: host.config.meta.domains.local)
|> lib.concatLists;
readOnly = true;
};
validate = lib.mkEnableOption "";
};
config = lib.mkIf cfg.validate {
assertions =
let
duplicateDomains =
self.nixosConfigurations
|> lib.attrValues
|> lib.map (host: host.options.meta.domains.local.definitionsWithLocations)
|> lib.concatLists
|> lib.concatMap (
{ file, value }:
value
|> lib.map (domain: {
file = self.lib.relativePath file;
inherit domain;
})
)
|> builtins.groupBy (entry: toString entry.domain)
|> lib.mapAttrs (_: values: values |> lib.map (value: value.file))
|> lib.filterAttrs (_: files: lib.length files > 1);
errorMessage =
duplicateDomains
|> lib.mapAttrsToList (
domain: files:
"Duplicate domain `${domain}` found in:\n"
+ (files |> lib.map (file: " - ${file}") |> lib.concatLines)
)
|> lib.concatStrings;
in
lib.singleton {
assertion = duplicateDomains == { };
message = errorMessage;
};
};
}

View file

@ -0,0 +1,65 @@
{
config,
options,
self,
lib,
...
}:
let
cfg = config.meta.ports;
in
{
options.meta.ports = {
tcp = lib.mkOption {
type = lib.types.listOf lib.types.port;
default = [ ];
};
udp = lib.mkOption {
type = lib.types.listOf lib.types.port;
default = [ ];
};
validate = lib.mkEnableOption "";
};
config = {
assertions =
let
findDuplicatePorts =
protocol:
options.meta.ports.${protocol}.definitionsWithLocations
|> lib.concatMap (
{ file, value }:
value
|> lib.map (port: {
file = self.lib.relativePath file;
inherit port;
})
)
|> builtins.groupBy (entry: toString entry.port)
|> lib.mapAttrs (_: values: values |> lib.map (value: value.file))
|> lib.filterAttrs (_: files: lib.length files > 1);
mkErrorMessage =
duplicatePorts:
duplicatePorts
|> lib.mapAttrsToList (
port: files:
"Duplicate port `${port}` found in:\n" + (files |> lib.map (file: " - ${file}") |> lib.concatLines)
)
|> lib.concatStrings;
duplicateTcpPorts = findDuplicatePorts "tcp";
duplicateUdpPorts = findDuplicatePorts "udp";
in
lib.mkIf cfg.validate [
{
assertion = duplicateTcpPorts == { };
message = mkErrorMessage duplicateTcpPorts;
}
{
assertion = duplicateUdpPorts == { };
message = mkErrorMessage duplicateUdpPorts;
}
];
};
}

View file

@ -95,7 +95,7 @@ in
message = "Each caddy virtual host must set exactly one of `port` or `files`"; message = "Each caddy virtual host must set exactly one of `port` or `files`";
}; };
networking.firewall.allowedTCPPorts = lib.mkIf publicHostsExist webPorts; meta.ports.tcp = [ cfg.metricsPort ];
services.caddy = { services.caddy = {
enable = true; enable = true;
@ -111,6 +111,11 @@ in
custom.persistence.directories = [ "/var/lib/caddy" ]; custom.persistence.directories = [ "/var/lib/caddy" ];
} }
(lib.mkIf publicHostsExist {
meta.ports.tcp = webPorts;
networking.firewall.allowedTCPPorts = webPorts;
})
(lib.mkIf privateHostsExist { (lib.mkIf privateHostsExist {
sops.secrets = { sops.secrets = {
"porkbun/api-key".owner = config.users.users.acme.name; "porkbun/api-key".owner = config.users.users.acme.name;

View file

@ -38,6 +38,11 @@ in
}; };
config = lib.mkIf cfg.enable { config = lib.mkIf cfg.enable {
meta.ports.tcp = [
cfg.apiPort
cfg.prometheusPort
];
sops.secrets."crowdsec/enrollment-key" = { sops.secrets."crowdsec/enrollment-key" = {
owner = user; owner = user;
restartUnits = [ "crowdsec.service" ]; restartUnits = [ "crowdsec.service" ];

View file

@ -12,6 +12,11 @@ in
options.custom.services.dns.enable = lib.mkEnableOption ""; options.custom.services.dns.enable = lib.mkEnableOption "";
config = lib.mkIf cfg.enable { config = lib.mkIf cfg.enable {
# meta.ports = {
# tcp = [ 53 ];
# udp = [ 53 ];
# };
services = { services = {
unbound = { unbound = {
enable = true; enable = true;
@ -34,9 +39,7 @@ in
|> lib.attrValues |> lib.attrValues
|> lib.concatMap ( |> lib.concatMap (
host: host:
host.config.custom.services.caddy.virtualHosts host.config.meta.domains.local
|> lib.attrValues
|> lib.map (vHost: vHost.domain)
|> lib.filter (domain: self.lib.isPrivateDomain domain) |> lib.filter (domain: self.lib.isPrivateDomain domain)
|> lib.map (domain: "\"${domain}. A ${host.config.custom.networking.overlay.address}\"") |> lib.map (domain: "\"${domain}. A ${host.config.custom.networking.overlay.address}\"")
); );

View file

@ -38,6 +38,8 @@ in
systemdUnit = "nebula@mesh.service"; systemdUnit = "nebula@mesh.service";
}; };
meta.ports.udp = lib.optional netCfg.underlay.isPublic publicPort;
sops.secrets."nebula/host-key" = { sops.secrets."nebula/host-key" = {
owner = config.users.users.nebula-mesh.name; owner = config.users.users.nebula-mesh.name;
restartUnits = [ "nebula@mesh.service" ]; restartUnits = [ "nebula@mesh.service" ];

View file

@ -1,10 +1,22 @@
{ config, lib, ... }: { config, lib, ... }:
let
ports = [
53
5353
5355
];
in
{ {
options.custom.services.resolved.enable = lib.mkEnableOption "" // { options.custom.services.resolved.enable = lib.mkEnableOption "" // {
default = config.systemd.network.enable; default = config.systemd.network.enable;
}; };
config = lib.mkIf config.custom.services.resolved.enable { config = lib.mkIf config.custom.services.resolved.enable {
meta.ports = {
tcp = ports;
udp = ports;
};
services.resolved = { services.resolved = {
enable = true; enable = true;
dnssec = "allow-downgrade"; dnssec = "allow-downgrade";

View file

@ -12,6 +12,8 @@ in
options.custom.services.sshd.enable = lib.mkEnableOption ""; options.custom.services.sshd.enable = lib.mkEnableOption "";
config = lib.mkIf cfg.enable { config = lib.mkIf cfg.enable {
meta.ports.tcp = [ 22 ];
services = { services = {
openssh = { openssh = {
enable = true; enable = true;

View file

@ -61,6 +61,17 @@ in
} }
]; ];
meta = {
domains.local = lib.mkIf (cfg.gui.domain != null) [ cfg.gui.domain ];
ports = {
tcp = [
cfg.syncPort
cfg.gui.port
];
udp = [ cfg.syncPort ];
};
};
sops.secrets = lib.mkIf useSopsSecrets { sops.secrets = lib.mkIf useSopsSecrets {
"syncthing/cert" = { "syncthing/cert" = {
owner = config.services.syncthing.user; owner = config.services.syncthing.user;

View file

@ -19,6 +19,11 @@ in
}; };
config = lib.mkIf cfg.enable { config = lib.mkIf cfg.enable {
meta = {
domains.local = [ cfg.domain ];
ports.tcp = [ cfg.port ];
};
users = { users = {
users.actual = { users.actual = {
isSystemUser = true; isSystemUser = true;

View file

@ -63,6 +63,11 @@ in
in in
metricsAssertions ++ logsAssertions; metricsAssertions ++ logsAssertions;
meta = {
domains.local = [ cfg.domain ];
ports.tcp = [ cfg.port ];
};
services.alloy = { services.alloy = {
enable = true; enable = true;
extraFlags = [ extraFlags = [

View file

@ -29,6 +29,11 @@ in
message = self.lib.mkUnprotectedMessage "Filebrowser"; message = self.lib.mkUnprotectedMessage "Filebrowser";
}; };
meta = {
domains.local = [ cfg.domain ];
ports.tcp = [ cfg.port ];
};
services.filebrowser = { services.filebrowser = {
enable = true; enable = true;
settings = { settings = {

View file

@ -17,6 +17,11 @@ in
}; };
config = lib.mkIf cfg.enable { config = lib.mkIf cfg.enable {
meta = {
domains.local = [ cfg.domain ];
ports.tcp = [ cfg.port ];
};
users = { users = {
users.git = { users.git = {
isSystemUser = true; isSystemUser = true;

View file

@ -12,6 +12,8 @@ in
}; };
config = lib.mkIf cfg.enable { config = lib.mkIf cfg.enable {
meta.ports.tcp = [ cfg.port ];
services.forgejo.settings.server.SSH_PORT = cfg.port; services.forgejo.settings.server.SSH_PORT = cfg.port;
services.openssh = { services.openssh = {

View file

@ -29,6 +29,11 @@ in
message = self.lib.mkUnprotectedMessage "FreshRSS"; message = self.lib.mkUnprotectedMessage "FreshRSS";
}; };
meta = {
domains.local = [ cfg.domain ];
ports.tcp = [ cfg.port ];
};
services.freshrss = { services.freshrss = {
enable = true; enable = true;
baseUrl = "https://${cfg.domain}"; baseUrl = "https://${cfg.domain}";

View file

@ -70,6 +70,11 @@ in
}; };
config = lib.mkIf cfg.enable { config = lib.mkIf cfg.enable {
meta = {
domains.local = [ cfg.domain ];
ports.tcp = [ cfg.port ];
};
sops = { sops = {
secrets."healthchecks/ping-key" = { }; secrets."healthchecks/ping-key" = { };
templates."gatus.env" = { templates."gatus.env" = {
@ -171,10 +176,7 @@ in
let let
defaultEndpoints = defaultEndpoints =
self.nixosConfigurations self.nixosConfigurations
|> lib.mapAttrs ( |> lib.mapAttrs (_: host: host.config.meta.domains.local)
_: host:
host.config.custom.services.caddy.virtualHosts |> lib.attrValues |> lib.map (vHost: vHost.domain)
)
|> lib.concatMapAttrs ( |> lib.concatMapAttrs (
hostName: domains: hostName: domains:
domains domains

View file

@ -64,6 +64,11 @@ in
}; };
config = lib.mkIf cfg.enable { config = lib.mkIf cfg.enable {
meta = {
domains.local = [ cfg.domain ];
ports.tcp = [ cfg.port ];
};
sops.secrets."grafana/admin-password" = { sops.secrets."grafana/admin-password" = {
owner = config.users.users.grafana.name; owner = config.users.users.grafana.name;
restartUnits = [ "grafana.service" ]; restartUnits = [ "grafana.service" ];

View file

@ -17,6 +17,8 @@ in
}; };
config = lib.mkIf cfg.enable { config = lib.mkIf cfg.enable {
meta.domains.local = [ cfg.domain ];
custom.services.caddy.virtualHosts.${cfg.domain}.files = "${pkgs.it-tools}/lib"; custom.services.caddy.virtualHosts.${cfg.domain}.files = "${pkgs.it-tools}/lib";
}; };
} }

View file

@ -24,6 +24,11 @@ in
}; };
config = lib.mkIf cfg.enable { config = lib.mkIf cfg.enable {
meta = {
domains.local = [ cfg.domain ];
ports.tcp = [ cfg.port ];
};
services.memos = { services.memos = {
enable = true; enable = true;
settings = options.services.memos.settings.default // { settings = options.services.memos.settings.default // {

View file

@ -16,6 +16,11 @@ in
}; };
config = lib.mkIf cfg.enable { config = lib.mkIf cfg.enable {
meta = {
domains.local = [ cfg.domain ];
ports.tcp = [ cfg.port ];
};
services.ntfy-sh = { services.ntfy-sh = {
enable = true; enable = true;
settings = lib.mkForce { settings = lib.mkForce {

View file

@ -22,6 +22,11 @@ in
}; };
config = lib.mkIf cfg.enable { config = lib.mkIf cfg.enable {
meta = {
domains.local = [ cfg.domain ];
ports.tcp = [ cfg.port ];
};
sops.secrets."outline/gitlab-auth-secret" = { sops.secrets."outline/gitlab-auth-secret" = {
owner = config.users.users.outline.name; owner = config.users.users.outline.name;
restartUnits = [ "outline.service" ]; restartUnits = [ "outline.service" ];

View file

@ -19,6 +19,8 @@ in
}; };
config = lib.mkIf cfg.enable { config = lib.mkIf cfg.enable {
meta.domains.local = [ cfg.domain ];
systemd.services.generate-blog = { systemd.services.generate-blog = {
serviceConfig.Type = "oneshot"; serviceConfig.Type = "oneshot";
wantedBy = [ "multi-user.target" ]; wantedBy = [ "multi-user.target" ];

View file

@ -20,6 +20,11 @@ in
}; };
config = lib.mkIf cfg.enable { config = lib.mkIf cfg.enable {
meta = {
domains.local = [ cfg.domain ];
ports.tcp = [ cfg.port ];
};
services = { services = {
privatebin = { privatebin = {
enable = true; enable = true;

View file

@ -25,6 +25,11 @@ in
}; };
config = lib.mkIf cfg.enable { config = lib.mkIf cfg.enable {
meta = {
domains.local = [ cfg.domain ];
ports.tcp = [ cfg.port ];
};
sops.secrets."radicale/htpasswd" = { sops.secrets."radicale/htpasswd" = {
owner = config.users.users.radicale.name; owner = config.users.users.radicale.name;
restartUnits = [ "radicale.service" ]; restartUnits = [ "radicale.service" ];

View file

@ -26,6 +26,11 @@ in
}; };
config = lib.mkIf cfg.enable { config = lib.mkIf cfg.enable {
meta = {
domains.local = [ cfg.domain ];
ports.tcp = [ cfg.port ];
};
services.stirling-pdf = { services.stirling-pdf = {
enable = true; enable = true;
environment = { environment = {

View file

@ -16,6 +16,11 @@ in
}; };
config = lib.mkIf cfg.enable { config = lib.mkIf cfg.enable {
meta = {
domains.local = [ cfg.domain ];
ports.tcp = [ cfg.port ];
};
services.uptime-kuma = { services.uptime-kuma = {
enable = true; enable = true;
settings.PORT = toString cfg.port; settings.PORT = toString cfg.port;

View file

@ -16,6 +16,11 @@ in
}; };
config = lib.mkIf cfg.enable { config = lib.mkIf cfg.enable {
meta = {
domains.local = [ cfg.domain ];
ports.tcp = [ cfg.port ];
};
users = { users = {
users.victorialogs = { users.victorialogs = {
isSystemUser = true; isSystemUser = true;

View file

@ -16,6 +16,11 @@ in
}; };
config = lib.mkIf cfg.enable { config = lib.mkIf cfg.enable {
meta = {
domains.local = [ cfg.domain ];
ports.tcp = [ cfg.port ];
};
users = { users = {
users.victoriametrics = { users.victoriametrics = {
isSystemUser = true; isSystemUser = true;