]> git.ipfire.org Git - ddns.git/blame - src/ddns/__init__.py
Log an entire stack trace for unhandled exceptions.
[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)
57 for handler in rootlogger.handlers:
58 handler.setLevel(logging.DEBUG)
59
4bba8ae2 60 logger.debug(_("Debugging mode enabled"))
f22ab085
MT
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 provider_handle = provider.INFO.get("handle")
82 assert provider_handle
83
84 assert not self.providers.has_key(provider_handle), \
85 "Provider '%s' has already been registered" % provider_handle
86
87 provider_name = provider.INFO.get("name")
88 assert provider_name
89
90 logger.debug("Registered new provider: %s (%s)" % (provider_name, provider_handle))
91 self.providers[provider_handle] = provider
92
93 def register_all_providers(self):
94 """
95 Simply registers all providers.
96 """
97 for provider in (
3b16fdb1 98 DDNSProviderAllInkl,
f3cf1f70 99 DDNSProviderDHS,
39301272 100 DDNSProviderDNSpark,
43b2cd59 101 DDNSProviderDtDNS,
bfed6701 102 DDNSProviderDynDNS,
3a8407fa 103 DDNSProviderDynU,
ee071271 104 DDNSProviderEasyDNS,
aa21a4c6 105 DDNSProviderFreeDNSAfraidOrg,
d1cd57eb 106 DDNSProviderNamecheap,
f22ab085 107 DDNSProviderNOIP,
a36d8df8 108 DDNSProviderLightningWireLabs,
a508bda6 109 DDNSProviderOVH,
ef33455e 110 DDNSProviderRegfish,
f22ab085 111 DDNSProviderSelfhost,
b09b1545 112 DDNSProviderSPDNS,
7488825c 113 DDNSProviderStrato,
a6183090 114 DDNSProviderTwoDNS,
03bdd188 115 DDNSProviderUdmedia,
c8c7ca8f 116 DDNSProviderVariomedia,
98fbe467 117 DDNSProviderZoneedit,
f22ab085
MT
118 ):
119 self.register_provider(provider)
120
2dae4713
MT
121 def get_provider_names(self):
122 """
123 Returns a list of names of all registered providers.
124 """
125 return sorted(self.providers.keys())
126
f22ab085 127 def load_configuration(self, filename):
332fd7cc
MT
128 logger.debug(_("Loading configuration file %s") % filename)
129
f22ab085
MT
130 configs = ConfigParser.SafeConfigParser()
131 configs.read([filename,])
132
133 # First apply all global configuration settings.
134 for k, v in configs.items("config"):
135 self.settings[k] = v
136
137 for entry in configs.sections():
138 # Skip the special config section.
139 if entry == "config":
140 continue
141
142 settings = {}
143 for k, v in configs.items(entry):
144 settings[k] = v
145 settings["hostname"] = entry
146
147 # Get the name of the provider.
148 provider = settings.get("provider", None)
149 if not provider:
150 logger.warning("Entry '%s' lacks a provider setting. Skipping." % entry)
151 continue
152
153 # Try to find the provider with the wanted name.
154 try:
155 provider = self.providers[provider]
156 except KeyError:
157 logger.warning("Could not find provider '%s' for entry '%s'." % (provider, entry))
158 continue
159
160 # Create an instance of the provider object with settings from the
161 # configuration file.
162 entry = provider(self, **settings)
163
164 # Add new entry to list (if not already exists).
165 if not entry in self.entries:
166 self.entries.append(entry)
167
1b8c6925
MT
168 def updateone(self, hostname, **kwargs):
169 for entry in self.entries:
170 if not entry.hostname == hostname:
171 continue
172
173 return self._update(entry, **kwargs)
174
175 raise DDNSHostNotFoundError(hostname)
176
177 def updateall(self, **kwargs):
178 """
179 Update all configured entries.
180 """
f22ab085
MT
181 # If there are no entries, there is nothing to do.
182 if not self.entries:
183 logger.debug(_("Found no entries in the configuration file. Exiting."))
184 return
185
f22ab085 186 for entry in self.entries:
1b8c6925 187 self._update(entry, **kwargs)
f22ab085 188
1b8c6925 189 def _update(self, entry, force=False):
f22ab085 190 try:
9da3e685 191 entry(force=force)
f22ab085
MT
192
193 except DDNSUpdateError, e:
194 logger.error(_("Dynamic DNS update for %(hostname)s (%(provider)s) failed:") % \
195 { "hostname" : entry.hostname, "provider" : entry.name })
196 logger.error(" %s" % e)
197
198 except Exception, e:
199 logger.error(_("Dynamic DNS update for %(hostname)s (%(provider)s) throwed an unhandled exception:") % \
708da5a4 200 { "hostname" : entry.hostname, "provider" : entry.name }, exc_info=True)
f22ab085 201
cbebe191
MT
202 else:
203 logger.info(_("Dynamic DNS update for %(hostname)s (%(provider)s) successful") % \
204 { "hostname" : entry.hostname, "provider" : entry.name })