Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

dns: T5144: Modernize dynamic dns operation (round 2) #2005

Merged
merged 9 commits into from Jun 5, 2023

Conversation

indrajitr
Copy link
Contributor

@indrajitr indrajitr commented May 14, 2023

Apply next round of configuration tree updates to 'service dns dynamic' config tree.

Note: This requires vyos/vyos-build#349

Change Summary

  • Migrate service dns dynamic interface <interface> [use-web] to service dns dynamic address <interface> or service dns dynamic address web [web-options].
    This communicates the intent that dynamic dns IP address is detected in only one way - using the <interface> or using an external web request, not both.
  • When using external web request, (service dns dynamic address web), external url is optional (web-options url). Ddclient defaults are used when unspecified,
  • Rename all config login to username for consistency and also to align better with alternative ddclient backends in consideration.
  • Apply global 'ipv6-enable' to per service 'ip-version: ipv6'. Selecting usage of IPv4 or IPv6 (or both simultaneously) is now at per service (protocol) level instead of global level. This allows more control on the ability to select IPv4 in some cases and IPv6 in some other cases wherever supported by the underlying ddclient protocol.
  • While the IP address (and by extension, the detection mechanism) is global, the way it is applied to a particular ddclient protocol depends on whether it supports IPv4 or IPv6 or both.
  • Related to the above, this also prevents generating incorrect config file (ddclient.conf) with multiple global sections leading to an unpredictable behavior of ddclient.
  • Implement provider (protocol) specific custom tweaks whenever possible (e.g., zone, username, server are not necessary in all cases).
  • Move service name from a combination of 'protocol' (with protocol config autodetected) and custom (with protocol config specified) to a single 'service' key. This allows for consisent setup of multiple config for the same ddclient protocol (with different options and credentials). This also avoid ambiguity with usual networking term 'protocol' and ddclient specific term 'protocol' (and can change with a move to a different backend).
  • Apply upfront XML constraints and validations consistently wherever applicable.
  • RFC2136 specific change: Rename rfc2136 config record to host-name for consistency.
  • Cloudflare specific change: While ddclient still supports authenticating with email and global auth key, skipping username in config will indicate the intent to use API token authentication (with special 'token' literal as username).
  • Create migration and bump package version from 0 -> 1 for dynamic dns
  • Relocate ddclient template location for consistency with config path
  • Templatize and simplify systemd override for ddclient service and move the generated
    override files in /run.

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Code style update (formatting, renaming)
  • Refactoring (no functional changes)
  • Migration from an old Vyatta component to vyos-1x, please link to related PR inside obsoleted component
  • Other (please describe):

Related Task(s)

Component(s) name

dns dynamic

How to test

set service dns dynamic address eth3 rfc2136 foo host-name 'rfc-foo-host.example.com'
set service dns dynamic address eth3 rfc2136 foo key '/config/auth/foo'
set service dns dynamic address eth3 rfc2136 foo server 'rfc-foo-server.example.com'
set service dns dynamic address eth3 rfc2136 foo zone 'example.com'

set service dns dynamic address web rfc2136 bar host-name 'rfc-bar-host.example.com'
set service dns dynamic address web rfc2136 bar key '/config/auth/foo'
set service dns dynamic address web rfc2136 bar server 'rfc-bar-server.example.com'
set service dns dynamic address web rfc2136 bar zone 'example.com'
set service dns dynamic address web web-options url 'https://domains.google.com/checkip'

set service dns dynamic address eth3 service cf1 host-name 'bar1.example.com'
set service dns dynamic address eth3 service cf1 ip-version 'both'
set service dns dynamic address eth3 service cf1 password 'api-token-from-cf-dashboard'
set service dns dynamic address eth3 service cf1 protocol 'cloudflare'
set service dns dynamic address eth3 service cf1 zone 'example.com'

set service dns dynamic address eth4 service ddns2 host-name 'ddns2.example.com'
set service dns dynamic address eth4 service ddns2 ip-version 'ipv6'
set service dns dynamic address eth4 service ddns2 password 'pass'
set service dns dynamic address eth4 service ddns2 protocol 'dyndns2'
set service dns dynamic address eth4 service ddns2 server 'ddns-server.example.com'
set service dns dynamic address eth4 service ddns2 username 'ddns2user'

Checklist:

  • I have read the CONTRIBUTING document
  • I have linked this PR to one or more Phabricator Task(s)
  • I have run the components SMOKETESTS if applicable
  • My commit headlines contain a valid Task id
  • My change requires a change to the documentation
  • I have updated the documentation accordingly

