+ raise DDNSRequestError(_("Invalid IP address has been sent"))
+
+ # If we got here, some other update error happened.
+ raise DDNSUpdateError
+
+
+class DDNSProviderGodaddy(DDNSProvider):
+ handle = "godaddy.com"
+ name = "godaddy.com"
+ website = "https://godaddy.com/"
+ protocols = ("ipv4",)
+
+ # Information about the format of the HTTP request is to be found
+ # here: https://developer.godaddy.com/doc/endpoint/domains#/v1/recordReplaceTypeName
+ url = "https://api.godaddy.com/v1/domains/"
+ can_remove_records = False
+
+ def update_protocol(self, proto):
+ # retrieve ip
+ ip_address = self.get_address(proto)
+
+ # set target url
+ url = f"{self.url}/{self.hostname}/records/A/@"
+
+ # prepare data
+ data = json.dumps([{"data": ip_address, "ttl": 600, "name": self.hostname, "type": "A"}]).encode("utf-8")
+
+ # Method requires authentication by special headers.
+ request = urllib.request.Request(url=url,
+ data=data,
+ headers={"Authorization": f"sso-key {self.username}:{self.password}",
+ "Content-Type": "application/json"},
+ method="PUT")
+ result = urllib.request.urlopen(request)
+
+ # handle success
+ if result.code == 200:
+ return
+
+ # handle errors
+ if result.code == 400:
+ raise DDNSRequestError(_("Malformed request received."))
+ if result.code in (401, 403):
+ raise DDNSAuthenticationError
+ if result.code == 404:
+ raise DDNSRequestError(_("Resource not found."))
+ if result.code == 422:
+ raise DDNSRequestError(_("Record does not fulfill the schema."))
+ if result.code == 429:
+ raise DDNSRequestError(_("API Rate limiting."))
+
+ # If we got here, some other update error happened.
+ raise DDNSUpdateError
+
+
+class DDNSProviderHENet(DDNSProtocolDynDNS2, DDNSProvider):
+ handle = "he.net"
+ name = "he.net"
+ website = "https://he.net"
+ protocols = ("ipv6", "ipv4",)
+
+ # Detailed information about the update api can be found here.
+ # http://dns.he.net/docs.html
+
+ url = "https://dyn.dns.he.net/nic/update"
+ @property
+ def username(self):
+ return self.get("hostname")
+
+
+
+class DDNSProviderItsdns(DDNSProtocolDynDNS2, DDNSProvider):
+ handle = "inwx.com"
+ name = "INWX"
+ website = "https://www.inwx.com"
+ protocols = ("ipv6", "ipv4")
+
+ # Information about the format of the HTTP request is to be found
+ # here: https://www.inwx.com/en/nameserver2/dyndns (requires login)
+ # Notice: The URL is the same for: inwx.com|de|at|ch|es
+
+ url = "https://dyndns.inwx.com/nic/update"
+
+
+class DDNSProviderItsdns(DDNSProtocolDynDNS2, DDNSProvider):
+ handle = "itsdns.de"
+ name = "it's DNS"
+ website = "http://www.itsdns.de/"
+ protocols = ("ipv6", "ipv4")
+
+ # Information about the format of the HTTP request is to be found
+ # here: https://www.itsdns.de/dynupdatehelp.htm
+
+ url = "https://www.itsdns.de/update.php"
+
+
+class DDNSProviderJoker(DDNSProtocolDynDNS2, DDNSProvider):
+ handle = "joker.com"
+ name = "Joker.com Dynamic DNS"
+ website = "https://joker.com/"
+ protocols = ("ipv4",)
+
+ # Information about the request can be found here:
+ # https://joker.com/faq/content/11/427/en/what-is-dynamic-dns-dyndns.html
+ # Using DynDNS V2 protocol over HTTPS here
+
+ url = "https://svc.joker.com/nic/update"
+
+
+class DDNSProviderKEYSYSTEMS(DDNSProvider):
+ handle = "key-systems.net"
+ name = "dynamicdns.key-systems.net"
+ website = "https://domaindiscount24.com/"
+ protocols = ("ipv4",)
+
+ # There are only information provided by the domaindiscount24 how to
+ # perform an update with HTTP APIs
+ # https://www.domaindiscount24.com/faq/dynamic-dns
+ # examples: https://dynamicdns.key-systems.net/update.php?hostname=hostname&password=password&ip=auto
+ # https://dynamicdns.key-systems.net/update.php?hostname=hostname&password=password&ip=213.x.x.x&mx=213.x.x.x
+
+ url = "https://dynamicdns.key-systems.net/update.php"
+ can_remove_records = False
+ supports_token_auth = False
+
+ def update_protocol(self, proto):
+ address = self.get_address(proto)
+ data = {
+ "hostname" : self.hostname,
+ "password" : self.password,
+ "ip" : address,
+ }
+
+ # Send update to the server.
+ response = self.send_request(self.url, data=data)
+
+ # Get the full response message.
+ output = response.read().decode()
+
+ # Handle success messages.
+ if "code = 200" in output:
+ return
+
+ # Handle error messages.
+ if "abuse prevention triggered" in output:
+ raise DDNSAbuseError
+ elif "invalid password" in output:
+ raise DDNSAuthenticationError
+ elif "Authorization failed" in output:
+ raise DDNSRequestError(_("Invalid hostname specified"))