feat(refactor): ready for merge
This commit is contained in:
@@ -6,7 +6,7 @@
|
|||||||
...
|
...
|
||||||
}: {
|
}: {
|
||||||
flake.nixosConfigurations = let
|
flake.nixosConfigurations = let
|
||||||
cLib = import ../lib inputs.nixpkgs.lib;
|
# clib = import ../lib inputs.nixpkgs.lib;
|
||||||
userConfig = "${self}/home";
|
userConfig = "${self}/home";
|
||||||
systemConfig = "${self}/system";
|
systemConfig = "${self}/system";
|
||||||
hostConfig = "${self}/hosts";
|
hostConfig = "${self}/hosts";
|
||||||
@@ -22,7 +22,7 @@
|
|||||||
|
|
||||||
specialArgs = {
|
specialArgs = {
|
||||||
inherit
|
inherit
|
||||||
cLib
|
# clib
|
||||||
inputs
|
inputs
|
||||||
outputs
|
outputs
|
||||||
self
|
self
|
||||||
|
|||||||
@@ -57,12 +57,14 @@
|
|||||||
services = {
|
services = {
|
||||||
homepage-dashboard = {
|
homepage-dashboard = {
|
||||||
enable = true;
|
enable = true;
|
||||||
subdomain = "";
|
subdomain = "dash";
|
||||||
|
exposure = "local";
|
||||||
port = 8082;
|
port = 8082;
|
||||||
};
|
};
|
||||||
n8n = {
|
n8n = {
|
||||||
enable = true;
|
enable = true;
|
||||||
subdomain = "n8n";
|
subdomain = "n8n";
|
||||||
|
exposure = "local";
|
||||||
port = 5678;
|
port = 5678;
|
||||||
homepage = {
|
homepage = {
|
||||||
name = "n8n";
|
name = "n8n";
|
||||||
@@ -74,6 +76,7 @@
|
|||||||
bazarr = {
|
bazarr = {
|
||||||
enable = true;
|
enable = true;
|
||||||
subdomain = "bazarr";
|
subdomain = "bazarr";
|
||||||
|
exposure = "local";
|
||||||
port = 6767;
|
port = 6767;
|
||||||
homepage = {
|
homepage = {
|
||||||
name = "Bazarr";
|
name = "Bazarr";
|
||||||
@@ -85,6 +88,7 @@
|
|||||||
prowlarr = {
|
prowlarr = {
|
||||||
enable = true;
|
enable = true;
|
||||||
subdomain = "prowlarr";
|
subdomain = "prowlarr";
|
||||||
|
exposure = "local";
|
||||||
port = 9696;
|
port = 9696;
|
||||||
homepage = {
|
homepage = {
|
||||||
name = "prowlarr";
|
name = "prowlarr";
|
||||||
@@ -96,6 +100,7 @@
|
|||||||
flaresolverr = {
|
flaresolverr = {
|
||||||
enable = true;
|
enable = true;
|
||||||
subdomain = "flaresolverr";
|
subdomain = "flaresolverr";
|
||||||
|
exposure = "local";
|
||||||
port = 8191;
|
port = 8191;
|
||||||
homepage = {
|
homepage = {
|
||||||
name = "FlareSolverr";
|
name = "FlareSolverr";
|
||||||
@@ -107,6 +112,7 @@
|
|||||||
lidarr = {
|
lidarr = {
|
||||||
enable = true;
|
enable = true;
|
||||||
subdomain = "lidarr";
|
subdomain = "lidarr";
|
||||||
|
exposure = "local";
|
||||||
port = 8686;
|
port = 8686;
|
||||||
homepage = {
|
homepage = {
|
||||||
name = "Lidarr";
|
name = "Lidarr";
|
||||||
@@ -118,6 +124,7 @@
|
|||||||
sonarr = {
|
sonarr = {
|
||||||
enable = true;
|
enable = true;
|
||||||
subdomain = "sonarr";
|
subdomain = "sonarr";
|
||||||
|
exposure = "local";
|
||||||
port = 8989;
|
port = 8989;
|
||||||
homepage = {
|
homepage = {
|
||||||
name = "Sonarr";
|
name = "Sonarr";
|
||||||
@@ -129,6 +136,7 @@
|
|||||||
radarr = {
|
radarr = {
|
||||||
enable = true;
|
enable = true;
|
||||||
subdomain = "radarr";
|
subdomain = "radarr";
|
||||||
|
exposure = "local";
|
||||||
port = 7878;
|
port = 7878;
|
||||||
homepage = {
|
homepage = {
|
||||||
name = "Radarr";
|
name = "Radarr";
|
||||||
@@ -140,6 +148,7 @@
|
|||||||
jellyseerr = {
|
jellyseerr = {
|
||||||
enable = true;
|
enable = true;
|
||||||
subdomain = "jellyseerr";
|
subdomain = "jellyseerr";
|
||||||
|
exposure = "local";
|
||||||
port = 5055;
|
port = 5055;
|
||||||
homepage = {
|
homepage = {
|
||||||
name = "Jellyseerr";
|
name = "Jellyseerr";
|
||||||
@@ -163,6 +172,7 @@
|
|||||||
uptime-kuma = {
|
uptime-kuma = {
|
||||||
enable = true;
|
enable = true;
|
||||||
subdomain = "uptime";
|
subdomain = "uptime";
|
||||||
|
exposure = "local";
|
||||||
port = 3001;
|
port = 3001;
|
||||||
homepage = {
|
homepage = {
|
||||||
name = "Uptime Kuma";
|
name = "Uptime Kuma";
|
||||||
@@ -218,6 +228,7 @@
|
|||||||
qbittorrent = {
|
qbittorrent = {
|
||||||
enable = true;
|
enable = true;
|
||||||
subdomain = "qbt";
|
subdomain = "qbt";
|
||||||
|
exposure = "local";
|
||||||
port = 8080;
|
port = 8080;
|
||||||
homepage = {
|
homepage = {
|
||||||
name = "qBittorrent";
|
name = "qBittorrent";
|
||||||
@@ -229,6 +240,7 @@
|
|||||||
slskd = {
|
slskd = {
|
||||||
enable = true;
|
enable = true;
|
||||||
subdomain = "slskd";
|
subdomain = "slskd";
|
||||||
|
exposure = "local";
|
||||||
port = 5030;
|
port = 5030;
|
||||||
homepage = {
|
homepage = {
|
||||||
name = "Soulseek";
|
name = "Soulseek";
|
||||||
@@ -240,6 +252,7 @@
|
|||||||
pihole = {
|
pihole = {
|
||||||
enable = true;
|
enable = true;
|
||||||
subdomain = "pihole";
|
subdomain = "pihole";
|
||||||
|
exposure = "local";
|
||||||
port = 8053;
|
port = 8053;
|
||||||
homepage = {
|
homepage = {
|
||||||
name = "PiHole";
|
name = "PiHole";
|
||||||
|
|||||||
@@ -4,6 +4,10 @@
|
|||||||
username = "cnst";
|
username = "cnst";
|
||||||
mail = "adam@cnst.dev";
|
mail = "adam@cnst.dev";
|
||||||
sshUser = "sobotka";
|
sshUser = "sobotka";
|
||||||
|
domains = {
|
||||||
|
local = "cnix.dev";
|
||||||
|
public = "cnst.dev";
|
||||||
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,26 @@
|
|||||||
{
|
{lib}: let
|
||||||
imports = [
|
server = {
|
||||||
./serviceurl
|
mkDomain = config: service: let
|
||||||
];
|
localDomain = config.settings.accounts.domains.local;
|
||||||
|
publicDomain = config.settings.accounts.domains.public;
|
||||||
|
tailscaleDomain = "ts.${publicDomain}";
|
||||||
|
in
|
||||||
|
if service.exposure == "tunnel"
|
||||||
|
then publicDomain
|
||||||
|
else if service.exposure == "tailscale"
|
||||||
|
then tailscaleDomain
|
||||||
|
else localDomain;
|
||||||
|
|
||||||
|
mkFullDomain = config: service: let
|
||||||
|
domain = server.mkDomain config service;
|
||||||
|
in "${service.subdomain}.${domain}";
|
||||||
|
|
||||||
|
mkHostDomain = config: service: let
|
||||||
|
domain = server.mkDomain config service;
|
||||||
|
in "${domain}";
|
||||||
|
|
||||||
|
mkSubDomain = config: service: "${service.subdomain}";
|
||||||
|
};
|
||||||
|
in {
|
||||||
|
server = server;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,23 +0,0 @@
|
|||||||
{
|
|
||||||
lib,
|
|
||||||
config,
|
|
||||||
...
|
|
||||||
}: let
|
|
||||||
mkServiceUrl' = import ./serviceurl.nix {inherit config;};
|
|
||||||
in {
|
|
||||||
options.clib = {
|
|
||||||
server = {
|
|
||||||
mkServiceUrl = lib.mkOption {
|
|
||||||
type = lib.types.function;
|
|
||||||
readOnly = true;
|
|
||||||
description = "Helper function to generate a service URL.";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
config.clib = {
|
|
||||||
server = {
|
|
||||||
mkServiceUrl = mkServiceUrl';
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
{config}: service: let
|
|
||||||
mainDomain = config.server.networking.domain;
|
|
||||||
tailscaleDomain = "ts.${mainDomain}";
|
|
||||||
|
|
||||||
domain =
|
|
||||||
if service.exposure == "tunnel"
|
|
||||||
then mainDomain
|
|
||||||
else if service.exposure == "tailscale"
|
|
||||||
then tailscaleDomain
|
|
||||||
else (service.domain or mainDomain);
|
|
||||||
in "${service.subdomain}.${domain}"
|
|
||||||
@@ -3,7 +3,7 @@
|
|||||||
pkgs,
|
pkgs,
|
||||||
lib,
|
lib,
|
||||||
osConfig,
|
osConfig,
|
||||||
cLib,
|
clib,
|
||||||
...
|
...
|
||||||
}: let
|
}: let
|
||||||
inherit (lib) mkIf mkEnableOption;
|
inherit (lib) mkIf mkEnableOption;
|
||||||
@@ -13,7 +13,7 @@
|
|||||||
# hyprlockPkg = pkgs.hyprlock;
|
# hyprlockPkg = pkgs.hyprlock;
|
||||||
#
|
#
|
||||||
bg = osConfig.settings.theme.background;
|
bg = osConfig.settings.theme.background;
|
||||||
inherit (cLib.theme.bgs) resolve;
|
inherit (clib.theme.bgs) resolve;
|
||||||
in {
|
in {
|
||||||
config = mkIf cfg.enable {
|
config = mkIf cfg.enable {
|
||||||
programs.hyprlock = {
|
programs.hyprlock = {
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
pkgs,
|
pkgs,
|
||||||
inputs,
|
inputs,
|
||||||
osConfig,
|
osConfig,
|
||||||
cLib,
|
clib,
|
||||||
...
|
...
|
||||||
}: let
|
}: let
|
||||||
inherit (lib) mkIf;
|
inherit (lib) mkIf;
|
||||||
@@ -11,7 +11,7 @@
|
|||||||
cfg = osConfig.nixos.programs.hyprland;
|
cfg = osConfig.nixos.programs.hyprland;
|
||||||
hyprpaperFlake = inputs.hyprpaper.packages.${pkgs.system}.default;
|
hyprpaperFlake = inputs.hyprpaper.packages.${pkgs.system}.default;
|
||||||
bg = osConfig.settings.theme.background;
|
bg = osConfig.settings.theme.background;
|
||||||
bgs = cLib.theme.bgs;
|
bgs = clib.theme.bgs;
|
||||||
|
|
||||||
monitorMappings = [
|
monitorMappings = [
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,6 +1,14 @@
|
|||||||
{self, ...}: {
|
{
|
||||||
|
self,
|
||||||
|
lib,
|
||||||
|
...
|
||||||
|
}: let
|
||||||
|
clib = import "${self}/lib/server" {inherit lib;};
|
||||||
|
in {
|
||||||
imports = [
|
imports = [
|
||||||
"${self}/lib/server"
|
{
|
||||||
|
_module.args.clib = clib;
|
||||||
|
}
|
||||||
./options.nix
|
./options.nix
|
||||||
./infra
|
./infra
|
||||||
./services
|
./services
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
{
|
{
|
||||||
lib,
|
lib,
|
||||||
|
clib,
|
||||||
config,
|
config,
|
||||||
pkgs,
|
pkgs,
|
||||||
self,
|
self,
|
||||||
@@ -29,21 +30,21 @@
|
|||||||
# }
|
# }
|
||||||
# ) (lib.filterAttrs (name: service: service.enable) services);
|
# ) (lib.filterAttrs (name: service: service.enable) services);
|
||||||
|
|
||||||
generateRouters = services:
|
generateRouters = services: config:
|
||||||
lib.mapAttrs' (
|
lib.mapAttrs' (
|
||||||
name: service:
|
name: service:
|
||||||
lib.nameValuePair "${service.subdomain}" {
|
lib.nameValuePair name {
|
||||||
entryPoints = ["websecure"];
|
entryPoints = ["websecure"];
|
||||||
rule = "Host(`${config.clib.server.mkServiceUrl service}`)";
|
# FIX 3: Use backticks for the Host rule and interpolation
|
||||||
service = service.subdomain;
|
rule = "Host(`${clib.server.mkFullDomain config service}`)";
|
||||||
|
service = name;
|
||||||
tls.certResolver = "letsencrypt";
|
tls.certResolver = "letsencrypt";
|
||||||
}
|
}
|
||||||
) (lib.filterAttrs (_: s: s.enable) services);
|
) (lib.filterAttrs (_: s: s.enable) services);
|
||||||
|
|
||||||
# Generates all Traefik backend services
|
|
||||||
generateServices = services:
|
generateServices = services:
|
||||||
lib.mapAttrs' (name: service:
|
lib.mapAttrs' (name: service:
|
||||||
lib.nameValuePair "${service.subdomain}" {
|
lib.nameValuePair name {
|
||||||
loadBalancer.servers = [{url = "http://localhost:${toString service.port}";}];
|
loadBalancer.servers = [{url = "http://localhost:${toString service.port}";}];
|
||||||
}) (lib.filterAttrs (name: service: service.enable) services);
|
}) (lib.filterAttrs (name: service: service.enable) services);
|
||||||
|
|
||||||
@@ -168,12 +169,10 @@ in {
|
|||||||
|
|
||||||
dynamicConfigOptions = {
|
dynamicConfigOptions = {
|
||||||
http = {
|
http = {
|
||||||
# Generate the services from your central list
|
|
||||||
services = generateServices srv.services;
|
services = generateServices srv.services;
|
||||||
|
|
||||||
# Generate the routers and manually add the special 'api' router
|
|
||||||
routers =
|
routers =
|
||||||
(generateRouters srv.services)
|
(generateRouters srv.services config)
|
||||||
// {
|
// {
|
||||||
api = {
|
api = {
|
||||||
entryPoints = ["websecure"];
|
entryPoints = ["websecure"];
|
||||||
|
|||||||
@@ -8,10 +8,22 @@
|
|||||||
cfg = config.server.infra.${unit};
|
cfg = config.server.infra.${unit};
|
||||||
srv = config.server;
|
srv = config.server;
|
||||||
|
|
||||||
generateLocalRecords = services:
|
svcNames = lib.attrNames srv.services;
|
||||||
lib.mapAttrsToList (
|
|
||||||
name: service: "local-data: \"${service.subdomain}.${srv.domain}. A ${srv.ip}\""
|
localARecords = builtins.concatLists (map (
|
||||||
) (lib.filterAttrs (name: service: service.enable) services);
|
name: let
|
||||||
|
s = srv.services.${name};
|
||||||
|
in
|
||||||
|
if s != null && s.enable && s.subdomain != null
|
||||||
|
then [''"${s.subdomain}.${srv.domain}. A ${srv.ip}"'']
|
||||||
|
else []
|
||||||
|
)
|
||||||
|
svcNames);
|
||||||
|
|
||||||
|
revParts = lib.lists.reverseList (lib.splitString "." srv.ip);
|
||||||
|
revName = lib.concatStringsSep "." revParts;
|
||||||
|
|
||||||
|
localPTRs = ["${revName}.in-addr.arpa. PTR traefik.${srv.domain}"];
|
||||||
|
|
||||||
hostIp = hostname:
|
hostIp = hostname:
|
||||||
if hostname == "ziggy"
|
if hostname == "ziggy"
|
||||||
@@ -104,10 +116,10 @@ in {
|
|||||||
"255.255.255.255/32"
|
"255.255.255.255/32"
|
||||||
"2001:db8::/32"
|
"2001:db8::/32"
|
||||||
];
|
];
|
||||||
local-data = generateLocalRecords srv.services;
|
local-data = localARecords;
|
||||||
local-data-ptr = [
|
|
||||||
"local-data: \"traefik.${srv.domain}. A ${srv.ip}\""
|
# Example PTR entry: "14.88.168.192.in-addr.arpa. PTR traefik.cnix.dev."
|
||||||
];
|
# local-data-ptr = localPTRs;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -12,16 +12,13 @@ in {
|
|||||||
age.secrets.giteaCloudflared.file = "${self}/secrets/giteaCloudflared.age";
|
age.secrets.giteaCloudflared.file = "${self}/secrets/giteaCloudflared.age";
|
||||||
|
|
||||||
server.infra = {
|
server.infra = {
|
||||||
fail2ban.jails.unit = {
|
fail2ban.jails.${unit} = {
|
||||||
serviceName = "${unit}";
|
serviceName = "${unit}";
|
||||||
failRegex = ''
|
failRegex = ''.*(Failed authentication attempt|invalid credentials|Attempted access of unknown user).* from <HOST>'';
|
||||||
.*(Failed authentication attempt|invalid credentials|Attempted access of unknown user).*
|
|
||||||
from <HOST>
|
|
||||||
'';
|
|
||||||
};
|
};
|
||||||
|
|
||||||
postgresql.databases = [
|
postgresql.databases = [
|
||||||
{database = unit;}
|
{database = "gitea";}
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
config,
|
config,
|
||||||
lib,
|
lib,
|
||||||
self,
|
self,
|
||||||
|
clib,
|
||||||
...
|
...
|
||||||
}: let
|
}: let
|
||||||
unit = "homepage-dashboard";
|
unit = "homepage-dashboard";
|
||||||
@@ -90,9 +91,10 @@ in {
|
|||||||
"Downloads"
|
"Downloads"
|
||||||
"Services"
|
"Services"
|
||||||
];
|
];
|
||||||
|
|
||||||
allServices = srv.services;
|
allServices = srv.services;
|
||||||
|
|
||||||
|
getDomain = s: clib.server.mkHostDomain config s;
|
||||||
|
|
||||||
homepageServicesFor = category:
|
homepageServicesFor = category:
|
||||||
lib.filterAttrs
|
lib.filterAttrs
|
||||||
(
|
(
|
||||||
@@ -108,12 +110,15 @@ in {
|
|||||||
"${cat}" =
|
"${cat}" =
|
||||||
lib.lists.forEach
|
lib.lists.forEach
|
||||||
(lib.attrsets.mapAttrsToList (name: _value: name) (homepageServicesFor cat))
|
(lib.attrsets.mapAttrsToList (name: _value: name) (homepageServicesFor cat))
|
||||||
(x: {
|
(x: let
|
||||||
"${allServices.${x}.homepage.name}" = {
|
service = allServices.${x};
|
||||||
icon = allServices.${x}.homepage.icon;
|
domain = getDomain service;
|
||||||
description = allServices.${x}.homepage.description;
|
in {
|
||||||
href = "https://${allServices.${x}.url}";
|
"${service.homepage.name}" = {
|
||||||
siteMonitor = "https://${allServices.${x}.url}";
|
icon = service.homepage.icon;
|
||||||
|
description = service.homepage.description;
|
||||||
|
href = "https://${domain}";
|
||||||
|
siteMonitor = "https://${domain}";
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -2,8 +2,7 @@
|
|||||||
lib,
|
lib,
|
||||||
config,
|
config,
|
||||||
...
|
...
|
||||||
}:
|
}: let
|
||||||
let
|
|
||||||
inherit (lib) mkOption types;
|
inherit (lib) mkOption types;
|
||||||
|
|
||||||
sshKeys = {
|
sshKeys = {
|
||||||
@@ -16,14 +15,14 @@ let
|
|||||||
keyName = config.settings.accounts.sshUser or null;
|
keyName = config.settings.accounts.sshUser or null;
|
||||||
|
|
||||||
selectedKey =
|
selectedKey =
|
||||||
if keyName != null then
|
if keyName != null
|
||||||
|
then
|
||||||
lib.attrByPath [
|
lib.attrByPath [
|
||||||
keyName
|
keyName
|
||||||
] (builtins.abort "No SSH key defined for hostname/key '${toString keyName}'") sshKeys
|
] (builtins.abort "No SSH key defined for hostname/key '${toString keyName}'")
|
||||||
else
|
sshKeys
|
||||||
builtins.abort "No accounts.sshUser provided, cannot select SSH key.";
|
else builtins.abort "No accounts.sshUser provided, cannot select SSH key.";
|
||||||
in
|
in {
|
||||||
{
|
|
||||||
options.settings.accounts = {
|
options.settings.accounts = {
|
||||||
username = mkOption {
|
username = mkOption {
|
||||||
type = types.str;
|
type = types.str;
|
||||||
@@ -46,5 +45,21 @@ in
|
|||||||
default = null;
|
default = null;
|
||||||
description = "Optional override for selecting an SSH key by name";
|
description = "Optional override for selecting an SSH key by name";
|
||||||
};
|
};
|
||||||
|
domains = lib.mkOption {
|
||||||
|
type = lib.types.submodule {
|
||||||
|
options = {
|
||||||
|
local = lib.mkOption {
|
||||||
|
type = lib.types.str;
|
||||||
|
default = "127.0.0.1";
|
||||||
|
description = "The local domain of the host";
|
||||||
|
};
|
||||||
|
public = lib.mkOption {
|
||||||
|
type = lib.types.str;
|
||||||
|
default = "example.com";
|
||||||
|
description = "The public domain of the host";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
Binary file not shown.
Reference in New Issue
Block a user