@vyosbot vyosbot requested review from a team, dmbaturin, sarthurdev, zdc, jestabro, sever-sever and c-po and removed request for a team May 14, 2023 08:23
@indrajitr indrajitr force-pushed the ddclient-improvement-round-2 branch from 5db9217 to 18962e7 Compare May 14, 2023 08:29
@indrajitr indrajitr marked this pull request as draft May 14, 2023 18:43
@indrajitr indrajitr force-pushed the ddclient-improvement-round-2 branch 2 times, most recently from 5922484 to eba9ea5 Compare May 15, 2023 09:08
@indrajitr
Copy link
Contributor Author

Smoketests updated, up for review.

@indrajitr indrajitr marked this pull request as ready for review May 15, 2023 09:12
@vyosbot vyosbot requested a review from a team May 15, 2023 09:12
@indrajitr indrajitr force-pushed the ddclient-improvement-round-2 branch 2 times, most recently from 9766603 to b57183a Compare May 16, 2023 00:13
@c-po
Copy link
Member

c-po commented May 16, 2023

I actually wonder if we can take out one level from the CLI:

set service dns dynamic eth3 rfc2136 foo host-name 'rfc-foo-host.example.com'
set service dns dynamic eth3 rfc2136 foo key '/config/auth/foo'
set service dns dynamic eth3 rfc2136 foo server 'rfc-foo-server.example.com'
set service dns dynamic eth3 rfc2136 foo zone 'example.com'

set service dns dynamic web rfc2136 bar host-name 'rfc-bar-host.example.com'
set service dns dynamic web rfc2136 bar key '/config/auth/foo'
set service dns dynamic web rfc2136 bar server 'rfc-bar-server.example.com'
set service dns dynamic web rfc2136 bar zone 'example.com'
set service dns dynamic web web-options url 'https://domains.google.com/checkip'

set service dns dynamic eth3 service cf1 host-name 'bar1.example.com'
set service dns dynamic eth3 service cf1 ip-version 'both'
set service dns dynamic eth3 service cf1 password 'api-token-from-cf-dashboard'
set service dns dynamic eth3 service cf1 protocol 'cloudflare'
set service dns dynamic eth3 service cf1 zone 'example.com'

set service dns dynamic eth4 service ddns2 host-name 'ddns2.example.com'
set service dns dynamic eth4 service ddns2 ip-version 'ipv6'
set service dns dynamic eth4 service ddns2 password 'pass'
set service dns dynamic eth4 service ddns2 protocol 'dyndns2'
set service dns dynamic eth4 service ddns2 server 'ddns-server.example.com'
set service dns dynamic eth4 service ddns2 username 'ddns2user'

You can reference the value of a tag node in your Python script by the ENV variable: VYOS_TAGNODE_VALUE

@indrajitr
Copy link
Contributor Author

indrajitr commented May 16, 2023

I actually wonder if we can take out one level from the CLI:

set service dns dynamic eth3 rfc2136 foo host-name 'rfc-foo-host.example.com'
set service dns dynamic eth3 rfc2136 foo key '/config/auth/foo'
set service dns dynamic eth3 rfc2136 foo server 'rfc-foo-server.example.com'
set service dns dynamic eth3 rfc2136 foo zone 'example.com'

set service dns dynamic web rfc2136 bar host-name 'rfc-bar-host.example.com'
set service dns dynamic web rfc2136 bar key '/config/auth/foo'
set service dns dynamic web rfc2136 bar server 'rfc-bar-server.example.com'
set service dns dynamic web rfc2136 bar zone 'example.com'
set service dns dynamic web web-options url 'https://domains.google.com/checkip'

set service dns dynamic eth3 service cf1 host-name 'bar1.example.com'
set service dns dynamic eth3 service cf1 ip-version 'both'
set service dns dynamic eth3 service cf1 password 'api-token-from-cf-dashboard'
set service dns dynamic eth3 service cf1 protocol 'cloudflare'
set service dns dynamic eth3 service cf1 zone 'example.com'

set service dns dynamic eth4 service ddns2 host-name 'ddns2.example.com'
set service dns dynamic eth4 service ddns2 ip-version 'ipv6'
set service dns dynamic eth4 service ddns2 password 'pass'
set service dns dynamic eth4 service ddns2 protocol 'dyndns2'
set service dns dynamic eth4 service ddns2 server 'ddns-server.example.com'
set service dns dynamic eth4 service ddns2 username 'ddns2user'

You can reference the value of a tag node in your Python script by the ENV variable: VYOS_TAGNODE_VALUE

This is precisely what I wanted to do! But couldn't figure out how to keep tagNode and node at the same level, and couldn't find another example in the codebase. Thank you for the VYOS_TAGNODE_VALUE hint, I'll try this tomorrow.

Edit: Knocking off address node is totally doable, it has nothing to do with tagNode and node at the same level. Sorry for the confusion, I'll update the PR tomorrow.

