Skip to content

Commit

Permalink
feat(config): accept templates for PROXIED and TTL (#214)
Browse files Browse the repository at this point in the history
* feat(config): PROXIED and TTL accept templates

* docs: document Go templates

* test: improve coverage

* test: improve coverage
  • Loading branch information
favonia committed Sep 5, 2022
1 parent a2b2e9b commit a78b96b
Show file tree
Hide file tree
Showing 21 changed files with 732 additions and 609 deletions.
1 change: 1 addition & 0 deletions .golangci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ linters:
- ifshort # deprecated
- interfacer # deprecated
- ireturn # ireturn works poorly for the style with private types and public interfaces
- maintidx # It seems the linter never leads to code changes
- maligned # deprecated, and I value readability over bytes saved by alignment
- nlreturn # I don't agree with the style enforced by nlreturn
- nonamedreturns # named returns are needed in the internal updator package
Expand Down
26 changes: 20 additions & 6 deletions README.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -345,12 +345,26 @@ In most cases, `CF_ACCOUNT_ID` is not needed.
| `PROXIED` | Boolean values, such as `true`, `false`, `0` and `1`. See [strconv.ParseBool](https://pkg.go.dev/strconv#ParseBool) | Whether new DNS records should be proxied by Cloudflare | No | `false`
| `TTL` | Time-to-live (TTL) values in seconds | The TTL values used to create new DNS records | No | `1` (This means “automatic” to Cloudflare)

🧪 Experimental features: (Please [share your case at this GitHub issue](https://github.com/favonia/cloudflare-ddns/issues/199) so that we can further revise the design. Thanks!)
> <details>
> <summary>🧪 Experimental support of Go templates:</summary>
>
> Both `PROXIED` and `TTL` can be [Go templates](https://pkg.go.dev/text/template) for per-domain settings. For example, `PROXIED={{not (suffix "example.org")}}` means all domains should be proxied except domains like `www.example.org` and `example.org`. The Go templates are executed with the following two custom functions:
> - `domain(patterns ...string) bool`
>
> Returns `true` if and only if the target domain matches one of `patterns`. All domains are normalized before comparison; for example, internationalized domain names are converted to Punycode before comparing them.
> - `suffix(patterns ...string) bool`
>
> Returns `true` if and only if the target domain has one of `patterns` as itself or its parent (or ancestor). Note that labels in domains must fully match; for example, the suffix `b.org` will not match `www.bb.org` because `bb.org` and `b.org` are incomparable, while the suffix `bb.org` will match `www.bb.org`.
>
> Some examples:
> - `TTL={{if suffix "b.c"}} 60 {{else if domain "d.e.f" "a.bb.c" }} 90 {{else}} 120 {{end}}`
>
> For the domain `b.c` and its descendants, the TTL is 60, and for the domains `d.e.f` and `a.bb.c`, the TTL is 90, and then for all other domains, the TTL is 120.
> - `PROXIED={{and (suffix "b.c") (not (domain "a.b.c"))}}`
>
> Proxy the domain `b.c` and its descendants except for the domain `a.b.c`.
> </details>
| Name | Valid Values | Meaning | Required? | Default Value |
| ---- | ------------ | ------- | --------- | ------------- |
| `PROXIED_DOMAINS` | Comma-separated fully qualified domain names or wildcard domain names | The domains for which the new DNS records should be proxied by Cloudflare, overriding the global setting (`PROXIED`) for these domains | No | `""` (empty)
| `NON_PROXIED_DOMAINS` | Comma-separated fully qualified domain names or wildcard domain names | The domains for which the new DNS records should **not** be proxied by Cloudflare, overriding the global setting (`PROXIED`) for these domains | No | `""` (empty)
</details>

<details>
Expand Down Expand Up @@ -412,7 +426,7 @@ If you are using Kubernetes, run `kubectl replace -f cloudflare-ddns.yaml` after
| `cloudflare.authentication.api_key` || _Use the newer, more secure [API tokens](https://dash.cloudflare.com/profile/api-tokens)_ |
| `cloudflare.zone_id` | ✔️ | Not needed; automatically retrieved from the server |
| `cloudflare.subdomains[].name` | ✔️ | Use `DOMAINS` with **fully qualified domain names** (FQDNs); for example, if your zone is `example.org` and your subdomain is `www`, use `DOMAINS=sub.example.org` |
| `cloudflare.subdomains[].proxied` | ✔️ | Use `PROXIED=true` or `PROXIED=false` to specify the global proxy setting, and then use `PROXIED_DOMAINS` and `NON_PROXIED_DOMAINS` with **fully qualified domain names** (FQDNs) to override the global setting if desired |
| `cloudflare.subdomains[].proxied` | ✔️ | Use the experimental support of Go templates in `PROXIED` to specify per-domain settings; see above for the detailed documentation |
| `a` | ✔️ | Both IPv4 and IPv6 are enabled by default; use `IP4_PROVIDER=none` to disable IPv4 |
| `aaaa` | ✔️ | Both IPv4 and IPv6 are enabled by default; use `IP6_PROVIDER=none` to disable IPv6 |
| `proxied` | ✔️ | Use `PROXIED=true` or `PROXIED=false` |
Expand Down
2 changes: 1 addition & 1 deletion cmd/ddns.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ func initConfig(ctx context.Context, ppfmt pp.PP) (*config.Config, api.Handle, s
}

// Get the setter
s, ok := setter.New(ppfmt, h, c.TTL)
s, ok := setter.New(ppfmt, h)
if !ok {
bye()
}
Expand Down
11 changes: 9 additions & 2 deletions internal/api/ttl.go
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
package api

import (
"sort"
"strconv"
)

type TTL int

const TTLAuto = 1

func (t TTL) Int() int {
return int(t)
}
Expand All @@ -15,8 +18,12 @@ func (t TTL) String() string {
}

func (t TTL) Describe() string {
if t == 1 {
return "1 (automatic)"
if t == TTLAuto {
return "1 (auto)"
}
return strconv.Itoa(t.Int())
}

func SortTTLs(s []TTL) {
sort.Slice(s, func(i, j int) bool { return int(s[i]) < int(s[j]) })
}
2 changes: 1 addition & 1 deletion internal/api/ttl_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ func TestTTLDescribe(t *testing.T) {
seconds int
description string
}{
"automatic": {1, "1 (automatic)"},
"automatic": {1, "1 (auto)"},
"2": {2, "2"},
"30": {30, "30"},
"293": {293, "293"},
Expand Down

0 comments on commit a78b96b

Please sign in to comment.