ddns-scripts: add support for Scaleway DNS
authorLars Kaiser <[email protected]>
Wed, 19 Mar 2025 01:20:12 +0000 (02:20 +0100)
committerFlorian Eckert <[email protected]>
Tue, 1 Apr 2025 06:57:10 +0000 (08:57 +0200)
Signed-off-by: Lars Kaiser <[email protected]>
net/ddns-scripts/Makefile
net/ddns-scripts/files/usr/lib/ddns/update_scaleway_com.sh [new file with mode: 0755]
net/ddns-scripts/files/usr/share/ddns/default/scaleway.com.json [new file with mode: 0644]

index 2db9b944830c3434b44834f5811faa4048eafa74..ad395666d521075d8e247481edebfd33a3419b7e 100644 (file)
@@ -8,7 +8,7 @@ include $(TOPDIR)/rules.mk
 
 PKG_NAME:=ddns-scripts
 PKG_VERSION:=2.8.2
-PKG_RELEASE:=65
+PKG_RELEASE:=66
 
 PKG_LICENSE:=GPL-2.0
 
@@ -270,6 +270,20 @@ define Package/ddns-scripts-pdns/description
   'option password' to be a valid API key for the PowerDNS webserver
 endef
 
+define Package/ddns-scripts-scaleway
+  $(call Package/ddns-scripts/Default)
+  TITLE:=Extension for Scaleway DNS API
+  DEPENDS:=ddns-scripts +curl
+endef
+
+define Package/ddns-scripts-scaleway
+  Dynamic DNS Client scripts extension for Scaleway.
+  Parameters:
+  'option username'  The zone in which the RR is to be set
+  'option password'  The Scaleway API token with sufficient access rights
+  'option domain'    The domain to be updated
+  'option param_opt' (Optional) The TTL of the RR
+endef
 
 define Package/ddns-scripts-transip
   $(call Package/ddns-scripts/Default)
@@ -407,6 +421,7 @@ define Package/ddns-scripts-services/install
        rm $(1)/usr/share/ddns/default/cnkuai.cn.json
        rm $(1)/usr/share/ddns/default/gandi.net.json
        rm $(1)/usr/share/ddns/default/pdns.json
+       rm $(1)/usr/share/ddns/default/scaleway.com.json
        rm $(1)/usr/share/ddns/default/transip.nl.json
        rm $(1)/usr/share/ddns/default/ns1.com.json
        rm $(1)/usr/share/ddns/default/one.com.json
@@ -709,6 +724,25 @@ exit 0
 endef
 
 
+define Package/ddns-scripts-scaleway/install
+       $(INSTALL_DIR) $(1)/usr/lib/ddns
+       $(INSTALL_BIN) ./files/usr/lib/ddns/update_scaleway_com.sh \
+               $(1)/usr/lib/ddns
+
+       $(INSTALL_DIR) $(1)/usr/share/ddns/default
+       $(INSTALL_DATA) ./files/usr/share/ddns/default/scaleway.com.json \
+               $(1)/usr/share/ddns/default
+endef
+
+define Package/ddns-scripts-scaleway/prerm
+#!/bin/sh
+if [ -z "$${IPKG_INSTROOT}" ]; then
+       /etc/init.d/ddns stop
+fi
+exit 0
+endef
+
+
 define Package/ddns-scripts-transip/install
        $(INSTALL_DIR) $(1)/usr/lib/ddns
        $(INSTALL_BIN) ./files/usr/lib/ddns/update_transip_nl.sh \
@@ -802,6 +836,7 @@ $(eval $(call BuildPackage,ddns-scripts-route53))
 $(eval $(call BuildPackage,ddns-scripts-cnkuai))
 $(eval $(call BuildPackage,ddns-scripts-gandi))
 $(eval $(call BuildPackage,ddns-scripts-pdns))
+$(eval $(call BuildPackage,ddns-scripts-scaleway))
 $(eval $(call BuildPackage,ddns-scripts-transip))
 $(eval $(call BuildPackage,ddns-scripts-ns1))
 $(eval $(call BuildPackage,ddns-scripts-one))
