commit
43d7b5760b
@ -0,0 +1,93 @@ |
||||
{ config, pkgs, lib, ... }: |
||||
|
||||
with lib; |
||||
|
||||
let |
||||
cfg = config.services.cloudflare-dyndns; |
||||
in |
||||
{ |
||||
options = { |
||||
services.cloudflare-dyndns = { |
||||
enable = mkEnableOption "Cloudflare Dynamic DNS Client"; |
||||
|
||||
apiTokenFile = mkOption { |
||||
type = types.nullOr types.str; |
||||
default = null; |
||||
description = '' |
||||
The path to a file containing the CloudFlare API token. |
||||
|
||||
The file must have the form `CLOUDFLARE_API_TOKEN=...` |
||||
''; |
||||
}; |
||||
|
||||
domains = mkOption { |
||||
type = types.listOf types.str; |
||||
default = [ ]; |
||||
description = '' |
||||
List of domain names to update records for. |
||||
''; |
||||
}; |
||||
|
||||
proxied = mkOption { |
||||
type = types.bool; |
||||
default = false; |
||||
description = '' |
||||
Whether this is a DNS-only record, or also being proxied through CloudFlare. |
||||
''; |
||||
}; |
||||
|
||||
ipv4 = mkOption { |
||||
type = types.bool; |
||||
default = true; |
||||
description = '' |
||||
Whether to enable setting IPv4 A records. |
||||
''; |
||||
}; |
||||
|
||||
ipv6 = mkOption { |
||||
type = types.bool; |
||||
default = false; |
||||
description = '' |
||||
Whether to enable setting IPv6 AAAA records. |
||||
''; |
||||
}; |
||||
|
||||
deleteMissing = mkOption { |
||||
type = types.bool; |
||||
default = false; |
||||
description = '' |
||||
Whether to delete the record when no IP address is found. |
||||
''; |
||||
}; |
||||
}; |
||||
}; |
||||
|
||||
config = mkIf cfg.enable { |
||||
systemd.services.cloudflare-dyndns = { |
||||
description = "CloudFlare Dynamic DNS Client"; |
||||
after = [ "network.target" ]; |
||||
wantedBy = [ "multi-user.target" ]; |
||||
startAt = "*:0/5"; |
||||
|
||||
environment = { |
||||
CLOUDFLARE_DOMAINS = toString cfg.domains; |
||||
}; |
||||
|
||||
serviceConfig = { |
||||
Type = "simple"; |
||||
DynamicUser = true; |
||||
StateDirectory = "cloudflare-dyndns"; |
||||
EnvironmentFile = cfg.apiTokenFile; |
||||
ExecStart = |
||||
let |
||||
args = [ "--cache-file /var/lib/cloudflare-dyndns/ip.cache" ] |
||||
++ (if cfg.ipv4 then [ "-4" ] else [ "-no-4" ]) |
||||
++ (if cfg.ipv6 then [ "-6" ] else [ "-no-6" ]) |
||||
++ optional cfg.deleteMissing "--delete-missing" |
||||
++ optional cfg.proxied "--proxied"; |
||||
in |
||||
"${pkgs.cloudflare-dyndns}/bin/cloudflare-dyndns ${toString args}"; |
||||
}; |
||||
}; |
||||
}; |
||||
} |
@ -0,0 +1,53 @@ |
||||
{ buildPythonApplication |
||||
, attrs |
||||
, click |
||||
, cloudflare |
||||
, fetchFromGitHub |
||||
, lib |
||||
, poetry |
||||
, pydantic |
||||
, pytestCheckHook |
||||
, requests |
||||
}: |
||||
|
||||
buildPythonApplication rec { |
||||
pname = "cloudflare-dyndns"; |
||||
version = "4.1"; |
||||
|
||||
src = fetchFromGitHub { |
||||
owner = "kissgyorgy"; |
||||
repo = pname; |
||||
rev = "v${version}"; |
||||
hash = "sha256-6Q5fpJ+HuQ+hc3xTtB5tR43pn9WZ0nZZR723iLAkpis="; |
||||
}; |
||||
|
||||
format = "pyproject"; |
||||
|
||||
nativeBuildInputs = [ poetry ]; |
||||
|
||||
propagatedBuildInputs = [ |
||||
attrs |
||||
click |
||||
cloudflare |
||||
pydantic |
||||
requests |
||||
]; |
||||
|
||||
postPatch = '' |
||||
substituteInPlace pyproject.toml \ |
||||
--replace 'click = "^7.0"' 'click = "*"' |
||||
''; |
||||
|
||||
checkInputs = [ pytestCheckHook ]; |
||||
|
||||
disabledTests = [ |
||||
"test_get_ipv4" |
||||
]; |
||||
|
||||
meta = with lib; { |
||||
description = " CloudFlare Dynamic DNS client "; |
||||
homepage = "https://github.com/kissgyorgy/cloudflare-dyndns"; |
||||
license = licenses.mit; |
||||
maintainers = with maintainers; [ lovesegfault ]; |
||||
}; |
||||
} |
Loading…
Reference in new issue