@indrajitr indrajitr force-pushed the ddclient-improvement-round-2 branch 3 times, most recently from 761e6d3 to 2a10a59 Compare May 17, 2023 07:00
@c-po
Copy link
Member

c-po commented May 20, 2023

As you have placed the owner python script on the tagNode, it will be executed for every instance under the tagNode and it will always collect not only dat afor it's instance, but also for all the other instances.

You can see this by the multiple lines of

[ service dns dynamic eth2 ]
[ service dns dynamic eth3 ]

When doing commit. For this to "properly" work I encourage you to make use of multiple ddclient instances (one per tagNode). THis is something we already do for e.g. the interfaces, where the owner is on the tagNode but we only process individual interfaces - see VYOS_TAGNODE_VALUE environment value in vyos-1x repo.

If multiple ddclient instances are not supported (e.g for PID file handling and tear-down) we might need to change the CLI again.

@indrajitr
Copy link
Contributor Author

I now see what you were alluding to on Slack.

If multiple ddclient instances are not supported (e.g for PID file handling and tear-down) we might need to change the CLI again.

I think this should be doable with ddclient by making disabling daemon mode and let systems timer handle them. But there are other aspects to consider:

  • whether the same flexibility can be achieved with other providers in consideration
  • if we stick with ddclient long term (with a small set of patches), I was considering additional ways to detect IP address beyond interface and web, viz., cmd (custom command like dig/curl whatever). Will have to see if the CLI feels as intuitive in those cases as well.

Apply next round of configuration tree updates to 'service dns dynamic'
with the following changes:

- Migrate `service dns dynamic interface <interface> [use-web]`
       to `service dns dynamic address <interface>`
       or `service dns dynamic address web [web-options]`
  This communicates the intent that dynamic dns IP address is detected
  in only one way - using the `<interface>` or using an external web
  request, not both.
- When using external web request, (`service dns dynamic address web`),
  external url is optional (`web-options url`). Ddclient defaults are
  used when unspecified,
- Rename all config `login` to `username` for consistency and also to
  align better with alternative ddclient backends in consideration.
- Apply global 'ipv6-enable' to per service 'ip-version: ipv6'. Selecting
  usage of IPv4 or IPv6 (or both simultaneously) is now at per service
  (protocol) level instead of global level. This allows more control on
  the ability to select IPv4 in some cases and IPv6 in some other cases
  wherever supported by the underlying ddclient protocol.
- While the IP address (and by extension, the detection mechanism) is
  global, the way it is applied to a particular ddclient protocol depends
  on whether it supports IPv4 or IPv6 or both.
- Related to the above, this also prevents generating incorrect config
  file (`ddclient.conf`) with multiple global sections leading to an
  unpredictable behavior of ddclient.
- Implement provider (protocol) specific custom tweaks whenever possible
  (e.g., `zone`, `username`, `server` are not necessary in all cases).
- Move service name from a combination of 'protocol' (with protocol
  config autodetected) and custom (with protocol config specified) to a
  single 'service' key. This allows for consisent setup of multiple
  config for the same ddclient protocol (with different options and
  credentials). This also avoid ambiguity with usual networking term
  'protocol' and ddclient specific term 'protocol' (and can change with
  a move to a different backend).
- Apply upfront XML constraints and validations consistently wherever
  applicable.
- RFC2136 specific change: Rename rfc2136 config `record` to `host-name`
  for consistency.
- Cloudflare specific change: While ddclient still supports authenticating
  with email and global auth key, skipping `username` in config will
  indicate the intent to use API token authentication (with special
  'token' literal as `username`).
ddclient implementation of dualstack for dyndns2 protocol is targeted
for dyn.com (dyndns.org) only. Dualstack won't work for other servers
supporting dyndns2 protocol (for example, dyn.dns.he.net).
Create migration and bump package version from 0 -> 1 for dynamic dns
Templatize systemd override for ddclient service and move the generated
override files in /run. This ensures that the override files are always
generated afresh after boot.

Additionally, simplify the systemd override file by removing the
redundant/superfluous overrides.
@indrajitr indrajitr force-pushed the ddclient-improvement-round-2 branch from 2a10a59 to c14825f Compare June 4, 2023 09:11
@indrajitr
Copy link
Contributor Author

Updated with the previous implementation of CLI reinstated.

That said, the necessary groundwork to self-contain cache config, PID config etc. is in place and can be taken up in the future depending on whether we settle with ddclient or any alternative backend.

@c-po c-po merged commit 47cce68 into vyos:current Jun 5, 2023
4 of 6 checks passed
@indrajitr indrajitr deleted the ddclient-improvement-round-2 branch June 8, 2023 18:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
2 participants