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