diff options
| -rw-r--r-- | data/templates/dns-dynamic/ddclient.conf.j2 | 7 | ||||
| -rw-r--r-- | interface-definitions/service_dns_dynamic.xml.in | 47 | ||||
| -rwxr-xr-x | src/conf_mode/service_dns_dynamic.py | 49 | 
3 files changed, 49 insertions, 54 deletions
| diff --git a/data/templates/dns-dynamic/ddclient.conf.j2 b/data/templates/dns-dynamic/ddclient.conf.j2 index 6c0653a55..5538ea56c 100644 --- a/data/templates/dns-dynamic/ddclient.conf.j2 +++ b/data/templates/dns-dynamic/ddclient.conf.j2 @@ -7,7 +7,7 @@ use{{ ipv }}={{ address if address == 'web' else 'if' }}{{ ipv }}, \  web{{ ipv }}={{ web_options.url }}, \  {%         endif %}  {%         if web_options.skip is vyos_defined %} -web-skip{{ ipv }}='{{ web_options.skip }}', \ +web{{ ipv }}-skip='{{ web_options.skip }}', \  {%         endif %}  {%     else %}  if{{ ipv }}={{ address }}, \ @@ -45,9 +45,12 @@ use=no                                         else ['']) %}  {%             set password = config.key if config.protocol == 'nsupdate'                                else config.password %} +{%             set address = 'web' if config.address.web is vyos_defined +                              else config.address.interface %} +{%             set web_options = config.address.web | default({}) %}  # Web service dynamic DNS configuration for {{ service }}: [{{ config.protocol }}, {{ host }}] -{{ render_config(host, config.address, config.web_options, ip_suffixes, +{{ render_config(host, address, web_options, ip_suffixes,                   protocol=config.protocol, server=config.server, zone=config.zone,                   login=config.username, password=password, ttl=config.ttl,                   min_interval=config.wait_time, max_interval=config.expiry_time) }} diff --git a/interface-definitions/service_dns_dynamic.xml.in b/interface-definitions/service_dns_dynamic.xml.in index d1b0e90bb..75e5520b7 100644 --- a/interface-definitions/service_dns_dynamic.xml.in +++ b/interface-definitions/service_dns_dynamic.xml.in @@ -38,42 +38,29 @@                        </constraint>                      </properties>                    </leafNode> -                  <leafNode name="address"> +                  <node name="address">                      <properties>                        <help>Obtain IP address to send Dynamic DNS update for</help> -                      <valueHelp> -                        <format>txt</format> -                        <description>Use interface to obtain the IP address</description> -                      </valueHelp> -                      <valueHelp> -                        <format>web</format> -                        <description>Use HTTP(S) web request to obtain the IP address</description> -                      </valueHelp> -                      <completionHelp> -                        <script>${vyos_completion_dir}/list_interfaces</script> -                        <list>web</list> -                      </completionHelp> -                      <constraint> -                        #include <include/constraint/interface-name.xml.i> -                        <regex>web</regex> -                      </constraint> -                    </properties> -                  </leafNode> -                  <node name="web-options"> -                    <properties> -                      <help>Options when using HTTP(S) web request to obtain the IP address</help>                      </properties>                      <children> -                      #include <include/url-http-https.xml.i> -                      <leafNode name="skip"> +                      #include <include/generic-interface.xml.i> +                      <node name="web">                          <properties> -                          <help>Pattern to skip from the HTTP(S) respose</help> -                          <valueHelp> -                            <format>txt</format> -                            <description>Pattern to skip from the HTTP(S) respose to extract the external IP address</description> -                          </valueHelp> +                          <help>HTTP(S) web request to use</help>                          </properties> -                      </leafNode> +                        <children> +                          #include <include/url-http-https.xml.i> +                          <leafNode name="skip"> +                            <properties> +                              <help>Pattern to skip from the HTTP(S) respose</help> +                              <valueHelp> +                                <format>txt</format> +                                <description>Pattern to skip from the HTTP(S) respose to extract the external IP address</description> +                              </valueHelp> +                            </properties> +                          </leafNode> +                        </children> +                      </node>                      </children>                    </node>                    <leafNode name="ip-version"> diff --git a/src/conf_mode/service_dns_dynamic.py b/src/conf_mode/service_dns_dynamic.py index 845aaa1b5..a551a9891 100755 --- a/src/conf_mode/service_dns_dynamic.py +++ b/src/conf_mode/service_dns_dynamic.py @@ -1,6 +1,6 @@  #!/usr/bin/env python3  # -# Copyright (C) 2018-2023 VyOS maintainers and contributors +# Copyright (C) 2018-2024 VyOS maintainers and contributors  #  # This program is free software; you can redistribute it and/or modify  # it under the terms of the GNU General Public License version 2 or later as @@ -87,31 +87,36 @@ def verify(dyndns):              if field not in config:                  raise ConfigError(f'"{field.replace("_", "-")}" {error_msg_req}') -        # If dyndns address is an interface, ensure -        # that the interface exists (or just warn if dynamic interface) -        # and that web-options are not set -        if config['address'] != 'web': +        if not any(x in config['address'] for x in ['interface', 'web']): +            raise ConfigError(f'Either "interface" or "web" {error_msg_req} ' +                              f'with protocol "{config["protocol"]}"') +        if all(x in config['address'] for x in ['interface', 'web']): +            raise ConfigError(f'Both "interface" and "web" at the same time {error_msg_uns} ' +                              f'with protocol "{config["protocol"]}"') + +        # If dyndns address is an interface, ensure that the interface exists +        # and warn if a non-active dynamic interface is used +        if 'interface' in config['address']:              tmp = re.compile(dynamic_interface_pattern)              # exclude check interface for dynamic interfaces -            if tmp.match(config["address"]): -                if not interface_exists(config["address"]): -                    Warning(f'Interface "{config["address"]}" does not exist yet and cannot ' -                            f'be used for Dynamic DNS service "{service}" until it is up!') +            if tmp.match(config['address']['interface']): +                if not interface_exists(config['address']['interface']): +                    Warning(f'Interface "{config["address"]["interface"]}" does not exist yet and ' +                            f'cannot be used for Dynamic DNS service "{service}" until it is up!')              else: -                verify_interface_exists(config['address']) -            if 'web_options' in config: -                raise ConfigError(f'"web-options" is applicable only when using HTTP(S) ' -                                  f'web request to obtain the IP address') - -        # Warn if using checkip.dyndns.org, as it does not support HTTPS -        # See: https://github.com/ddclient/ddclient/issues/597 -        if 'web_options' in config: -            if 'url' not in config['web_options']: -                raise ConfigError(f'"url" in "web-options" {error_msg_req} ' +                verify_interface_exists(config['address']['interface']) + +        if 'web' in config['address']: +            # If 'skip' is specified, 'url' is required as well +            if 'skip' in config['address']['web'] and 'url' not in config['address']['web']: +                raise ConfigError(f'"url" along with "skip" {error_msg_req} '                                    f'with protocol "{config["protocol"]}"') -            elif re.search("^(https?://)?checkip\.dyndns\.org", config['web_options']['url']): -                Warning(f'"checkip.dyndns.org" does not support HTTPS requests for IP address ' -                        f'lookup. Please use a different IP address lookup service.') +            if 'url' in config['address']['web']: +                # Warn if using checkip.dyndns.org, as it does not support HTTPS +                # See: https://github.com/ddclient/ddclient/issues/597 +                if re.search("^(https?://)?checkip\.dyndns\.org", config['address']['web']['url']): +                    Warning(f'"checkip.dyndns.org" does not support HTTPS requests for IP address ' +                            f'lookup. Please use a different IP address lookup service.')          # RFC2136 uses 'key' instead of 'password'          if config['protocol'] != 'nsupdate' and 'password' not in config: | 
