On systems that had connectivity to e.g. IPv6 which they don't
have any more need to remove the IPv6 address from the DNS system.
Most providers do not support this and hence this case is completely
ignored and the invalid record is left in the DNS system.
# the IP address has changed.
holdoff_days = 30
# the IP address has changed.
holdoff_days = 30
+ # True if the provider is able to remove records, too.
+ # Required to remove AAAA records if IPv6 is absent again.
+ can_remove_records = True
+
# Automatically register all providers.
class __metaclass__(type):
def __init__(provider, name, bases, dict):
# Automatically register all providers.
class __metaclass__(type):
def __init__(provider, name, bases, dict):
for protocol in self.protocols:
if self.have_address(protocol):
self.update_protocol(protocol)
for protocol in self.protocols:
if self.have_address(protocol):
self.update_protocol(protocol)
+ elif self.can_remove_records:
self.remove_protocol(protocol)
def update_protocol(self, proto):
raise NotImplementedError
def remove_protocol(self, proto):
self.remove_protocol(protocol)
def update_protocol(self, proto):
raise NotImplementedError
def remove_protocol(self, proto):
- logger.warning(_("%(hostname)s current resolves to an IP address"
- " of the %(proto)s protocol which could not be removed by ddns") % \
- { "hostname" : self.hostname, "proto" : proto })
+ if not self.can_remove_records:
+ raise RuntimeError, "can_remove_records is enabled, but remove_protocol() not implemented"
- # Maybe this will raise NotImplementedError at some time
- #raise NotImplementedError
+ raise NotImplementedError
@property
def requires_update(self):
@property
def requires_update(self):
"""
for proto in protos:
addresses = self.core.system.resolve(self.hostname, proto)
"""
for proto in protos:
addresses = self.core.system.resolve(self.hostname, proto)
current_address = self.get_address(proto)
current_address = self.get_address(proto)
- # If no addresses for the given protocol exist, we
- # are fine...
- if current_address is None and not addresses:
+ # Handle if the system has not got any IP address from a protocol
+ # (i.e. had full dual-stack connectivity which it has not any more)
+ if current_address is None:
+ # If addresses still exists in the DNS system and if this provider
+ # is able to remove records, we will do that.
+ if addresses and self.can_remove_records:
+ return True
+
+ # Otherwise, we cannot go on...
continue
if not current_address in addresses:
continue
if not current_address in addresses:
# http://dyn.com/support/developers/api/perform-update/
# http://dyn.com/support/developers/api/return-codes/
# http://dyn.com/support/developers/api/perform-update/
# http://dyn.com/support/developers/api/return-codes/
+ # The DynDNS protocol version 2 does not allow to remove records
+ can_remove_records = False
+
def prepare_request_data(self, proto):
data = {
"hostname" : self.hostname,
def prepare_request_data(self, proto):
data = {
"hostname" : self.hostname,
# http://all-inkl.goetze.it/v01/ddns-mit-einfachen-mitteln/
url = "http://dyndns.kasserver.com"
# http://all-inkl.goetze.it/v01/ddns-mit-einfachen-mitteln/
url = "http://dyndns.kasserver.com"
+ can_remove_records = False
def update(self):
# There is no additional data required so we directly can
def update(self):
# There is no additional data required so we directly can
# grabed from source code of ez-ipudate.
url = "http://members.dhs.org/nic/hosts"
# grabed from source code of ez-ipudate.
url = "http://members.dhs.org/nic/hosts"
+ can_remove_records = False
def update_protocol(self, proto):
data = {
def update_protocol(self, proto):
data = {
# https://dnspark.zendesk.com/entries/31229348-Dynamic-DNS-API-Documentation
url = "https://control.dnspark.com/api/dynamic/update.php"
# https://dnspark.zendesk.com/entries/31229348-Dynamic-DNS-API-Documentation
url = "https://control.dnspark.com/api/dynamic/update.php"
+ can_remove_records = False
def update_protocol(self, proto):
data = {
def update_protocol(self, proto):
data = {
# http://www.dtdns.com/dtsite/updatespec
url = "https://www.dtdns.com/api/autodns.cfm"
# http://www.dtdns.com/dtsite/updatespec
url = "https://www.dtdns.com/api/autodns.cfm"
+ can_remove_records = False
def update_protocol(self, proto):
data = {
def update_protocol(self, proto):
data = {
name = "DyNS"
website = "http://www.dyns.net/"
protocols = ("ipv4",)
name = "DyNS"
website = "http://www.dyns.net/"
protocols = ("ipv4",)
+ can_remove_records = False
# There is very detailed informatio about how to send the update request and
# the possible response codes. (Currently we are using the v1.1 proto)
# There is very detailed informatio about how to send the update request and
# the possible response codes. (Currently we are using the v1.1 proto)
# http://www.enom.com/APICommandCatalog/
url = "https://dynamic.name-services.com/interface.asp"
# http://www.enom.com/APICommandCatalog/
url = "https://dynamic.name-services.com/interface.asp"
+ can_remove_records = False
def update_protocol(self, proto):
data = {
def update_protocol(self, proto):
data = {
# Some very tiny details about their so called "Simple API" can be found
# here: https://entrydns.net/help
url = "https://entrydns.net/records/modify"
# Some very tiny details about their so called "Simple API" can be found
# here: https://entrydns.net/help
url = "https://entrydns.net/records/modify"
+ can_remove_records = False
def update_protocol(self, proto):
data = {
def update_protocol(self, proto):
data = {
# No information about the request or response could be found on the vendor
# page. All used values have been collected by testing.
url = "https://freedns.afraid.org/dynamic/update.php"
# No information about the request or response could be found on the vendor
# page. All used values have been collected by testing.
url = "https://freedns.afraid.org/dynamic/update.php"
+ can_remove_records = False
def update_protocol(self, proto):
data = {
def update_protocol(self, proto):
data = {
# https://community.namecheap.com/forums/viewtopic.php?f=6&t=6772
url = "https://dynamicdns.park-your-domain.com/update"
# https://community.namecheap.com/forums/viewtopic.php?f=6&t=6772
url = "https://dynamicdns.park-your-domain.com/update"
+ can_remove_records = False
def update_protocol(self, proto):
# Namecheap requires the hostname splitted into a host and domain part.
def update_protocol(self, proto):
# Namecheap requires the hostname splitted into a host and domain part.
# after login on the provider user interface and here:
# http://nsupdateinfo.readthedocs.org/en/latest/user.html
# after login on the provider user interface and here:
# http://nsupdateinfo.readthedocs.org/en/latest/user.html
+ # TODO nsupdate.info can actually do this, but the functionality
+ # has not been implemented here, yet.
+ can_remove_records = False
+
# Nsupdate.info uses the hostname as user part for the HTTP basic auth,
# and for the password a so called secret.
@property
# Nsupdate.info uses the hostname as user part for the HTTP basic auth,
# and for the password a so called secret.
@property
# https://www.regfish.de/domains/dyndns/dokumentation
url = "https://dyndns.regfish.de/"
# https://www.regfish.de/domains/dyndns/dokumentation
url = "https://dyndns.regfish.de/"
+ can_remove_records = False
def update(self):
data = {
def update(self):
data = {
# https://bugzilla.ipfire.org/show_bug.cgi?id=10584#c2
url = "https://zzzz.io/api/v1/update"
# https://bugzilla.ipfire.org/show_bug.cgi?id=10584#c2
url = "https://zzzz.io/api/v1/update"
+ can_remove_records = False
def update_protocol(self, proto):
data = {
def update_protocol(self, proto):
data = {