Add Namecheap as new provider.
[oddments/ddns.git] / src / ddns / __init__.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
MT
21
22import logging
23import logging.handlers
24import ConfigParser
25
26from i18n import _
27
28logger = logging.getLogger("ddns.core")
29logger.propagate = 1
30
31from .providers import *
32from .system import DDNSSystem
33
34# Setup the logger.
35def setup_logging():
36 rootlogger = logging.getLogger("ddns")
4bba8ae2 37 rootlogger.setLevel(logging.INFO)
f22ab085
MT
38
39 # Setup a logger that logs to syslog.
5ad24917
MT
40 handler = logging.handlers.SysLogHandler(address="/dev/log",
41 facility=logging.handlers.SysLogHandler.LOG_DAEMON
42 )
43 handler.setLevel(logging.INFO)
44 rootlogger.addHandler(handler)
f22ab085
MT
45
46 handler = logging.StreamHandler()
47 rootlogger.addHandler(handler)
48
49setup_logging()
50
51class DDNSCore(object):
52 def __init__(self, debug=False):
53 # In debug mode, enable debug logging.
54 if debug:
55 logger.setLevel(logging.DEBUG)
4bba8ae2 56 logger.debug(_("Debugging mode enabled"))
f22ab085
MT
57
58 # Initialize the settings array.
59 self.settings = {}
60
61 # Dict with all providers, that are supported.
62 self.providers = {}
63 self.register_all_providers()
64
65 # List of configuration entries.
66 self.entries = []
67
68 # Add the system class.
69 self.system = DDNSSystem(self)
70
71 def register_provider(self, provider):
72 """
73 Registers a new provider.
74 """
75 assert issubclass(provider, DDNSProvider)
76
77 provider_handle = provider.INFO.get("handle")
78 assert provider_handle
79
80 assert not self.providers.has_key(provider_handle), \
81 "Provider '%s' has already been registered" % provider_handle
82
83 provider_name = provider.INFO.get("name")
84 assert provider_name
85
86 logger.debug("Registered new provider: %s (%s)" % (provider_name, provider_handle))
87 self.providers[provider_handle] = provider
88
89 def register_all_providers(self):
90 """
91 Simply registers all providers.
92 """
93 for provider in (
f3cf1f70 94 DDNSProviderDHS,
39301272 95 DDNSProviderDNSpark,
43b2cd59 96 DDNSProviderDtDNS,
bfed6701 97 DDNSProviderDynDNS,
3a8407fa 98 DDNSProviderDynU,
ee071271 99 DDNSProviderEasyDNS,
aa21a4c6 100 DDNSProviderFreeDNSAfraidOrg,
d1cd57eb 101 DDNSProviderNamecheap,
f22ab085 102 DDNSProviderNOIP,
a36d8df8 103 DDNSProviderLightningWireLabs,
a508bda6 104 DDNSProviderOVH,
ef33455e 105 DDNSProviderRegfish,
f22ab085 106 DDNSProviderSelfhost,
b09b1545 107 DDNSProviderSPDNS,
c8c7ca8f 108 DDNSProviderVariomedia,
f22ab085
MT
109 ):
110 self.register_provider(provider)
111
2dae4713
MT
112 def get_provider_names(self):
113 """
114 Returns a list of names of all registered providers.
115 """
116 return sorted(self.providers.keys())
117
f22ab085 118 def load_configuration(self, filename):
332fd7cc
MT
119 logger.debug(_("Loading configuration file %s") % filename)
120
f22ab085
MT
121 configs = ConfigParser.SafeConfigParser()
122 configs.read([filename,])
123
124 # First apply all global configuration settings.
125 for k, v in configs.items("config"):
126 self.settings[k] = v
127
128 for entry in configs.sections():
129 # Skip the special config section.
130 if entry == "config":
131 continue
132
133 settings = {}
134 for k, v in configs.items(entry):
135 settings[k] = v
136 settings["hostname"] = entry
137
138 # Get the name of the provider.
139 provider = settings.get("provider", None)
140 if not provider:
141 logger.warning("Entry '%s' lacks a provider setting. Skipping." % entry)
142 continue
143
144 # Try to find the provider with the wanted name.
145 try:
146 provider = self.providers[provider]
147 except KeyError:
148 logger.warning("Could not find provider '%s' for entry '%s'." % (provider, entry))
149 continue
150
151 # Create an instance of the provider object with settings from the
152 # configuration file.
153 entry = provider(self, **settings)
154
155 # Add new entry to list (if not already exists).
156 if not entry in self.entries:
157 self.entries.append(entry)
158
1b8c6925
MT
159 def updateone(self, hostname, **kwargs):
160 for entry in self.entries:
161 if not entry.hostname == hostname:
162 continue
163
164 return self._update(entry, **kwargs)
165
166 raise DDNSHostNotFoundError(hostname)
167
168 def updateall(self, **kwargs):
169 """
170 Update all configured entries.
171 """
f22ab085
MT
172 # If there are no entries, there is nothing to do.
173 if not self.entries:
174 logger.debug(_("Found no entries in the configuration file. Exiting."))
175 return
176
f22ab085 177 for entry in self.entries:
1b8c6925 178 self._update(entry, **kwargs)
f22ab085 179
1b8c6925 180 def _update(self, entry, force=False):
f22ab085 181 try:
9da3e685 182 entry(force=force)
f22ab085
MT
183
184 except DDNSUpdateError, e:
185 logger.error(_("Dynamic DNS update for %(hostname)s (%(provider)s) failed:") % \
186 { "hostname" : entry.hostname, "provider" : entry.name })
187 logger.error(" %s" % e)
188
189 except Exception, e:
190 logger.error(_("Dynamic DNS update for %(hostname)s (%(provider)s) throwed an unhandled exception:") % \
191 { "hostname" : entry.hostname, "provider" : entry.name })
192 logger.error(" %s" % e)
193
cbebe191
MT
194 else:
195 logger.info(_("Dynamic DNS update for %(hostname)s (%(provider)s) successful") % \
196 { "hostname" : entry.hostname, "provider" : entry.name })