mirror of
https://github.com/gensokyo-zone/infrastructure.git
synced 2026-02-09 20:39:18 -08:00
refactor: move services out of systems/tewi/
This commit is contained in:
parent
2f68968238
commit
5a661e8809
30 changed files with 992 additions and 638 deletions
63
modules/nixos/cloudflared.nix
Normal file
63
modules/nixos/cloudflared.nix
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
{ pkgs, config, utils, lib, ... }: let
|
||||
inherit (lib.attrsets) mapAttrsToList mapAttrs' nameValuePair filterAttrsRecursive;
|
||||
inherit (lib.lists) singleton;
|
||||
inherit (lib.modules) mkIf mkMerge mkForce;
|
||||
inherit (lib.options) mkOption mkEnableOption;
|
||||
cfg = config.services.cloudflared;
|
||||
in {
|
||||
options.services.cloudflared = with lib.types; {
|
||||
tunnels = let
|
||||
tunnelModule = { config, ... }: {
|
||||
options = {
|
||||
extraTunnel = {
|
||||
enable = mkEnableOption "extra tunnels" // {
|
||||
default = config.extraTunnel.ingress != { };
|
||||
};
|
||||
ingress = mkOption {
|
||||
type = attrs;
|
||||
default = { };
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
in mkOption {
|
||||
type = attrsOf (submodule tunnelModule);
|
||||
};
|
||||
};
|
||||
config.systemd.services = let
|
||||
filterConfig = filterAttrsRecursive (_: v: ! builtins.elem v [ null [ ] { } ]);
|
||||
mapIngress = hostname: ingress: {
|
||||
inherit hostname;
|
||||
} // filterConfig (filterConfig ingress);
|
||||
in mkIf cfg.enable (mapAttrs' (uuid: tunnel: let
|
||||
RuntimeDirectory = "cloudflared-tunnel-${uuid}";
|
||||
configPath = "/run/${RuntimeDirectory}/config.yml";
|
||||
settings = {
|
||||
tunnel = uuid;
|
||||
credentials-file = tunnel.credentialsFile;
|
||||
ingress = mapAttrsToList mapIngress tunnel.ingress
|
||||
++ mapAttrsToList mapIngress tunnel.extraTunnel.ingress
|
||||
++ singleton { service = tunnel.default; };
|
||||
};
|
||||
in nameValuePair "cloudflared-tunnel-${uuid}" (mkMerge [
|
||||
{
|
||||
after = mkIf config.services.tailscale.enable [ "tailscale-autoconnect.service" ];
|
||||
serviceConfig = {
|
||||
RestartSec = 10;
|
||||
};
|
||||
}
|
||||
(mkIf tunnel.extraTunnel.enable {
|
||||
serviceConfig = {
|
||||
inherit RuntimeDirectory;
|
||||
ExecStart = mkForce [
|
||||
"${cfg.package}/bin/cloudflared tunnel --config=${configPath} --no-autoupdate run"
|
||||
];
|
||||
ExecStartPre = [
|
||||
(pkgs.writeShellScript "cloudflared-tunnel-${uuid}-prepare" ''
|
||||
${utils.genJqSecretsReplacementSnippet settings configPath}
|
||||
'')
|
||||
];
|
||||
};
|
||||
})
|
||||
])) cfg.tunnels);
|
||||
}
|
||||
193
modules/nixos/home-assistant.nix
Normal file
193
modules/nixos/home-assistant.nix
Normal file
|
|
@ -0,0 +1,193 @@
|
|||
{
|
||||
pkgs,
|
||||
config,
|
||||
lib,
|
||||
...
|
||||
}: let
|
||||
cfg = config.services.home-assistant;
|
||||
inherit (lib.modules) mkIf mkMerge mkBefore mkDefault;
|
||||
inherit (lib.options) mkOption mkEnableOption;
|
||||
inherit (lib.lists) optional elem;
|
||||
in {
|
||||
options.services.home-assistant = with lib.types; {
|
||||
mutableUiConfig = mkEnableOption "UI-editable config files";
|
||||
domain = mkOption {
|
||||
type = str;
|
||||
default = config.networking.domain;
|
||||
};
|
||||
homekit.enable = mkEnableOption "homekit" // {
|
||||
default = cfg.config.homekit or [ ] != [ ];
|
||||
};
|
||||
googleAssistant.enable = mkEnableOption "Google Assistant" // {
|
||||
default = cfg.config.google_assistant or { } != { };
|
||||
};
|
||||
androidTv.enable = mkEnableOption "Android TV" // {
|
||||
default = elem "androidtv" cfg.extraComponents;
|
||||
};
|
||||
cast = {
|
||||
enable = mkEnableOption "Chromecast" // {
|
||||
default = elem "cast" cfg.extraComponents;
|
||||
};
|
||||
openFirewall = mkEnableOption "Chromecast ports" // {
|
||||
default = cfg.openFirewall;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
config = {
|
||||
networking.firewall = mkIf cfg.enable {
|
||||
allowedTCPPorts = mkIf (cfg.openFirewall && cfg.homekit.enable) (
|
||||
map ({ port, ... }: port) cfg.config.homekit or [ ]
|
||||
);
|
||||
|
||||
allowedUDPPortRanges = [
|
||||
(mkIf (cfg.cast.enable && cfg.cast.openFirewall) {
|
||||
from = 32768;
|
||||
to = 60999;
|
||||
})
|
||||
];
|
||||
};
|
||||
|
||||
# MDNS
|
||||
services.avahi = mkIf (cfg.enable && cfg.homekit.enable) {
|
||||
enable = mkDefault true;
|
||||
publish.enable = false;
|
||||
};
|
||||
|
||||
systemd.services.home-assistant = mkIf (cfg.enable && cfg.mutableUiConfig) {
|
||||
# UI-editable config files
|
||||
preStart = mkBefore ''
|
||||
touch ${cfg.configDir}/{automations,scenes,scripts,manual,homekit_entity_config,homekit_include_entities}.yaml
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
config.services.home-assistant = {
|
||||
config = mkMerge [
|
||||
{
|
||||
homeassistant = {
|
||||
external_url = "https://${cfg.domain}";
|
||||
};
|
||||
logger = {
|
||||
default = mkDefault "info";
|
||||
};
|
||||
http = {
|
||||
cors_allowed_origins = [
|
||||
"https://google.com"
|
||||
"https://www.home-assistant.io"
|
||||
];
|
||||
use_x_forwarded_for = "true";
|
||||
trusted_proxies = [
|
||||
"127.0.0.0/24"
|
||||
"200::/7"
|
||||
"100.64.0.0/10"
|
||||
"fd7a:115c:a1e0:ab12::/64"
|
||||
"::1"
|
||||
];
|
||||
};
|
||||
recorder = {
|
||||
db_url = mkIf config.services.postgresql.enable (mkDefault "postgresql://@/hass");
|
||||
};
|
||||
counter = {};
|
||||
device_tracker = {};
|
||||
energy = {};
|
||||
group = {};
|
||||
history = {};
|
||||
input_boolean = {};
|
||||
input_button = {};
|
||||
input_datetime = {};
|
||||
input_number = {};
|
||||
input_select = {};
|
||||
input_text = {};
|
||||
logbook = {};
|
||||
schedule = {};
|
||||
map = {};
|
||||
media_source = {};
|
||||
media_player = [];
|
||||
mobile_app = {};
|
||||
my = {};
|
||||
person = {};
|
||||
ssdp = {};
|
||||
switch = {};
|
||||
stream = {};
|
||||
sun = {};
|
||||
system_health = {};
|
||||
tag = {};
|
||||
template = {};
|
||||
timer = {};
|
||||
webhook = {};
|
||||
zeroconf = {};
|
||||
zone = {};
|
||||
sensor = {};
|
||||
}
|
||||
(mkIf cfg.mutableUiConfig {
|
||||
# https://nixos.wiki/wiki/Home_Assistant#Combine_declarative_and_UI_defined_automations
|
||||
"automation manual" = [];
|
||||
"automation ui" = "!include automations.yaml";
|
||||
# https://nixos.wiki/wiki/Home_Assistant#Combine_declarative_and_UI_defined_scenes
|
||||
"scene manual" = [];
|
||||
"scene ui" = "!include scenes.yaml";
|
||||
"script manual" = [];
|
||||
"script ui" = "!include scripts.yaml";
|
||||
})
|
||||
];
|
||||
package = let
|
||||
inherit (cfg.package) python;
|
||||
hasBrother = elem "brother" cfg.extraComponents;
|
||||
# https://github.com/pysnmp/pysnmp/issues/51
|
||||
needsPyasn1pin = if lib.versionOlder python.pkgs.pysnmplib.version "6.0"
|
||||
then true
|
||||
else lib.warn "pyasn1 pin likely no longer needed" false;
|
||||
pyasn1prefix = "${python.pkgs.pysnmp-pyasn1}/${python.sitePackages}";
|
||||
home-assistant = pkgs.home-assistant.override {
|
||||
packageOverrides = self: super: {
|
||||
};
|
||||
};
|
||||
in home-assistant.overrideAttrs (old: {
|
||||
makeWrapperArgs = old.makeWrapperArgs ++ optional (hasBrother && needsPyasn1pin) "--prefix PYTHONPATH : ${pyasn1prefix}";
|
||||
disabledTests = old.disabledTests or [ ] ++ [
|
||||
"test_check_config"
|
||||
];
|
||||
});
|
||||
extraPackages = python3Packages: with python3Packages; mkMerge [
|
||||
[
|
||||
psycopg2
|
||||
securetar
|
||||
getmac # for upnp integration
|
||||
python-otbr-api
|
||||
protobuf3
|
||||
(aiogithubapi.overrideAttrs (_: {doInstallCheck = false;}))
|
||||
]
|
||||
(mkIf cfg.homekit.enable [
|
||||
aiohomekit
|
||||
])
|
||||
(mkIf cfg.androidTv.enable [
|
||||
adb-shell
|
||||
(callPackage ../../packages/androidtvremote2.nix { })
|
||||
])
|
||||
];
|
||||
extraComponents = mkMerge [
|
||||
[
|
||||
"automation"
|
||||
"scene"
|
||||
"script"
|
||||
"default_config"
|
||||
"environment_canada"
|
||||
"met"
|
||||
"generic_thermostat"
|
||||
"mqtt"
|
||||
"zeroconf"
|
||||
]
|
||||
(mkIf cfg.homekit.enable [
|
||||
"homekit"
|
||||
])
|
||||
(mkIf cfg.googleAssistant.enable [
|
||||
"google"
|
||||
"google_assistant"
|
||||
"google_cloud"
|
||||
])
|
||||
(map ({ platform, ... }: platform) cfg.config.media_player or [ ])
|
||||
(map ({ platform, ... }: platform) cfg.config.tts or [ ])
|
||||
];
|
||||
};
|
||||
}
|
||||
91
modules/nixos/kanidm.nix
Normal file
91
modules/nixos/kanidm.nix
Normal file
|
|
@ -0,0 +1,91 @@
|
|||
{
|
||||
lib,
|
||||
pkgs,
|
||||
config,
|
||||
...
|
||||
}: let
|
||||
inherit (lib) mkIf mkMerge mkDefault mkOptionDefault mkEnableOption mkOption;
|
||||
cfg = config.services.kanidm;
|
||||
in {
|
||||
options.services.kanidm = with lib.types; {
|
||||
server = {
|
||||
openFirewall = mkEnableOption "firewall ports";
|
||||
unencrypted = {
|
||||
enable = mkEnableOption "snake oil certificate";
|
||||
domain = mkOption {
|
||||
type = str;
|
||||
default = cfg.server.frontend.domain;
|
||||
};
|
||||
package = mkOption {
|
||||
type = package;
|
||||
};
|
||||
};
|
||||
frontend = {
|
||||
domain = mkOption {
|
||||
type = nullOr str;
|
||||
default = cfg.serverSettings.domain;
|
||||
};
|
||||
address = mkOption {
|
||||
type = str;
|
||||
default = "127.0.0.1";
|
||||
};
|
||||
port = mkOption {
|
||||
type = port;
|
||||
default = 8081;
|
||||
};
|
||||
};
|
||||
ldap = {
|
||||
enable = mkEnableOption "LDAP interface";
|
||||
address = mkOption {
|
||||
type = str;
|
||||
default = "127.0.0.1";
|
||||
};
|
||||
port = mkOption {
|
||||
type = port;
|
||||
default = 636;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
config = {
|
||||
networking.firewall.allowedTCPPorts = mkIf (cfg.enableServer && cfg.server.openFirewall) [
|
||||
cfg.server.frontend.port
|
||||
cfg.server.ldap.port
|
||||
];
|
||||
|
||||
services.kanidm = {
|
||||
server.unencrypted.package = let
|
||||
cert = pkgs.runCommand "kanidm-cert" {
|
||||
inherit (cfg.server.unencrypted) domain;
|
||||
nativeBuildInputs = [ pkgs.buildPackages.minica ];
|
||||
} ''
|
||||
install -d $out
|
||||
cd $out
|
||||
minica \
|
||||
--ca-key ca.key.pem \
|
||||
--ca-cert ca.cert.pem \
|
||||
--domains $domain
|
||||
cat $domain/cert.pem ca.cert.pem > $domain.pem
|
||||
'';
|
||||
in mkOptionDefault cert;
|
||||
clientSettings = mkIf cfg.enableServer {
|
||||
uri = mkDefault cfg.serverSettings.origin;
|
||||
};
|
||||
serverSettings = mkMerge [
|
||||
{
|
||||
domain = mkDefault config.networking.domain;
|
||||
origin = mkDefault "https://${cfg.server.frontend.domain}";
|
||||
bindaddress = mkDefault "${cfg.server.frontend.address}:${toString cfg.server.frontend.port}";
|
||||
ldapbindaddress = mkIf cfg.server.ldap.enable (
|
||||
mkDefault "${cfg.server.ldap.address}:${toString cfg.server.ldap.port}"
|
||||
);
|
||||
}
|
||||
(mkIf cfg.server.unencrypted.enable {
|
||||
tls_chain = "${cfg.server.unencrypted.package}/${cfg.server.unencrypted.domain}.pem";
|
||||
tls_key = "${cfg.server.unencrypted.package}/${cfg.server.unencrypted.domain}/key.pem";
|
||||
})
|
||||
];
|
||||
};
|
||||
};
|
||||
}
|
||||
25
modules/nixos/mosquitto.nix
Normal file
25
modules/nixos/mosquitto.nix
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
{
|
||||
config,
|
||||
lib,
|
||||
...
|
||||
}: let
|
||||
inherit (lib) mkIf mkMerge mkEnableOption mkOption;
|
||||
cfg = config.services.mosquitto;
|
||||
in {
|
||||
options.services.mosquitto = with lib.types; {
|
||||
listeners = let
|
||||
listenerModule = { ... }: {
|
||||
options = {
|
||||
openFirewall = mkEnableOption "firewall";
|
||||
};
|
||||
};
|
||||
in mkOption {
|
||||
type = listOf (submodule listenerModule);
|
||||
};
|
||||
};
|
||||
config = {
|
||||
networking.firewall.allowedTCPPorts = mkIf cfg.enable (mkMerge (
|
||||
map (listener: mkIf listener.openFirewall [ listener.port ]) cfg.listeners
|
||||
));
|
||||
};
|
||||
}
|
||||
75
modules/nixos/nginx-vouch.nix
Normal file
75
modules/nixos/nginx-vouch.nix
Normal file
|
|
@ -0,0 +1,75 @@
|
|||
{
|
||||
config,
|
||||
lib,
|
||||
...
|
||||
}:
|
||||
with lib; let
|
||||
inherit (config.services) vouch-proxy;
|
||||
in {
|
||||
options = with types; {
|
||||
services.nginx.virtualHosts = let
|
||||
vouchModule = { config, ... }: {
|
||||
options = {
|
||||
vouch = {
|
||||
enable = mkEnableOption "vouch auth proxy";
|
||||
proxyOrigin = mkOption {
|
||||
type = str;
|
||||
};
|
||||
authUrl = mkOption {
|
||||
type = str;
|
||||
};
|
||||
url = mkOption {
|
||||
type = str;
|
||||
};
|
||||
};
|
||||
};
|
||||
config = mkMerge [
|
||||
{
|
||||
vouch = mkIf vouch-proxy.enable {
|
||||
proxyOrigin = let
|
||||
inherit (vouch-proxy.settings.vouch) listen port;
|
||||
in mkOptionDefault "http://${listen}:${toString port}";
|
||||
authUrl = mkOptionDefault vouch-proxy.authUrl;
|
||||
url = mkOptionDefault vouch-proxy.url;
|
||||
};
|
||||
}
|
||||
(mkIf config.vouch.enable {
|
||||
extraConfig = ''
|
||||
auth_request /validate;
|
||||
error_page 401 = @error401;
|
||||
'';
|
||||
locations = {
|
||||
"/" = {
|
||||
extraConfig = ''
|
||||
add_header Access-Control-Allow-Origin ${config.vouch.url};
|
||||
add_header Access-Control-Allow-Origin ${config.vouch.authUrl};
|
||||
proxy_set_header X-Vouch-User $auth_resp_x_vouch_user;
|
||||
'';
|
||||
};
|
||||
"@error401" = {
|
||||
extraConfig = ''
|
||||
return 302 ${config.vouch.url}/login?url=$scheme://$http_host$request_uri&vouch-failcount=$auth_resp_failcount&X-Vouch-Token=$auth_resp_jwt&error=$auth_resp_err;
|
||||
'';
|
||||
};
|
||||
"/validate" = {
|
||||
recommendedProxySettings = false;
|
||||
proxyPass = "${config.vouch.proxyOrigin}/validate";
|
||||
extraConfig = ''
|
||||
proxy_set_header Host $host;
|
||||
proxy_pass_request_body off;
|
||||
proxy_set_header Content-Length "";
|
||||
auth_request_set $auth_resp_x_vouch_user $upstream_http_x_vouch_user;
|
||||
auth_request_set $auth_resp_jwt $upstream_http_x_vouch_jwt;
|
||||
auth_request_set $auth_resp_err $upstream_http_x_vouch_err;
|
||||
auth_request_set $auth_resp_failcount $upstream_http_x_vouch_failcount;
|
||||
'';
|
||||
};
|
||||
};
|
||||
})
|
||||
];
|
||||
};
|
||||
in mkOption {
|
||||
type = attrsOf (submodule vouchModule);
|
||||
};
|
||||
};
|
||||
}
|
||||
163
modules/nixos/vouch.nix
Normal file
163
modules/nixos/vouch.nix
Normal file
|
|
@ -0,0 +1,163 @@
|
|||
{
|
||||
config,
|
||||
utils,
|
||||
pkgs,
|
||||
lib,
|
||||
...
|
||||
}: let
|
||||
inherit (lib) mkIf mkMerge mkDefault mkOptionDefault mkOption mkEnableOption types
|
||||
getExe;
|
||||
nixosConfig = config;
|
||||
cfg = config.services.vouch-proxy;
|
||||
settingsFormat = pkgs.formats.json { };
|
||||
in {
|
||||
options.services.vouch-proxy = with types; {
|
||||
enable = mkEnableOption "vouch";
|
||||
user = mkOption {
|
||||
type = str;
|
||||
default = "vouch-proxy";
|
||||
};
|
||||
group = mkOption {
|
||||
type = str;
|
||||
default = "vouch-proxy";
|
||||
};
|
||||
authUrl = mkOption {
|
||||
type = str;
|
||||
default = config.services.kanidm.serverSettings.origin;
|
||||
};
|
||||
domain = mkOption {
|
||||
type = str;
|
||||
default = config.networking.domain;
|
||||
};
|
||||
url = mkOption {
|
||||
type = str;
|
||||
default = "https://${cfg.domain}";
|
||||
};
|
||||
enableSettingsSecrets = mkEnableOption "genJqSecretsReplacementSnippet";
|
||||
settings = let
|
||||
settingsModule = { ... }: {
|
||||
freeformType = settingsFormat.type;
|
||||
options = {
|
||||
vouch = {
|
||||
cookie = {
|
||||
domain = mkOption {
|
||||
type = nullOr str;
|
||||
default = nixosConfig.networking.domain;
|
||||
};
|
||||
secure = mkOption {
|
||||
type = bool;
|
||||
default = true;
|
||||
};
|
||||
};
|
||||
port = mkOption {
|
||||
type = port;
|
||||
default = 30746;
|
||||
};
|
||||
listen = mkOption {
|
||||
type = nullOr str;
|
||||
default = "127.0.0.1";
|
||||
};
|
||||
allowAllUsers = mkOption {
|
||||
type = bool;
|
||||
default = true;
|
||||
};
|
||||
};
|
||||
oauth = {
|
||||
auth_url = mkOption {
|
||||
type = str;
|
||||
default = "${cfg.authUrl}/ui/oauth2";
|
||||
};
|
||||
token_url = mkOption {
|
||||
type = str;
|
||||
default = "${cfg.authUrl}/oauth2/token";
|
||||
};
|
||||
user_info_url = mkOption {
|
||||
type = str;
|
||||
default = "${cfg.authUrl}/oauth2/openid/vouch/userinfo";
|
||||
};
|
||||
scopes = mkOption {
|
||||
type = listOf str;
|
||||
default = ["openid" "email" "profile"];
|
||||
};
|
||||
callback_url = mkOption {
|
||||
type = str;
|
||||
default = "${cfg.url}/auth";
|
||||
};
|
||||
provider = mkOption {
|
||||
type = nullOr str;
|
||||
default = "oidc";
|
||||
};
|
||||
code_challenge_method = mkOption {
|
||||
type = str;
|
||||
default = "S256";
|
||||
};
|
||||
client_id = mkOption {
|
||||
type = str;
|
||||
default = "vouch";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
in mkOption {
|
||||
type = submodule settingsModule;
|
||||
default = { };
|
||||
};
|
||||
extraSettings = mkOption {
|
||||
inherit (settingsFormat) type;
|
||||
default = { };
|
||||
};
|
||||
settingsPath = mkOption {
|
||||
type = path;
|
||||
};
|
||||
};
|
||||
config = let
|
||||
recursiveMergeAttrs = listOfAttrsets: lib.fold (attrset: acc: lib.recursiveUpdate attrset acc) {} listOfAttrsets;
|
||||
settings = recursiveMergeAttrs [
|
||||
cfg.settings
|
||||
cfg.extraSettings
|
||||
];
|
||||
settingsPath = if cfg.enableSettingsSecrets
|
||||
then "/run/vouch-proxy/vouch-config.json"
|
||||
else settingsFormat.generate "vouch-config.json" settings;
|
||||
in mkMerge [
|
||||
{
|
||||
services.vouch-proxy = {
|
||||
settingsPath = mkOptionDefault settingsPath;
|
||||
};
|
||||
}
|
||||
(mkIf cfg.enable {
|
||||
systemd.services.vouch-proxy = {
|
||||
description = "Vouch-proxy";
|
||||
after = [ "network.target" ];
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
serviceConfig = {
|
||||
ExecStartPre = let
|
||||
preprocess = pkgs.writeShellScript "vouch-proxy-prestart" (
|
||||
utils.genJqSecretsReplacementSnippet settings cfg.settingsPath
|
||||
);
|
||||
in mkIf cfg.enableSettingsSecrets [
|
||||
"${preprocess}"
|
||||
];
|
||||
ExecStart = [
|
||||
"${getExe pkgs.vouch-proxy} -config ${cfg.settingsPath}"
|
||||
];
|
||||
Restart = "on-failure";
|
||||
RestartSec = mkDefault 5;
|
||||
WorkingDirectory = "/var/lib/vouch-proxy";
|
||||
StateDirectory = "vouch-proxy";
|
||||
RuntimeDirectory = "vouch-proxy";
|
||||
User = cfg.user;
|
||||
Group = cfg.group;
|
||||
StartLimitBurst = mkDefault 3;
|
||||
};
|
||||
};
|
||||
|
||||
users.users.${cfg.user} = {
|
||||
inherit (cfg) group;
|
||||
isSystemUser = true;
|
||||
};
|
||||
|
||||
users.groups.${cfg.group} = {};
|
||||
})
|
||||
];
|
||||
}
|
||||
22
modules/nixos/zigbee2mqtt.nix
Normal file
22
modules/nixos/zigbee2mqtt.nix
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
{
|
||||
config,
|
||||
lib,
|
||||
...
|
||||
}: let
|
||||
inherit (lib) mkIf mkEnableOption mkOption;
|
||||
cfg = config.services.zigbee2mqtt;
|
||||
in {
|
||||
options.services.zigbee2mqtt = with lib.types; {
|
||||
openFirewall = mkEnableOption "firewall port";
|
||||
domain = mkOption {
|
||||
type = str;
|
||||
default = config.networking.domain;
|
||||
};
|
||||
};
|
||||
|
||||
config = {
|
||||
networking.firewall.allowedTCPPorts = mkIf (cfg.enable && cfg.openFirewall) [
|
||||
cfg.settings.frontend.port
|
||||
];
|
||||
};
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue