From 0c63c84e505033474368b7842e271ee8614c9e51 Mon Sep 17 00:00:00 2001
From: Indrajit Raychaudhuri <irc@indrajit.com>
Date: Fri, 21 Apr 2023 00:51:34 -0500
Subject: dns: T5144: Improve dynamic DNS validations and completions

Apply validations and completions to dynamic DNS protocols supported.
This also opens up additional protocols supported by ddclient 3.10.

Additional details:
- Validation and constraint have been added for interface names as well.
- While at it, the help texts got some copyedit and rewording.
---
 interface-definitions/dns-dynamic.xml.in  | 116 +++++-------------------------
 src/completion/list_ddclient_protocols.sh |  17 +++++
 src/validators/ddclient-protocol          |  24 +++++++
 3 files changed, 60 insertions(+), 97 deletions(-)
 create mode 100755 src/completion/list_ddclient_protocols.sh
 create mode 100755 src/validators/ddclient-protocol

diff --git a/interface-definitions/dns-dynamic.xml.in b/interface-definitions/dns-dynamic.xml.in
index 58dd48f9d..3e77e2540 100644
--- a/interface-definitions/dns-dynamic.xml.in
+++ b/interface-definitions/dns-dynamic.xml.in
@@ -14,10 +14,17 @@
             <children>
               <tagNode name="interface">
                 <properties>
-                  <help>Interface to send DDNS updates for</help>
+                  <help>Interface to send Dynamic DNS updates for</help>
                   <completionHelp>
                     <script>${vyos_completion_dir}/list_interfaces</script>
                   </completionHelp>
+                  <valueHelp>
+                    <format>txt</format>
+                    <description>Interface name</description>
+                  </valueHelp>
+                  <constraint>
+                    #include <include/constraint/interface-name.xml.i>
+                  </constraint>
                 </properties>
                 <children>
                   <tagNode name="rfc2136">
@@ -127,144 +134,59 @@
                     <children>
                       <leafNode name="host-name">
                         <properties>
-                          <help>Hostname registered with DDNS service</help>
+                          <help>Hostname to register with Dynamic DNS service</help>
                           <multi/>
                         </properties>
                       </leafNode>
                       <leafNode name="login">
                         <properties>
-                          <help>Login for DDNS service</help>
+                          <help>Login for Dynamic DNS service (not used by all protocols, or referred as api-token in some cases)</help>
                         </properties>
                       </leafNode>
                       <leafNode name="password">
                         <properties>
-                          <help>Password for DDNS service</help>
+                          <help>Password for Dynamic DNS service (referred as api-token, global-token or api-secret in some cases)</help>
                         </properties>
                       </leafNode>
                       <leafNode name="protocol">
                         <properties>
-                          <help>ddclient protocol used for DDNS service</help>
+                          <help>ddclient protocol used for Dynamic DNS service</help>
                           <completionHelp>
-                            <list>changeip cloudflare dnsmadeeasy dnspark dondominio dslreports1 dtdns duckdns dyndns2 easydns freedns freemyip googledomains hammernode1 namecheap nfsn noip sitelutions woima yandex zoneedit1</list>
+                            <script>${vyos_completion_dir}/list_ddclient_protocols.sh</script>
                           </completionHelp>
