]> git.ipfire.org Git - ddns.git/blame - src/ddns/providers.py
Add empty lines between api documentation and the update url.
[ddns.git] / src / ddns / providers.py
CommitLineData
f22ab085 1#!/usr/bin/python
3fdcb9d1
MT
2###############################################################################
3# #
4# ddns - A dynamic DNS client for IPFire #
5# Copyright (C) 2012 IPFire development team #
6# #
7# This program is free software: you can redistribute it and/or modify #
8# it under the terms of the GNU General Public License as published by #
9# the Free Software Foundation, either version 3 of the License, or #
10# (at your option) any later version. #
11# #
12# This program is distributed in the hope that it will be useful, #
13# but WITHOUT ANY WARRANTY; without even the implied warranty of #
14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
15# GNU General Public License for more details. #
16# #
17# You should have received a copy of the GNU General Public License #
18# along with this program. If not, see <http://www.gnu.org/licenses/>. #
19# #
20###############################################################################
f22ab085 21
7399fc5b 22import logging
3b16fdb1 23import urllib2
d1cd57eb 24import xml.dom.minidom
7399fc5b
MT
25
26from i18n import _
27
f22ab085
MT
28# Import all possible exception types.
29from .errors import *
30
7399fc5b
MT
31logger = logging.getLogger("ddns.providers")
32logger.propagate = 1
33
f22ab085 34class DDNSProvider(object):
6a11646e
MT
35 # A short string that uniquely identifies
36 # this provider.
37 handle = None
f22ab085 38
6a11646e
MT
39 # The full name of the provider.
40 name = None
f22ab085 41
6a11646e
MT
42 # A weburl to the homepage of the provider.
43 # (Where to register a new account?)
44 website = None
f22ab085 45
6a11646e
MT
46 # A list of supported protocols.
47 protocols = ("ipv6", "ipv4")
f22ab085
MT
48
49 DEFAULT_SETTINGS = {}
50
51 def __init__(self, core, **settings):
52 self.core = core
53
54 # Copy a set of default settings and
55 # update them by those from the configuration file.
56 self.settings = self.DEFAULT_SETTINGS.copy()
57 self.settings.update(settings)
58
59 def __repr__(self):
60 return "<DDNS Provider %s (%s)>" % (self.name, self.handle)
61
62 def __cmp__(self, other):
63 return cmp(self.hostname, other.hostname)
64
f22ab085
MT
65 def get(self, key, default=None):
66 """
67 Get a setting from the settings dictionary.
68 """
69 return self.settings.get(key, default)
70
71 @property
72 def hostname(self):
73 """
74 Fast access to the hostname.
75 """
76 return self.get("hostname")
77
78 @property
79 def username(self):
80 """
81 Fast access to the username.
82 """
83 return self.get("username")
84
85 @property
86 def password(self):
87 """
88 Fast access to the password.
89 """
90 return self.get("password")
91
46687828
SS
92 @property
93 def token(self):
94 """
95 Fast access to the token.
96 """
97 return self.get("token")
98
9da3e685
MT
99 def __call__(self, force=False):
100 if force:
c3888f15 101 logger.debug(_("Updating %s forced") % self.hostname)
9da3e685 102
7399fc5b 103 # Check if we actually need to update this host.
9da3e685 104 elif self.is_uptodate(self.protocols):
c3888f15 105 logger.debug(_("%s is already up to date") % self.hostname)
7399fc5b
MT
106 return
107
108 # Execute the update.
5f402f36
MT
109 self.update()
110
111 def update(self):
f22ab085
MT
112 raise NotImplementedError
113
7399fc5b
MT
114 def is_uptodate(self, protos):
115 """
116 Returns True if this host is already up to date
117 and does not need to change the IP address on the
118 name server.
119 """
120 for proto in protos:
121 addresses = self.core.system.resolve(self.hostname, proto)
122
123 current_address = self.get_address(proto)
124
38d81db4
MT
125 # If no addresses for the given protocol exist, we
126 # are fine...
127 if current_address is None and not addresses:
128 continue
129
7399fc5b
MT
130 if not current_address in addresses:
131 return False
132
133 return True
134
f22ab085
MT
135 def send_request(self, *args, **kwargs):
136 """
137 Proxy connection to the send request
138 method.
139 """
140 return self.core.system.send_request(*args, **kwargs)
141
e3c70807 142 def get_address(self, proto, default=None):
f22ab085
MT
143 """
144 Proxy method to get the current IP address.
145 """
e3c70807 146 return self.core.system.get_address(proto) or default
f22ab085
MT
147
148
3b16fdb1 149class DDNSProviderAllInkl(DDNSProvider):
6a11646e
MT
150 handle = "all-inkl.com"
151 name = "All-inkl.com"
152 website = "http://all-inkl.com/"
153 protocols = ("ipv4",)
3b16fdb1
SS
154
155 # There are only information provided by the vendor how to
156 # perform an update on a FRITZ Box. Grab requried informations
157 # from the net.
158 # http://all-inkl.goetze.it/v01/ddns-mit-einfachen-mitteln/
159
160 url = "http://dyndns.kasserver.com"
161
162 def update(self):
3b16fdb1
SS
163 # There is no additional data required so we directly can
164 # send our request.
536e87d1 165 response = self.send_request(self.url, username=self.username, password=self.password)
3b16fdb1
SS
166
167 # Get the full response message.
168 output = response.read()
169
170 # Handle success messages.
171 if output.startswith("good") or output.startswith("nochg"):
172 return
173
174 # If we got here, some other update error happened.
175 raise DDNSUpdateError
176
177
f3cf1f70 178class DDNSProviderDHS(DDNSProvider):
6a11646e
MT
179 handle = "dhs.org"
180 name = "DHS International"
181 website = "http://dhs.org/"
182 protocols = ("ipv4",)
f3cf1f70
SS
183
184 # No information about the used update api provided on webpage,
185 # grabed from source code of ez-ipudate.
b2b05ef3 186
f3cf1f70
SS
187 url = "http://members.dhs.org/nic/hosts"
188
5f402f36 189 def update(self):
f3cf1f70
SS
190 data = {
191 "domain" : self.hostname,
192 "ip" : self.get_address("ipv4"),
193 "hostcmd" : "edit",
194 "hostcmdstage" : "2",
195 "type" : "4",
196 }
197
198 # Send update to the server.
175c9b80 199 response = self.send_request(self.url, username=self.username, password=self.password,
f3cf1f70
SS
200 data=data)
201
202 # Handle success messages.
203 if response.code == 200:
204 return
205
f3cf1f70
SS
206 # If we got here, some other update error happened.
207 raise DDNSUpdateError
208
209
39301272 210class DDNSProviderDNSpark(DDNSProvider):
6a11646e
MT
211 handle = "dnspark.com"
212 name = "DNS Park"
213 website = "http://dnspark.com/"
214 protocols = ("ipv4",)
39301272
SS
215
216 # Informations to the used api can be found here:
217 # https://dnspark.zendesk.com/entries/31229348-Dynamic-DNS-API-Documentation
b2b05ef3 218
39301272
SS
219 url = "https://control.dnspark.com/api/dynamic/update.php"
220
5f402f36 221 def update(self):
39301272
SS
222 data = {
223 "domain" : self.hostname,
224 "ip" : self.get_address("ipv4"),
225 }
226
227 # Send update to the server.
175c9b80 228 response = self.send_request(self.url, username=self.username, password=self.password,
39301272
SS
229 data=data)
230
231 # Get the full response message.
232 output = response.read()
233
234 # Handle success messages.
235 if output.startswith("ok") or output.startswith("nochange"):
236 return
237
238 # Handle error codes.
239 if output == "unauth":
240 raise DDNSAuthenticationError
241 elif output == "abuse":
242 raise DDNSAbuseError
243 elif output == "blocked":
244 raise DDNSBlockedError
245 elif output == "nofqdn":
246 raise DDNSRequestError(_("No valid FQDN was given."))
247 elif output == "nohost":
248 raise DDNSRequestError(_("Invalid hostname specified."))
249 elif output == "notdyn":
250 raise DDNSRequestError(_("Hostname not marked as a dynamic host."))
251 elif output == "invalid":
252 raise DDNSRequestError(_("Invalid IP address has been sent."))
253
254 # If we got here, some other update error happened.
255 raise DDNSUpdateError
256
43b2cd59
SS
257
258class DDNSProviderDtDNS(DDNSProvider):
6a11646e
MT
259 handle = "dtdns.com"
260 name = "DtDNS"
261 website = "http://dtdns.com/"
262 protocols = ("ipv4",)
43b2cd59
SS
263
264 # Information about the format of the HTTPS request is to be found
265 # http://www.dtdns.com/dtsite/updatespec
b2b05ef3 266
43b2cd59
SS
267 url = "https://www.dtdns.com/api/autodns.cfm"
268
43b2cd59
SS
269 def update(self):
270 data = {
271 "ip" : self.get_address("ipv4"),
272 "id" : self.hostname,
273 "pw" : self.password
274 }
275
276 # Send update to the server.
277 response = self.send_request(self.url, data=data)
278
279 # Get the full response message.
280 output = response.read()
281
282 # Remove all leading and trailing whitespace.
283 output = output.strip()
284
285 # Handle success messages.
286 if "now points to" in output:
287 return
288
289 # Handle error codes.
290 if output == "No hostname to update was supplied.":
291 raise DDNSRequestError(_("No hostname specified."))
292
293 elif output == "The hostname you supplied is not valid.":
294 raise DDNSRequestError(_("Invalid hostname specified."))
295
296 elif output == "The password you supplied is not valid.":
297 raise DDNSAuthenticationError
298
299 elif output == "Administration has disabled this account.":
300 raise DDNSRequestError(_("Account has been disabled."))
301
302 elif output == "Illegal character in IP.":
303 raise DDNSRequestError(_("Invalid IP address has been sent."))
304
305 elif output == "Too many failed requests.":
306 raise DDNSRequestError(_("Too many failed requests."))
307
308 # If we got here, some other update error happened.
309 raise DDNSUpdateError
310
311
bfed6701 312class DDNSProviderDynDNS(DDNSProvider):
6a11646e
MT
313 handle = "dyndns.org"
314 name = "Dyn"
315 website = "http://dyn.com/dns/"
316 protocols = ("ipv4",)
bfed6701
SS
317
318 # Information about the format of the request is to be found
319 # http://http://dyn.com/support/developers/api/perform-update/
320 # http://dyn.com/support/developers/api/return-codes/
b2b05ef3 321
bfed6701
SS
322 url = "https://members.dyndns.org/nic/update"
323
88f39629 324 def _prepare_request_data(self):
bfed6701
SS
325 data = {
326 "hostname" : self.hostname,
327 "myip" : self.get_address("ipv4"),
328 }
329
88f39629
SS
330 return data
331
332 def update(self):
333 data = self._prepare_request_data()
334
bfed6701 335 # Send update to the server.
88f39629
SS
336 response = self.send_request(self.url, data=data,
337 username=self.username, password=self.password)
bfed6701
SS
338
339 # Get the full response message.
340 output = response.read()
341
342 # Handle success messages.
343 if output.startswith("good") or output.startswith("nochg"):
344 return
345
346 # Handle error codes.
347 if output == "badauth":
348 raise DDNSAuthenticationError
349 elif output == "aduse":
350 raise DDNSAbuseError
351 elif output == "notfqdn":
352 raise DDNSRequestError(_("No valid FQDN was given."))
353 elif output == "nohost":
354 raise DDNSRequestError(_("Specified host does not exist."))
355 elif output == "911":
356 raise DDNSInternalServerError
357 elif output == "dnserr":
358 raise DDNSInternalServerError(_("DNS error encountered."))
359
360 # If we got here, some other update error happened.
0271a97f 361 raise DDNSUpdateError(_("Server response: %s") % output)
bfed6701
SS
362
363
3a8407fa 364class DDNSProviderDynU(DDNSProviderDynDNS):
6a11646e
MT
365 handle = "dynu.com"
366 name = "Dynu"
367 website = "http://dynu.com/"
368 protocols = ("ipv6", "ipv4",)
3a8407fa
SS
369
370 # Detailed information about the request and response codes
371 # are available on the providers webpage.
372 # http://dynu.com/Default.aspx?page=dnsapi
373
374 url = "https://api.dynu.com/nic/update"
375
376 def _prepare_request_data(self):
54d3efc8
MT
377 data = DDNSProviderDynDNS._prepare_request_data(self)
378
379 # This one supports IPv6
380 data.update({
3a8407fa 381 "myipv6" : self.get_address("ipv6"),
54d3efc8
MT
382 })
383
384 return data
3a8407fa
SS
385
386
ee071271 387class DDNSProviderEasyDNS(DDNSProviderDynDNS):
6a11646e
MT
388 handle = "easydns.com"
389 name = "EasyDNS"
390 website = "http://www.easydns.com/"
ee071271
SS
391
392 # There is only some basic documentation provided by the vendor,
393 # also searching the web gain very poor results.
394 # http://mediawiki.easydns.com/index.php/Dynamic_DNS
395
396 url = "http://api.cp.easydns.com/dyn/tomato.php"
397
398
aa21a4c6 399class DDNSProviderFreeDNSAfraidOrg(DDNSProvider):
6a11646e
MT
400 handle = "freedns.afraid.org"
401 name = "freedns.afraid.org"
402 website = "http://freedns.afraid.org/"
aa21a4c6
SS
403
404 # No information about the request or response could be found on the vendor
405 # page. All used values have been collected by testing.
406 url = "https://freedns.afraid.org/dynamic/update.php"
407
408 @property
409 def proto(self):
410 return self.get("proto")
411
412 def update(self):
413 address = self.get_address(self.proto)
414
415 data = {
416 "address" : address,
417 }
418
419 # Add auth token to the update url.
420 url = "%s?%s" % (self.url, self.token)
421
422 # Send update to the server.
423 response = self.send_request(url, data=data)
424
aa21a4c6
SS
425 if output.startswith("Updated") or "has not changed" in output:
426 return
427
428 # Handle error codes.
429 if output == "ERROR: Unable to locate this record":
430 raise DDNSAuthenticationError
431 elif "is an invalid IP address" in output:
432 raise DDNSRequestError(_("Invalid IP address has been sent."))
433
3b524cf2
SS
434 # If we got here, some other update error happened.
435 raise DDNSUpdateError
436
aa21a4c6 437
a08c1b72 438class DDNSProviderLightningWireLabs(DDNSProvider):
6a11646e 439 handle = "dns.lightningwirelabs.com"
fb115fdc 440 name = "Lightning Wire Labs DNS Service"
6a11646e 441 website = "http://dns.lightningwirelabs.com/"
a08c1b72
SS
442
443 # Information about the format of the HTTPS request is to be found
444 # https://dns.lightningwirelabs.com/knowledge-base/api/ddns
b2b05ef3 445
a08c1b72
SS
446 url = "https://dns.lightningwirelabs.com/update"
447
5f402f36 448 def update(self):
a08c1b72
SS
449 data = {
450 "hostname" : self.hostname,
e3c70807
MT
451 "address6" : self.get_address("ipv6", "-"),
452 "address4" : self.get_address("ipv4", "-"),
a08c1b72
SS
453 }
454
a08c1b72
SS
455 # Check if a token has been set.
456 if self.token:
457 data["token"] = self.token
458
459 # Check for username and password.
460 elif self.username and self.password:
461 data.update({
462 "username" : self.username,
463 "password" : self.password,
464 })
465
466 # Raise an error if no auth details are given.
467 else:
468 raise DDNSConfigurationError
469
470 # Send update to the server.
cb455540 471 response = self.send_request(self.url, data=data)
a08c1b72
SS
472
473 # Handle success messages.
474 if response.code == 200:
475 return
476
a08c1b72
SS
477 # If we got here, some other update error happened.
478 raise DDNSUpdateError
479
480
d1cd57eb 481class DDNSProviderNamecheap(DDNSProvider):
6a11646e
MT
482 handle = "namecheap.com"
483 name = "Namecheap"
484 website = "http://namecheap.com"
485 protocols = ("ipv4",)
d1cd57eb
SS
486
487 # Information about the format of the HTTP request is to be found
488 # https://www.namecheap.com/support/knowledgebase/article.aspx/9249/0/nc-dynamic-dns-to-dyndns-adapter
489 # https://community.namecheap.com/forums/viewtopic.php?f=6&t=6772
490
491 url = "https://dynamicdns.park-your-domain.com/update"
492
493 def parse_xml(self, document, content):
494 # Send input to the parser.
495 xmldoc = xml.dom.minidom.parseString(document)
496
497 # Get XML elements by the given content.
498 element = xmldoc.getElementsByTagName(content)
499
500 # If no element has been found, we directly can return None.
501 if not element:
502 return None
503
504 # Only get the first child from an element, even there are more than one.
505 firstchild = element[0].firstChild
506
507 # Get the value of the child.
508 value = firstchild.nodeValue
509
510 # Return the value.
511 return value
512
513 def update(self):
514 # Namecheap requires the hostname splitted into a host and domain part.
515 host, domain = self.hostname.split(".", 1)
516
517 data = {
518 "ip" : self.get_address("ipv4"),
519 "password" : self.password,
520 "host" : host,
521 "domain" : domain
522 }
523
524 # Send update to the server.
525 response = self.send_request(self.url, data=data)
526
527 # Get the full response message.
528 output = response.read()
529
530 # Handle success messages.
531 if self.parse_xml(output, "IP") == self.get_address("ipv4"):
532 return
533
534 # Handle error codes.
535 errorcode = self.parse_xml(output, "ResponseNumber")
536
537 if errorcode == "304156":
538 raise DDNSAuthenticationError
539 elif errorcode == "316153":
540 raise DDNSRequestError(_("Domain not found."))
541 elif errorcode == "316154":
542 raise DDNSRequestError(_("Domain not active."))
543 elif errorcode in ("380098", "380099"):
544 raise DDNSInternalServerError
545
546 # If we got here, some other update error happened.
547 raise DDNSUpdateError
548
549
88f39629 550class DDNSProviderNOIP(DDNSProviderDynDNS):
6a11646e
MT
551 handle = "no-ip.com"
552 name = "No-IP"
553 website = "http://www.no-ip.com/"
f22ab085
MT
554
555 # Information about the format of the HTTP request is to be found
556 # here: http://www.no-ip.com/integrate/request and
557 # here: http://www.no-ip.com/integrate/response
558
88f39629 559 url = "http://dynupdate.no-ip.com/nic/update"
2de06f59 560
88f39629 561 def _prepare_request_data(self):
2de06f59
MT
562 data = {
563 "hostname" : self.hostname,
f22ab085
MT
564 "address" : self.get_address("ipv4"),
565 }
566
88f39629 567 return data
f22ab085
MT
568
569
a508bda6 570class DDNSProviderOVH(DDNSProviderDynDNS):
6a11646e
MT
571 handle = "ovh.com"
572 name = "OVH"
573 website = "http://www.ovh.com/"
a508bda6
SS
574
575 # OVH only provides very limited information about how to
576 # update a DynDNS host. They only provide the update url
577 # on the their german subpage.
578 #
579 # http://hilfe.ovh.de/DomainDynHost
580
581 url = "https://www.ovh.com/nic/update"
582
583 def _prepare_request_data(self):
54d3efc8
MT
584 data = DDNSProviderDynDNS._prepare_request_data(self)
585 data.update({
586 "system" : "dyndns",
587 })
588
589 return data
a508bda6
SS
590
591
ef33455e 592class DDNSProviderRegfish(DDNSProvider):
6a11646e
MT
593 handle = "regfish.com"
594 name = "Regfish GmbH"
595 website = "http://www.regfish.com/"
ef33455e
SS
596
597 # A full documentation to the providers api can be found here
598 # but is only available in german.
599 # https://www.regfish.de/domains/dyndns/dokumentation
600
601 url = "https://dyndns.regfish.de/"
602
603 def update(self):
604 data = {
605 "fqdn" : self.hostname,
606 }
607
608 # Check if we update an IPv6 address.
609 address6 = self.get_address("ipv6")
610 if address6:
611 data["ipv6"] = address6
612
613 # Check if we update an IPv4 address.
614 address4 = self.get_address("ipv4")
615 if address4:
616 data["ipv4"] = address4
617
618 # Raise an error if none address is given.
619 if not data.has_key("ipv6") and not data.has_key("ipv4"):
620 raise DDNSConfigurationError
621
622 # Check if a token has been set.
623 if self.token:
624 data["token"] = self.token
625
626 # Raise an error if no token and no useranem and password
627 # are given.
628 elif not self.username and not self.password:
629 raise DDNSConfigurationError(_("No Auth details specified."))
630
631 # HTTP Basic Auth is only allowed if no token is used.
632 if self.token:
633 # Send update to the server.
634 response = self.send_request(self.url, data=data)
635 else:
636 # Send update to the server.
637 response = self.send_request(self.url, username=self.username, password=self.password,
638 data=data)
639
640 # Get the full response message.
641 output = response.read()
642
643 # Handle success messages.
644 if "100" in output or "101" in output:
645 return
646
647 # Handle error codes.
648 if "401" or "402" in output:
649 raise DDNSAuthenticationError
650 elif "408" in output:
651 raise DDNSRequestError(_("Invalid IPv4 address has been sent."))
652 elif "409" in output:
653 raise DDNSRequestError(_("Invalid IPv6 address has been sent."))
654 elif "412" in output:
655 raise DDNSRequestError(_("No valid FQDN was given."))
656 elif "414" in output:
657 raise DDNSInternalServerError
658
659 # If we got here, some other update error happened.
660 raise DDNSUpdateError
661
662
04db1862 663class DDNSProviderSelfhost(DDNSProviderDynDNS):
6a11646e
MT
664 handle = "selfhost.de"
665 name = "Selfhost.de"
666 website = "http://www.selfhost.de/"
f22ab085 667
04db1862 668 url = "https://carol.selfhost.de/nic/update"
f22ab085 669
04db1862
MT
670 def _prepare_request_data(self):
671 data = DDNSProviderDynDNS._prepare_request_data(self)
672 data.update({
673 "hostname" : "1",
674 })
f22ab085 675
04db1862 676 return data
b09b1545
SS
677
678
679class DDNSProviderSPDNS(DDNSProviderDynDNS):
6a11646e
MT
680 handle = "spdns.org"
681 name = "SPDNS"
682 website = "http://spdns.org/"
b09b1545
SS
683
684 # Detailed information about request and response codes are provided
685 # by the vendor. They are using almost the same mechanism and status
686 # codes as dyndns.org so we can inherit all those stuff.
687 #
688 # http://wiki.securepoint.de/index.php/SPDNS_FAQ
689 # http://wiki.securepoint.de/index.php/SPDNS_Update-Tokens
690
691 url = "https://update.spdns.de/nic/update"
4ec90b93
MT
692
693
7488825c 694class DDNSProviderStrato(DDNSProviderDynDNS):
6a11646e
MT
695 handle = "strato.com"
696 name = "Strato AG"
697 website = "http:/www.strato.com/"
7488825c
SS
698
699 # Information about the request and response can be obtained here:
700 # http://www.strato-faq.de/article/671/So-einfach-richten-Sie-DynDNS-f%C3%BCr-Ihre-Domains-ein.html
701
702 url = "https://dyndns.strato.com/nic/update"
703
704
a6183090 705class DDNSProviderTwoDNS(DDNSProviderDynDNS):
6a11646e
MT
706 handle = "twodns.de"
707 name = "TwoDNS"
708 website = "http://www.twodns.de"
a6183090
SS
709
710 # Detailed information about the request can be found here
711 # http://twodns.de/en/faqs
712 # http://twodns.de/en/api
713
714 url = "https://update.twodns.de/update"
715
716 def _prepare_request_data(self):
717 data = {
718 "ip" : self.get_address("ipv4"),
719 "hostname" : self.hostname
720 }
721
722 return data
723
724
03bdd188 725class DDNSProviderUdmedia(DDNSProviderDynDNS):
6a11646e
MT
726 handle = "udmedia.de"
727 name = "Udmedia GmbH"
728 website = "http://www.udmedia.de"
03bdd188
SS
729
730 # Information about the request can be found here
731 # http://www.udmedia.de/faq/content/47/288/de/wie-lege-ich-einen-dyndns_eintrag-an.html
732
733 url = "https://www.udmedia.de/nic/update"
734
735
c8c7ca8f 736class DDNSProviderVariomedia(DDNSProviderDynDNS):
6a11646e
MT
737 handle = "variomedia.de"
738 name = "Variomedia"
739 website = "http://www.variomedia.de/"
740 protocols = ("ipv6", "ipv4",)
c8c7ca8f
SS
741
742 # Detailed information about the request can be found here
743 # https://dyndns.variomedia.de/
744
745 url = "https://dyndns.variomedia.de/nic/update"
746
747 @property
748 def proto(self):
749 return self.get("proto")
750
751 def _prepare_request_data(self):
752 data = {
753 "hostname" : self.hostname,
754 "myip" : self.get_address(self.proto)
755 }
54d3efc8
MT
756
757 return data
98fbe467
SS
758
759
760class DDNSProviderZoneedit(DDNSProvider):
6a11646e
MT
761 handle = "zoneedit.com"
762 name = "Zoneedit"
763 website = "http://www.zoneedit.com"
98fbe467
SS
764
765 # Detailed information about the request and the response codes can be
766 # obtained here:
767 # http://www.zoneedit.com/doc/api/other.html
768 # http://www.zoneedit.com/faq.html
769
770 url = "https://dynamic.zoneedit.com/auth/dynamic.html"
771
772 @property
773 def proto(self):
774 return self.get("proto")
775
776 def update(self):
777 data = {
778 "dnsto" : self.get_address(self.proto),
779 "host" : self.hostname
780 }
781
782 # Send update to the server.
783 response = self.send_request(self.url, username=self.username, password=self.password,
784 data=data)
785
786 # Get the full response message.
787 output = response.read()
788
789 # Handle success messages.
790 if output.startswith("<SUCCESS"):
791 return
792
793 # Handle error codes.
794 if output.startswith("invalid login"):
795 raise DDNSAuthenticationError
796 elif output.startswith("<ERROR CODE=\"704\""):
797 raise DDNSRequestError(_("No valid FQDN was given."))
798 elif output.startswith("<ERROR CODE=\"702\""):
799 raise DDNSInternalServerError
800
801 # If we got here, some other update error happened.
802 raise DDNSUpdateError