diff --git a/net/ddns-scripts/files/usr/lib/ddns/update_scaleway_com.sh b/net/ddns-scripts/files/usr/lib/ddns/update_scaleway_com.sh
new file mode 100755 (executable)
index 0000000..2f07107
--- /dev/null
@@ -0,0 +1,108 @@
+#!/bin/sh
+
+# This script sends DNS updates using the Scaleway DNS API.
+# See https://www.scaleway.com/en/developers/api/domains-and-dns/
+#
+# This script uses an API token created in the Scaleway Console.
+# The user is responsible for creating the token, ensuring it has the
+# DomainsDNSFullAccess permission set. The records to be updated
+# may already exist, but will be created if not.
+#
+# Arguments:
+#
+# - $username: The zone in which the RR is to be set.
+#   Example: example.org
+#
+# - $password: The API token.
+#
+# - $domain: The domain to update.
+#
+# - $param_opt: Optional TTL for the records, in seconds. Defaults to 300 (5m).
+#
+# Dependencies:
+# - ddns-scripts  (for the base functionality)
+# - curl          (for the Scaleway DNS API)
+
+. /usr/share/libubox/jshn.sh
+
+format_record_set() {
+       local domain="$1"
+       local record_type="$2"
+       local ttl="$3"
+       shift 3 # The remaining arguments are the IP addresses for this record set.
+
+       json_init
+       json_add_array "changes"
+       json_add_object ""
+       json_add_object "set"
+
+       json_add_object "id_fields"
+       json_add_string "name" "${domain}"
+       json_add_string "type" "${record_type}"
+       json_close_object
+
+       json_add_array "records"
+       for value in "$@"; do
+               json_add_object ""
+               json_add_string "data" "${value}"
+               json_add_string "name" "${domain}"
+               json_add_string "type" "${record_type}"
+               json_add_int "ttl" "${ttl}"
+               json_close_object
+       done
+       json_close_array
+
+       json_close_object
+       json_close_object
+       json_close_array
+       json_dump
+}
+
+patch_record_set() {
+       local access_token="$1"
+       local zone="$2"
+       local domain="$3"
+       local record_type="$4"
+       local ttl="$5"
+       shift 5 # The remaining arguments are the IP addresses for this record set.
+
+       local url="https://api.scaleway.com/domain/v2beta1/dns-zones/${zone}/records"
+       local payload
+       payload=$(format_record_set ${domain} ${record_type} ${ttl} "$@")
+       write_log 7 "cURL request payload: ${payload}"
+
+       ${CURL} ${url} \
+               --show-error --silent --fail-with-body \
+               --request   PATCH \
+               --header    "X-Auth-Token: ${access_token}" \
+               --json      "${payload}" \
+               --write-out "%{response_code}" \
+               --output $DATFILE 2> $ERRFILE
+
+       if [ $? -ne 0 ]; then
+               write_log 3 "cURL failed: $(cat $ERRFILE) \nscaleway.com response: $(cat $DATFILE)"
+               return 1
+       fi
+}
+
+main() {
+       local ttl record_type
+
+       # Dependency checking
+       [ -z "${CURL_SSL}" ] && write_log 13 "Scaleway DNS requires cURL with SSL support"
+
+       # Argument parsing
+       [ -z ${param_opt} ] && ttl=300 || ttl="${param_opt}"
+       [ ${use_ipv6} -ne 0 ] && record_type="AAAA" || record_type="A"
+
+       # Sanity checks
+       [ -z "${password}" ] && write_log 13 "Config is missing 'password' (API token)"
+       [ -z "${domain}" ] && write_log 13 "Config is missing 'domain'"
+       [ -z "${username}" ] && write_log 13 "Config is missing 'username' (DNS zone)"
+       [ -z "${ttl}" ] && write_log 13 "Could not parse TTL"
+       [ -z "${record_type}" ] && write_log 13 "Could not determine the record type"
+
+       patch_record_set "${password}" "${username}" "${domain}" "${record_type}" "${ttl}" "${__IP}"
+}
+
+main "$@"
diff --git a/net/ddns-scripts/files/usr/share/ddns/default/scaleway.com.json b/net/ddns-scripts/files/usr/share/ddns/default/scaleway.com.json
new file mode 100644 (file)
index 0000000..683d403
--- /dev/null
@@ -0,0 +1,9 @@
+{
+       "name": "Scaleway DNS",
+       "ipv4": {
+               "url": "update_scaleway_com.sh"
+       },
+       "ipv6": {
+               "url": "update_scaleway_com.sh"
+       }
+}