Don't log debugging output to syslog.
[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:
87649e22
MT
55 rootlogger = logging.getLogger("ddns")
56 rootlogger.setLevel(logging.DEBUG)
87649e22 57
4bba8ae2 58 logger.debug(_("Debugging mode enabled"))
f22ab085
MT
59
60 # Initialize the settings array.
61 self.settings = {}
62
63 # Dict with all providers, that are supported.
64 self.providers = {}
65 self.register_all_providers()
66
67 # List of configuration entries.
68 self.entries = []
69
70 # Add the system class.
71 self.system = DDNSSystem(self)
72
73 def register_provider(self, provider):
74 """
75 Registers a new provider.
76 """
77 assert issubclass(provider, DDNSProvider)
78
6a11646e
MT
79 if not all((provider.handle, provider.name, provider.website)):
80 raise DDNSError(_("Provider is not properly configured"))
f22ab085 81
6a11646e
MT
82 assert not self.providers.has_key(provider.handle), \
83 "Provider '%s' has already been registered" % provider.handle
f22ab085 84
6a11646e
MT
85 logger.debug("Registered new provider: %s (%s)" % (provider.name, provider.handle))
86 self.providers[provider.handle] = provider
f22ab085
MT
87
88 def register_all_providers(self):
89 """
90 Simply registers all providers.
91 """
92 for provider in (
3b16fdb1 93 DDNSProviderAllInkl,
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,
7488825c 108 DDNSProviderStrato,
a6183090 109 DDNSProviderTwoDNS,
03bdd188 110 DDNSProviderUdmedia,
c8c7ca8f 111 DDNSProviderVariomedia,
98fbe467 112 DDNSProviderZoneedit,
f22ab085
MT
113 ):
114 self.register_provider(provider)
115
2dae4713
MT
116 def get_provider_names(self):
117 """
118 Returns a list of names of all registered providers.
119 """
120 return sorted(self.providers.keys())
121
f22ab085 122 def load_configuration(self, filename):
332fd7cc
MT
123 logger.debug(_("Loading configuration file %s") % filename)
124
f22ab085
MT
125 configs = ConfigParser.SafeConfigParser()
126 configs.read([filename,])
127
128 # First apply all global configuration settings.
129 for k, v in configs.items("config"):
130 self.settings[k] = v
131
132 for entry in configs.sections():
133 # Skip the special config section.
134 if entry == "config":
135 continue
136
137 settings = {}
138 for k, v in configs.items(entry):
139 settings[k] = v
140 settings["hostname"] = entry
141
142 # Get the name of the provider.
143 provider = settings.get("provider", None)
144 if not provider:
145 logger.warning("Entry '%s' lacks a provider setting. Skipping." % entry)
146 continue
147
148 # Try to find the provider with the wanted name.
149 try:
150 provider = self.providers[provider]
151 except KeyError:
152 logger.warning("Could not find provider '%s' for entry '%s'." % (provider, entry))
153 continue
154
155 # Create an instance of the provider object with settings from the
156 # configuration file.
157 entry = provider(self, **settings)
158
159 # Add new entry to list (if not already exists).
160 if not entry in self.entries:
161 self.entries.append(entry)
162
1b8c6925
MT
163 def updateone(self, hostname, **kwargs):
164 for entry in self.entries:
165 if not entry.hostname == hostname:
166 continue
167
168 return self._update(entry, **kwargs)
169
170 raise DDNSHostNotFoundError(hostname)
171
172 def updateall(self, **kwargs):
173 """
174 Update all configured entries.
175 """
f22ab085
MT
176 # If there are no entries, there is nothing to do.
177 if not self.entries:
178 logger.debug(_("Found no entries in the configuration file. Exiting."))
179 return
180
f22ab085 181 for entry in self.entries:
1b8c6925 182 self._update(entry, **kwargs)
f22ab085 183
1b8c6925 184 def _update(self, entry, force=False):
f22ab085 185 try:
9da3e685 186 entry(force=force)
f22ab085 187
4689f5d3 188 except DDNSError, e:
f22ab085
MT
189 logger.error(_("Dynamic DNS update for %(hostname)s (%(provider)s) failed:") % \
190 { "hostname" : entry.hostname, "provider" : entry.name })
4689f5d3
MT
191 logger.error(" %s: %s" % (e.__class__.__name__, e.reason))
192 if e.message:
193 logger.error(" %s" % e.message)
f22ab085
MT
194
195 except Exception, e:
196 logger.error(_("Dynamic DNS update for %(hostname)s (%(provider)s) throwed an unhandled exception:") % \
708da5a4 197 { "hostname" : entry.hostname, "provider" : entry.name }, exc_info=True)
f22ab085 198
cbebe191
MT
199 else:
200 logger.info(_("Dynamic DNS update for %(hostname)s (%(provider)s) successful") % \
201 { "hostname" : entry.hostname, "provider" : entry.name })