-                          <valueHelp>
-                            <format>changeip</format>
-                            <description>ChangeIP protocol</description>
-                          </valueHelp>
-                          <valueHelp>
-                            <format>cloudflare</format>
-                            <description>Cloudflare protocol</description>
-                          </valueHelp>
-                          <valueHelp>
-                            <format>dnsmadeeasy</format>
-                            <description>DNS Made Easy protocol</description>
-                          </valueHelp>
-                          <valueHelp>
-                            <format>dnspark</format>
-                            <description>DNS Park protocol</description>
-                          </valueHelp>
-                          <valueHelp>
-                            <format>dondominio</format>
-                            <description>DonDominio protocol</description>
-                          </valueHelp>
-                          <valueHelp>
-                            <format>dslreports1</format>
-                            <description>DslReports protocol</description>
-                          </valueHelp>
-                          <valueHelp>
-                            <format>dtdns</format>
-                            <description>DtDNS protocol</description>
-                          </valueHelp>
-                          <valueHelp>
-                            <format>duckdns</format>
-                            <description>DuckDNS protocol</description>
-                          </valueHelp>
-                          <valueHelp>
-                            <format>dyndns2</format>
-                            <description>DynDNS protocol v2</description>
-                          </valueHelp>
-                          <valueHelp>
-                            <format>easydns</format>
-                            <description>easyDNS protocol</description>
-                          </valueHelp>
-                          <valueHelp>
-                            <format>freedns</format>
-                            <description>FreeDNS protocol</description>
-                          </valueHelp>
-                          <valueHelp>
-                            <format>freemyip</format>
-                            <description>freemyip protocol</description>
-                          </valueHelp>
-                          <valueHelp>
-                            <format>googledomains</format>
-                            <description>Google domains protocol</description>
-                          </valueHelp>
-                          <valueHelp>
-                            <format>hammernode1</format>
-                            <description>Hammernode protocol</description>
-                          </valueHelp>
-                          <valueHelp>
-                            <format>namecheap</format>
-                            <description>Namecheap protocol</description>
-                          </valueHelp>
-                          <valueHelp>
-                            <format>nfsn</format>
-                            <description>NearlyFreeSpeech DNS protocol</description>
-                          </valueHelp>
-                          <valueHelp>
-                            <format>noip</format>
-                            <description>No-IP protocol</description>
-                          </valueHelp>
-                          <valueHelp>
-                            <format>sitelutions</format>
-                            <description>Sitelutions protocol</description>
-                          </valueHelp>
-                          <valueHelp>
-                            <format>woima</format>
-                            <description>WOIMA protocol</description>
-                          </valueHelp>
-                          <valueHelp>
-                            <format>yandex</format>
-                            <description>Yandex.DNS protocol</description>
-                          </valueHelp>
-                          <valueHelp>
-                            <format>zoneedit1</format>
-                            <description>Zoneedit protocol</description>
-                          </valueHelp>
                           <constraint>
-                            <regex>(changeip|cloudflare|dnsmadeeasy|dnspark|dondominio|dslreports1|dtdns|duckdns|dyndns2|easydns|freedns|freemyip|googledomains|hammernode1|namecheap|nfsn|noip|sitelutions|woima|yandex|zoneedit1)</regex>
+                            <validator name="ddclient-protocol"/>
                           </constraint>
-                          <constraintErrorMessage>Please choose from the list of allowed protocols</constraintErrorMessage>
                         </properties>
                       </leafNode>
                       #include <include/server-ipv4-fqdn.xml.i>
                       <leafNode name="zone">
                         <properties>
-                          <help>DNS zone to update (only available with CloudFlare)</help>
+                          <help>DNS zone to update (not used by all protocols)</help>
                         </properties>
                       </leafNode>
                     </children>
                   </tagNode>
                   <node name="use-web">
                     <properties>
-                      <help>Web check used for obtaining the external IP address</help>
+                      <help>Use http(s) web request to obtain the external IP address instead of the IP address associated with the interface</help>
                     </properties>
                     <children>
                       <leafNode name="skip">
                         <properties>
-                          <help>Skip everything before this on the given URL</help>
+                          <help>Text pattern to skip from the respose of the given URL to extract the external IP address</help>
                         </properties>
                       </leafNode>
                       <leafNode name="url">
                         <properties>
-                          <help>URL to obtain the current external IP address</help>
+                          <help>Custom URL to obtain the current external IP address over http(s) web request, overriding ddclient default</help>
                         </properties>
                       </leafNode>
                     </children>
                   </node>
                   <leafNode name="ipv6-enable">
                     <properties>
-                      <help>Allow explicit IPv6 addresses for Dynamic DNS for this interface</help>
+                      <help>Explicitly use IPv6 address instead of IPv4 address to update the Dynamic DNS IP address</help>
                       <valueless/>
                     </properties>
                   </leafNode>
