[001/001] ddns: Add 1984.hosting Free DNS (DDNS) provider
Commit Message
From: Franco Masotti <franco.masotti@tutanota.com>
This patch adds support for 1984.hosting Free DNS to the ddns service.
This provider uses token authorization and a GET request with inline
parameters.
Signed-off-by: Franco Masotti <franco.masotti@tutanota.com>
---
ddns.conf.sample | 4 +++
src/ddns/providers.py | 68 +++++++++++++++++++++++++++++++++++++++++++
2 files changed, 72 insertions(+)
Comments
Hello Franco,
thank you very much for your patch. I have merged it, and 1984.hosting
is now supported by ddns:
https://git.ipfire.org/?p=ddns.git;a=commit;h=6f89e41662b261bf76bb2760649ac4d62cf0cd44
Since then, the providers have been moved into a module each, so you will
now find it in src/ddns/providers/1984_hosting.py, and it has tests, too.
It would be great if you could give the current master branch a try with
your account, and let us know if anything does not work as expected.
Best,
-Michael
@@ -14,6 +14,10 @@
# Accounts are its own sections.
# These are some examples.
+#
+# [test.1984.hosting]
+# provider = 1984.hosting
+# token = token
# [test.all-inkl.com]
# provider = all-inkl.com
@@ -2017,3 +2017,71 @@ class DDNSProviderInfomaniak(DDNSProtocolDynDNS2, DDNSProvider):
# https://www.infomaniak.com/de/support/faq/2376/dyndns-aktualisieren-eines-dynamischen-dns-uber-die-api
url = "https://infomaniak.com/nic/update"
+
+
+class DDNSProvider1984Hosting(DDNSProvider):
+ handle = "1984.hosting"
+ name = "1984 Hosting Free DNS"
+ website = "http://1984.hosting"
+ protocols = ("ipv6", "ipv4",)
+
+ # Information about the format of the request is to be found after logging
+ # in. The account and usage it totally free of cost
+ # https://1984.hosting/domains/freednsapi/
+ #
+ # General information on FreeDNS
+ # https://1984.hosting/knowledge-base/freedns/
+ #
+ # examples: https://api.1984.is/1.0/freedns/?apikey=apikey&domain=domain&ip=
+ # https://api.1984.is/1.0/freedns/?apikey=apikey&domain=domain&ip=213.x.x.x
+ url = "https://api.1984.is/1.0/freedns/"
+ can_remove_records = False
+ supports_token_auth = True
+
+ def update_protocol(self, proto):
+ # Raise an error if no auth details are given.
+ if not self.token:
+ raise DDNSConfigurationError
+
+ address = self.get_address(proto)
+ data = {
+ "domain" : self.hostname,
+ "apikey" : self.token,
+ "ip" : address,
+ }
+
+ # Send update to the server.
+ response = self.send_request(self.url, data=data)
+
+ # Get the full response message.
+ output = response.read().decode()
+
+ try:
+ # JSON Response official documentation:
+ #
+ # {
+ # "ok": true or false depending on if the request was successful or not, if the ip is the same as before this will be true,
+ # "msg": successes or why it is not working,
+ # "lookup": if domain or subdomain was not found lookup will contain a list of names tried
+ # }
+ res = json.loads(output)
+ except json.JSONDecodeError:
+ raise DDNSUpdateError(_("Unable to decode server response, assuming request failed"))
+
+ if res.get("ok", False):
+ return
+ else:
+ # API reurns an undocumented 'error' JSON key-value if key is wrong.
+ error = res.get("error", "")
+ if error:
+ raise DDNSAuthenticationError
+ else:
+ message = res.get("msg", "")
+ if "record does not exist" in message:
+ raise DDNSRequestError(_("Invalid hostname specified"))
+ else:
+ raise DDNSUpdateError(_("Server response: %s") % message)
+
+ # If we got here, some other update error happened.
+ raise DDNSUpdateError
+