From 35e88be03f013e0ae240b6ec9b73fdd8d36ed75e Mon Sep 17 00:00:00 2001 From: Indrajit Raychaudhuri Date: Thu, 21 Sep 2023 22:04:15 -0500 Subject: ddclient: T5612: Refactor zone configuration Refactor zone configuration to use shared XML snippet for all cases. --- .../include/dns/dynamic-service-zone.xml.i | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 interface-definitions/include/dns/dynamic-service-zone.xml.i (limited to 'interface-definitions/include') diff --git a/interface-definitions/include/dns/dynamic-service-zone.xml.i b/interface-definitions/include/dns/dynamic-service-zone.xml.i new file mode 100644 index 000000000..0cc00468f --- /dev/null +++ b/interface-definitions/include/dns/dynamic-service-zone.xml.i @@ -0,0 +1,14 @@ + + + + DNS zone to be updated + + txt + Name of DNS zone + + + + + + + -- cgit v1.2.3 From 8088cb8b6aacf9b7003845e4c9081b7f569b6fac Mon Sep 17 00:00:00 2001 From: Indrajit Raychaudhuri Date: Thu, 21 Sep 2023 21:35:18 -0500 Subject: ddclient: T5612: Enable TTL support for web-service based protocols Enable TTL support for web-service based protocols in addition to RFC2136 based (nsupdate) protocol. Since TTL is not supported by all protocols, and thus cannot have a configuration default, the existing XML snippet `include/dns/time-to-live.xml.i` does not have common `300` anymore and is instead added explicitly whenever necessary. --- data/templates/dns-dynamic/ddclient.conf.j2 | 2 +- interface-definitions/dns-dynamic.xml.in | 1 + interface-definitions/dns-forwarding.xml.in | 30 ++++++++++++++++++++++ .../include/dns/time-to-live.xml.i | 1 - smoketest/scripts/cli/test_service_dns_dynamic.py | 19 +++++++++++--- src/conf_mode/dns_dynamic.py | 6 +++++ 6 files changed, 53 insertions(+), 6 deletions(-) (limited to 'interface-definitions/include') diff --git a/data/templates/dns-dynamic/ddclient.conf.j2 b/data/templates/dns-dynamic/ddclient.conf.j2 index f2a20d4b8..5905b19ea 100644 --- a/data/templates/dns-dynamic/ddclient.conf.j2 +++ b/data/templates/dns-dynamic/ddclient.conf.j2 @@ -66,7 +66,7 @@ use=no # Web service dynamic DNS configuration for {{ name }}: [{{ config.protocol }}, {{ host }}] {{ render_config(host, address, service_cfg.web_options, ip_suffixes, protocol=config.protocol, server=config.server, zone=config.zone, - login=config.username, password=config.password) }} + login=config.username, password=config.password, ttl=config.ttl) }} {% endfor %} {% endfor %} diff --git a/interface-definitions/dns-dynamic.xml.in b/interface-definitions/dns-dynamic.xml.in index 8d08bf37d..ba7f426c1 100644 --- a/interface-definitions/dns-dynamic.xml.in +++ b/interface-definitions/dns-dynamic.xml.in @@ -90,6 +90,7 @@ #include #include #include + #include ddclient protocol used for Dynamic DNS service diff --git a/interface-definitions/dns-forwarding.xml.in b/interface-definitions/dns-forwarding.xml.in index 86dc47a47..c4295317a 100644 --- a/interface-definitions/dns-forwarding.xml.in +++ b/interface-definitions/dns-forwarding.xml.in @@ -158,6 +158,9 @@ #include + + 300 + #include @@ -195,6 +198,9 @@ #include + + 300 + #include @@ -227,6 +233,9 @@ #include + + 300 + #include @@ -274,6 +283,9 @@ #include + + 300 + #include @@ -302,6 +314,9 @@ #include + + 300 + #include @@ -334,6 +349,9 @@ #include + + 300 + #include @@ -364,6 +382,9 @@ #include + + 300 + #include @@ -393,6 +414,9 @@ #include + + 300 + #include @@ -477,6 +501,9 @@ #include + + 300 + #include @@ -585,6 +612,9 @@ #include + + 300 + #include diff --git a/interface-definitions/include/dns/time-to-live.xml.i b/interface-definitions/include/dns/time-to-live.xml.i index 5c1a1472d..000eea108 100644 --- a/interface-definitions/include/dns/time-to-live.xml.i +++ b/interface-definitions/include/dns/time-to-live.xml.i @@ -10,6 +10,5 @@ - 300 diff --git a/smoketest/scripts/cli/test_service_dns_dynamic.py b/smoketest/scripts/cli/test_service_dns_dynamic.py index 366b063c7..aa4891829 100755 --- a/smoketest/scripts/cli/test_service_dns_dynamic.py +++ b/smoketest/scripts/cli/test_service_dns_dynamic.py @@ -63,18 +63,29 @@ class TestServiceDDNS(VyOSUnitTestSHIM.TestCase): self.cli_set(base_path + ddns + [svc, 'host-name', hostname]) self.cli_set(base_path + ddns + [svc, 'password', password]) self.cli_set(base_path + ddns + [svc, 'zone', zone]) + self.cli_set(base_path + ddns + [svc, 'ttl', ttl]) for opt, value in details.items(): self.cli_set(base_path + ddns + [svc, opt, value]) - # commit changes + # 'zone' option is supported and required by 'cloudfare', but not 'freedns' and 'zoneedit' + self.cli_set(base_path + ddns + [svc, 'zone', zone]) + if details['protocol'] == 'cloudflare': + pass + else: + # exception is raised for unsupported ones + with self.assertRaises(ConfigSessionError): + self.cli_commit() + self.cli_delete(base_path + ddns + [svc, 'zone']) + + # 'ttl' option is supported by 'cloudfare', but not 'freedns' and 'zoneedit' + self.cli_set(base_path + ddns + [svc, 'ttl', ttl]) if details['protocol'] == 'cloudflare': pass else: - # zone option does not work on all protocols, an exception is - # raised for all others + # exception is raised for unsupported ones with self.assertRaises(ConfigSessionError): self.cli_commit() - self.cli_delete(base_path + ddns + [svc, 'zone', zone]) + self.cli_delete(base_path + ddns + [svc, 'ttl']) # commit changes self.cli_commit() diff --git a/src/conf_mode/dns_dynamic.py b/src/conf_mode/dns_dynamic.py index 84c983ee3..5150574a8 100755 --- a/src/conf_mode/dns_dynamic.py +++ b/src/conf_mode/dns_dynamic.py @@ -35,6 +35,9 @@ zone_required = ['cloudflare', 'godaddy', 'hetzner', 'gandi', 'nfsn'] # Protocols that do not require username username_unnecessary = ['1984', 'cloudflare', 'cloudns', 'duckdns', 'freemyip', 'hetzner', 'keysystems', 'njalla'] +# Protocols that support TTL +ttl_supported = ['cloudflare', 'gandi', 'hetzner', 'dnsexit', 'godaddy', 'nfsn'] + # Protocols that support both IPv4 and IPv6 dualstack_supported = ['cloudflare', 'dyndns2', 'freedns', 'njalla'] @@ -97,6 +100,9 @@ def verify(dyndns): if 'username' not in config: raise ConfigError(f'"username" {error_msg}') + if config['protocol'] not in ttl_supported and 'ttl' in config: + raise ConfigError(f'"{config["protocol"]}" does not support "ttl"') + if config['ip_version'] == 'both': if config['protocol'] not in dualstack_supported: raise ConfigError(f'"{config["protocol"]}" does not support ' -- cgit v1.2.3 From f0a8d0d8c622e67ef66c370747f13d4fdb6fd773 Mon Sep 17 00:00:00 2001 From: Indrajit Raychaudhuri Date: Sat, 23 Sep 2023 19:06:03 -0500 Subject: ddclient: T5612: Relax hostname validation for apex and wildcard entry Some porvides (like 'namecheap') allow to use '@' or '*' as hostname prefix for apex and wildcard records. This commit relaxes the hostname validation to allow these prefixes. --- .../dns/dynamic-service-host-name-server.xml.i | 3 ++- smoketest/scripts/cli/test_service_dns_dynamic.py | 26 +++++++++++++++++++++- 2 files changed, 27 insertions(+), 2 deletions(-) (limited to 'interface-definitions/include') diff --git a/interface-definitions/include/dns/dynamic-service-host-name-server.xml.i b/interface-definitions/include/dns/dynamic-service-host-name-server.xml.i index ee1af2a36..9dd14f97c 100644 --- a/interface-definitions/include/dns/dynamic-service-host-name-server.xml.i +++ b/interface-definitions/include/dns/dynamic-service-host-name-server.xml.i @@ -4,8 +4,9 @@ Hostname to register with Dynamic DNS service #include + (\@|\*)[-.A-Za-z0-9]* - Host-name must be alphanumeric and can contain hyphens + Host-name must be alphanumeric, can contain hyphens and can be prefixed with '@' or '*' diff --git a/smoketest/scripts/cli/test_service_dns_dynamic.py b/smoketest/scripts/cli/test_service_dns_dynamic.py index aa4891829..f1870320e 100755 --- a/smoketest/scripts/cli/test_service_dns_dynamic.py +++ b/smoketest/scripts/cli/test_service_dns_dynamic.py @@ -203,7 +203,31 @@ class TestServiceDDNS(VyOSUnitTestSHIM.TestCase): self.assertIn(f'password={key_file.name}', ddclient_conf) self.assertIn(f'ttl={ttl}', ddclient_conf) - def test_05_dyndns_vrf(self): + def test_05_dyndns_hostname(self): + # Check if DDNS service can be configured and runs + svc_path = ['address', interface, 'service', 'namecheap'] + proto = 'namecheap' + hostnames = ['@', 'www', hostname, f'@.{hostname}'] + + for name in hostnames: + self.cli_set(base_path + svc_path + ['protocol', proto]) + self.cli_set(base_path + svc_path + ['server', server]) + self.cli_set(base_path + svc_path + ['username', username]) + self.cli_set(base_path + svc_path + ['password', password]) + self.cli_set(base_path + svc_path + ['host-name', name]) + + # commit changes + self.cli_commit() + + # Check the generating config parameters + ddclient_conf = cmd(f'sudo cat {DDCLIENT_CONF}') + self.assertIn(f'protocol={proto}', ddclient_conf) + self.assertIn(f'server={server}', ddclient_conf) + self.assertIn(f'login={username}', ddclient_conf) + self.assertIn(f'password={password}', ddclient_conf) + self.assertIn(f'{name}', ddclient_conf) + + def test_06_dyndns_vrf(self): vrf_name = f'vyos-test-{"".join(random.choices(string.ascii_letters + string.digits, k=5))}' svc_path = ['address', interface, 'service', 'cloudflare'] -- cgit v1.2.3