diff --git a/src/completion/list_ddclient_protocols.sh b/src/completion/list_ddclient_protocols.sh
new file mode 100755
index 000000000..75fb0cf44
--- /dev/null
+++ b/src/completion/list_ddclient_protocols.sh
@@ -0,0 +1,17 @@
+#!/bin/sh
+#
+# Copyright (C) 2023 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
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+echo -n $(ddclient -list-protocols)
diff --git a/src/validators/ddclient-protocol b/src/validators/ddclient-protocol
new file mode 100755
index 000000000..6f927927b
--- /dev/null
+++ b/src/validators/ddclient-protocol
@@ -0,0 +1,24 @@
+#!/bin/sh
+#
+# Copyright (C) 2023 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
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+ddclient -list-protocols | grep -qw $1
+
+if [ $? -gt 0 ]; then
+    echo "Error: $1 is not a valid protocol, please choose from the supported list of protocols"
+    exit 1
+fi
+
+exit 0
-- 
cgit v1.2.3


From 2f278d4dd00caf2b30b3908545d982062a6eb68d Mon Sep 17 00:00:00 2001
From: Christian Breunig <christian@breunig.cc>
Date: Mon, 8 May 2023 08:32:35 +0200
Subject: dns: T4144: additional improvements to dynamic DNS XML definitions

* Re-use XML building blocks when poossible
* Use XML constraints when possible (password)
* Capitalize protocols (HTTP) in <help> strings
---
 interface-definitions/dns-dynamic.xml.in | 30 +++++++++++++++++-------------
 1 file changed, 17 insertions(+), 13 deletions(-)

diff --git a/interface-definitions/dns-dynamic.xml.in b/interface-definitions/dns-dynamic.xml.in
index 3e77e2540..48c101d73 100644
--- a/interface-definitions/dns-dynamic.xml.in
+++ b/interface-definitions/dns-dynamic.xml.in
@@ -135,19 +135,19 @@
                       <leafNode name="host-name">
                         <properties>
                           <help>Hostname to register with Dynamic DNS service</help>
+                          <constraint>
+                            #include <include/constraint/host-name.xml.i>
+                          </constraint>
+                          <constraintErrorMessage>Host-name must be alphanumeric and can contain hyphens</constraintErrorMessage>
                           <multi/>
                         </properties>
                       </leafNode>
                       <leafNode name="login">
                         <properties>
-                          <help>Login for Dynamic DNS service (not used by all protocols, or referred as api-token in some cases)</help>
-                        </properties>
-                      </leafNode>
-                      <leafNode name="password">
-                        <properties>
-                          <help>Password for Dynamic DNS service (referred as api-token, global-token or api-secret in some cases)</help>
+                          <help>Login/Username for Dynamic DNS service</help>
                         </properties>
                       </leafNode>
+                      #include <include/generic-password.xml.i>
                       <leafNode name="protocol">
                         <properties>
                           <help>ddclient protocol used for Dynamic DNS service</help>
@@ -163,25 +163,29 @@
                       <leafNode name="zone">
                         <properties>
                           <help>DNS zone to update (not used by all protocols)</help>
+                          <valueHelp>
+                            <format>txt</format>
+                            <description>Name of DNS zone</description>
+                          </valueHelp>
                         </properties>
                       </leafNode>
                     </children>
                   </tagNode>
                   <node name="use-web">
                     <properties>
-                      <help>Use http(s) web request to obtain the external IP address instead of the IP address associated with the interface</help>
+                      <help>Use HTTP(S) web request to obtain external IP address instead of the IP address associated with the interface</help>
                     </properties>
                     <children>
                       <leafNode name="skip">
                         <properties>
-                          <help>Text pattern to skip from the respose of the given URL to extract the external IP address</help>
-                        </properties>
-                      </leafNode>
-                      <leafNode name="url">
-                        <properties>
-                          <help>Custom URL to obtain the current external IP address over http(s) web request, overriding ddclient default</help>
+                          <help>Pattern to skip from the respose</help>
+                          <valueHelp>
+                            <format>txt</format>
+                            <description>Pattern to skip from the respose of the given URL to extract the external IP address</description>
+                          </valueHelp>
                         </properties>
                       </leafNode>
+                      #include <include/url.xml.i>
                     </children>
                   </node>
                   <leafNode name="ipv6-enable">
-- 
cgit v1.2.3