1{
2 config,
3 pkgs,
4 lib,
5 ...
6}:
7let
8 cfg = config.services.cfdyndns;
9in
10{
11 imports = [
12 (lib.mkRemovedOptionModule [
13 "services"
14 "cfdyndns"
15 "apikey"
16 ] "Use services.cfdyndns.apikeyFile instead.")
17 ];
18
19 options = {
20 services.cfdyndns = {
21 enable = lib.mkEnableOption "Cloudflare Dynamic DNS Client";
22
23 email = lib.mkOption {
24 type = lib.types.str;
25 description = ''
26 The email address to use to authenticate to CloudFlare.
27 '';
28 };
29
30 apiTokenFile = lib.mkOption {
31 default = null;
32 type = lib.types.nullOr lib.types.str;
33 description = ''
34 The path to a file containing the API Token
35 used to authenticate with CloudFlare.
36 '';
37 };
38
39 apikeyFile = lib.mkOption {
40 default = null;
41 type = lib.types.nullOr lib.types.str;
42 description = ''
43 The path to a file containing the API Key
44 used to authenticate with CloudFlare.
45 '';
46 };
47
48 records = lib.mkOption {
49 default = [ ];
50 example = [ "host.tld" ];
51 type = lib.types.listOf lib.types.str;
52 description = ''
53 The records to update in CloudFlare.
54 '';
55 };
56 };
57 };
58
59 config = lib.mkIf cfg.enable {
60 systemd.services.cfdyndns = {
61 description = "CloudFlare Dynamic DNS Client";
62 after = [ "network.target" ];
63 wantedBy = [ "multi-user.target" ];
64 startAt = "*:0/5";
65 serviceConfig = {
66 Type = "simple";
67 LoadCredential = lib.optional (
68 cfg.apiTokenFile != null
69 ) "CLOUDFLARE_APITOKEN_FILE:${cfg.apiTokenFile}";
70 DynamicUser = true;
71 };
72 environment = {
73 CLOUDFLARE_RECORDS = "${lib.concatStringsSep "," cfg.records}";
74 };
75 script = ''
76 ${lib.optionalString (cfg.apikeyFile != null) ''
77 export CLOUDFLARE_APIKEY="$(cat ${lib.escapeShellArg cfg.apikeyFile})"
78 export CLOUDFLARE_EMAIL="${cfg.email}"
79 ''}
80 ${lib.optionalString (cfg.apiTokenFile != null) ''
81 export CLOUDFLARE_APITOKEN=$(${pkgs.systemd}/bin/systemd-creds cat CLOUDFLARE_APITOKEN_FILE)
82 ''}
83 ${pkgs.cfdyndns}/bin/cfdyndns
84 '';
85 };
86 };
87}