View | Details | Raw Unified | Return to bug 40393
Collapse All | Expand All

(-)a/management/univention-management-console-module-diagnostic/umc/python/diagnostic/plugins/check_nameservers.py (-2 / +238 lines)
Line 0    Link Here 
0
- 
1
#!/usr/bin/python2.7
2
# coding: utf-8
3
#
4
# Univention Management Console module:
5
#  System Diagnosis UMC module
6
#
7
# Copyright 2017 Univention GmbH
8
#
9
# http://www.univention.de/
10
#
11
# All rights reserved.
12
#
13
# The source code of this program is made available
14
# under the terms of the GNU Affero General Public License version 3
15
# (GNU AGPL V3) as published by the Free Software Foundation.
16
#
17
# Binary versions of this program provided by Univention to you as
18
# well as other copyrighted, protected or trademarked materials like
19
# Logos, graphics, fonts, specific documentations and configurations,
20
# cryptographic keys etc. are subject to a license agreement between
21
# you and Univention and not subject to the GNU AGPL V3.
22
#
23
# In the case you use this program under the terms of the GNU AGPL V3,
24
# the program is provided in the hope that it will be useful,
25
# but WITHOUT ANY WARRANTY; without even the implied warranty of
26
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27
# GNU Affero General Public License for more details.
28
#
29
# You should have received a copy of the GNU Affero General Public
30
# License with the Debian GNU/Linux or Univention distribution in file
31
# /usr/share/common-licenses/AGPL-3; if not, see
32
# <http://www.gnu.org/licenses/>.
33
34
import socket
35
import ldap.filter
36
import itertools as it
37
38
import univention.admin.uldap
39
import univention.admin.modules as udm_modules
40
import univention.admin.objects as udm_objects
41
42
import univention.config_registry
43
from univention.management.console.modules.diagnostic import Warning
44
45
from univention.lib.i18n import Translation
46
_ = Translation('univention-management-console-module-diagnostic').translate
47
48
title = _('Check nameserver entries on DNS zones')
49
description = _('All nameserver entries are ok.')
50
links = [{
51
	'name': 'sdb',
52
	'href': _('http://sdb.univention.de/1273'),
53
	'label': _('Univention Support Database - Bind: zone transfer failed')
54
}]
55
56
57
class RecordNotFound(Exception):
58
	pass
59
60
61
class ZoneError(Exception):
62
	def __init__(self, nameserver):
63
		self.nameserver = nameserver
64
65
	@property
66
	def zone(self):
67
		return self.nameserver.zone
68
69
70
class NoHostRecord(ZoneError):
71
	def __str__(self):
72
		msg = _('Found no host record (A/AAAA record) for nameserver {ns}.')
73
		return msg.format(ns=self.nameserver.nameserver())
74
75
76
class CnameAsNameServer(ZoneError):
77
	def __str__(self):
78
		msg = _('Found illegal alias record (CNAME record) for nameserver {ns}.')
79
		return msg.format(ns=self.nameserver.nameserver())
80
81
82
class Zone(object):
83
	def __init__(self, udm_zone, domainname):
84
		self.udm_zone = udm_zone
85
		self.domainname = domainname
86
87
	@property
88
	def kind(self):
89
		return self.udm_zone.module
90
91
	@property
92
	def zone(self):
93
		if self.kind == 'dns/forward_zone':
94
			return self.udm_zone.get('zone')
95
		return self.udm_zone.get('subnet')
96
97
	def base(self):
98
		if self.kind == 'dns/forward_zone':
99
			return self.zone
100
		return '{}.in-addr.arpa'.format(self.zone)
101
102
	def nameserver(self):
103
		for nameserver in self.udm_zone.get('nameserver'):
104
			yield NameServer(self, nameserver)
105
106
	def umc_link(self):
107
		text = 'udm:dns/dns'
108
		link = {
109
			'module': 'udm',
110
			'flavor': 'dns/dns',
111
			'props': {
112
				'openObject': {
113
					'objectDN': self.udm_zone.dn,
114
					'objectType': self.kind,
115
				}
116
			}
117
		}
118
		return (text, link)
119
120
121
class NameServer(object):
122
	def __init__(self, zone, nameserver):
123
		self.zone = zone
124
		self._nameserver = nameserver
125
126
	def is_qualified(self):
127
		return self._nameserver.endswith('.')
128
129
	def nameserver(self):
130
		return self._nameserver.rstrip('.')
131
132
	def fqdn(self):
133
		if self.is_qualified():
134
			return self.nameserver()
135
		return '{}.{}'.format(self.nameserver(), self.zone.base())
136
137
	def is_in_zone(self):
138
		return not self.is_qualified() or \
139
			self.nameserver().endswith(self.zone.domainname)
140
141
	def _generate_splits(self, fqdn):
142
		zn = fqdn
143
		while True:
144
			(rdn, zn) = zn.split('.', 1)
145
			if rdn and zn:
146
				yield (rdn, zn)
147
			if '.' not in zn or zn == self.zone.domainname:
148
				break
149
150
	def build_filter(self):
151
		template = '(&(relativeDomainName=%s)(zoneName=%s))'
152
		expressions = (ldap.filter.filter_format(template, (rdn, zn))
153
			for (rdn, zn) in self._generate_splits(self.fqdn()))
154
		return '(|{})'.format(''.join(expressions))
155
156
157
class UDM(object):
158
	def __init__(self):
159
		univention.admin.modules.update()
160
		(self.ldap_connection, self.position) = univention.admin.uldap.getMachineConnection()
161
		self.configRegistry = univention.config_registry.ConfigRegistry()
162
		self.configRegistry.load()
163
164
	def lookup(self, module_name, filter_expression=''):
165
		module = udm_modules.get(module_name)
166
		for instance in module.lookup(None, self.ldap_connection, filter_expression):
167
			instance.open()
168
			yield instance
169
170
	def find(self, nameserver):
171
		filter_expression = nameserver.build_filter()
172
		for (dn, attr) in self.ldap_connection.search(filter_expression):
173
			if dn:
174
				for module in udm_modules.identify(dn, attr):
175
					record = udm_objects.get(module, None,
176
						self.ldap_connection, self.position, dn, attr=attr,
177
						attributes=attr)
178
					record.open()
179
					return record
180
		raise RecordNotFound()
181
182
	def all_zones(self):
183
		domainname = self.configRegistry.get('domainname')
184
		for zone in self.lookup('dns/forward_zone'):
185
			yield Zone(zone, domainname)
186
		for zone in self.lookup('dns/reverse_zone'):
187
			yield Zone(zone, domainname)
188
189
	def check_zone(self, zone):
190
		for nameserver in zone.nameserver():
191
			try:
192
				record = self.find(nameserver)
193
			except RecordNotFound:
194
				if not nameserver.is_in_zone():
195
					try:
196
						socket.getaddrinfo(nameserver.fqdn(), None)
197
					except socket.gaierror:
198
						yield NoHostRecord(nameserver)
199
				else:
200
					yield NoHostRecord(nameserver)
201
202
			else:
203
				if record.module == 'dns/alias':
204
					yield CnameAsNameServer(nameserver)
205
				elif record.module != 'dns/host_record':
206
					yield NoHostRecord(nameserver)
207
208
209
def find_all_zone_problems():
210
	udm = UDM()
211
	for zone in udm.all_zones():
212
		for error in udm.check_zone(zone):
213
			yield error
214
215
216
def run():
217
	ed = [_('Found errors in the nameserver entries of the following zones.') + ' ' +
218
		_('Please refer to {sdb} for further information.')]
219
	modules = list()
220
	tmpl_forward = _('In forward zone {name} (see {{{link}}}):')
221
	tmpl_reverse = _('In reverse zone {name} (see {{{link}}}):')
222
	for (zone, group) in it.groupby(find_all_zone_problems(), lambda error: error.zone):
223
		(text, link) = zone.umc_link()
224
		ed.append('')
225
		if zone.kind == 'dns/forward_zone':
226
			ed.append(tmpl_forward.format(kind=zone.kind, name=zone.zone, link=text))
227
		elif zone.kind == 'dns/reverse_zone':
228
			ed.append(tmpl_reverse.format(kind=zone.kind, name=zone.zone, link=text))
229
		ed.extend(str(error) for error in group)
230
		modules.append(link)
231
232
	if modules:
233
		raise Warning(description='\n'.join(ed), umc_modules=modules)
234
235
236
if __name__ == '__main__':
237
	from univention.management.console.modules.diagnostic import main
238
	main()
1
(po)
239
(po)
2
--
3
.../umc/python/diagnostic/de.po                    | 50 +++++++++++++++++++++-
240
.../umc/python/diagnostic/de.po                    | 50 +++++++++++++++++++++-
4
1 file changed, 48 insertions(+), 2 deletions(-)
241
1 file changed, 48 insertions(+), 2 deletions(-)
(-)a/management/univention-management-console-module-diagnostic/umc/python/diagnostic/de.po (-3 / +48 lines)
 Lines 2-9    Link Here 
2
msgid ""
2
msgid ""
3
msgstr ""
3
msgstr ""
4
"Project-Id-Version: univention-management-console-module-diagnostic\n"
4
"Project-Id-Version: univention-management-console-module-diagnostic\n"
5
"Report-Msgid-Bugs-To: packages@univention.de\n"
5
"Report-Msgid-Bugs-To: \n"
6
"POT-Creation-Date: 2016-01-14 12:19+0100\n"
6
"POT-Creation-Date: 2017-06-22 16:36+0200\n"
7
"PO-Revision-Date: \n"
7
"PO-Revision-Date: \n"
8
"Last-Translator: Univention GmbH <packages@univention.de>\n"
8
"Last-Translator: Univention GmbH <packages@univention.de>\n"
9
"Language-Team: Univention GmbH <packages@univention.de>\n"
9
"Language-Team: Univention GmbH <packages@univention.de>\n"
 Lines 27-32   msgstr "" Link Here 
27
msgid "Adjust to suggested limits"
27
msgid "Adjust to suggested limits"
28
msgstr "An vorgeschlagene Limits anpassen"
28
msgstr "An vorgeschlagene Limits anpassen"
29
29
30
#: umc/python/diagnostic/plugins/check_nameservers.py:49
31
msgid "All nameserver entries are ok."
32
msgstr "Alle Nameserver Einträge sind in Ordnung."
33
34
#: umc/python/diagnostic/plugins/check_nameservers.py:48
35
msgid "Check nameserver entries on DNS zones"
36
msgstr "Überprüfe die Nameserver Einträge der DNS Zonen"
37
38
#: umc/python/diagnostic/plugins/check_nameservers.py:217
39
msgid "Found errors in the nameserver entries of the following zones."
40
msgstr ""
41
"Es wurden Fehler in den Nameserver Einträgen der folgenden Zonen gefunden."
42
43
#: umc/python/diagnostic/plugins/check_nameservers.py:78
44
#, python-brace-format
45
msgid "Found illegal alias record (CNAME record) for nameserver {ns}."
46
msgstr "Ungültiger Alias-Record (CNAME record) für Namenserver {ns} gefunden."
47
48
#: umc/python/diagnostic/plugins/check_nameservers.py:72
49
#, python-brace-format
50
msgid "Found no host record (A/AAAA record) for nameserver {ns}."
51
msgstr "Kein Host-Record (A/AAAA record) für Namenserver {ns} gefunden."
52
30
#: umc/python/diagnostic/plugins/gateway.py:11
53
#: umc/python/diagnostic/plugins/gateway.py:11
31
msgid "Gateway is not reachable"
54
msgid "Gateway is not reachable"
32
msgstr "Gateway ist nicht erreichbar"
55
msgstr "Gateway ist nicht erreichbar"
 Lines 49-54   msgid "If these settings are correct the problem relies in the gateway itself:" Link Here 
49
msgstr ""
72
msgstr ""
50
"Wenn diese Einstellungen richtig sind liegt das Problem im Gateway selbst:"
73
"Wenn diese Einstellungen richtig sind liegt das Problem im Gateway selbst:"
51
74
75
#: umc/python/diagnostic/plugins/check_nameservers.py:220
76
#, python-brace-format
77
msgid "In forward zone {name} (see {{{link}}}):"
78
msgstr "In der Forward-Zone {name} (siehe {{{link}}}):"
79
80
#: umc/python/diagnostic/plugins/check_nameservers.py:221
81
#, python-brace-format
82
msgid "In reverse zone {name} (see {{{link}}}):"
83
msgstr "In der Reverse-Zone {name} (siehe {{{link}}}):"
84
52
#: umc/python/diagnostic/plugins/security_limits.py:19
85
#: umc/python/diagnostic/plugins/security_limits.py:19
53
#, python-brace-format
86
#, python-brace-format
54
msgid ""
87
msgid ""
 Lines 116-121   msgstr "" Link Here 
116
"Bitte sicherstellen, dass die DNS-Einstellungen in {setup:network} korrekt "
149
"Bitte sicherstellen, dass die DNS-Einstellungen in {setup:network} korrekt "
117
"konfiguriert sind."
150
"konfiguriert sind."
118
151
152
#: umc/python/diagnostic/plugins/check_nameservers.py:218
153
#, python-brace-format
154
msgid "Please refer to {sdb} for further information."
155
msgstr "Siehe {sdb} für weitere Informationen."
156
119
#: umc/python/diagnostic/plugins/ssh_connection.py:52
157
#: umc/python/diagnostic/plugins/ssh_connection.py:52
120
#, python-format
158
#, python-format
121
msgid ""
159
msgid ""
 Lines 260-265   msgstr "" Link Here 
260
"dass Authentifikations-Zugangsdaten (falls existierend) korrekt sind und die "
298
"dass Authentifikations-Zugangsdaten (falls existierend) korrekt sind und die "
261
"ACL's des Proxy-Servers nicht verbieten, Anfragen an %s zu stellen."
299
"ACL's des Proxy-Servers nicht verbieten, Anfragen an %s zu stellen."
262
300
301
#: umc/python/diagnostic/plugins/check_nameservers.py:53
302
msgid "Univention Support Database - Bind: zone transfer failed"
303
msgstr ""
304
305
#: umc/python/diagnostic/plugins/check_nameservers.py:52
306
msgid "http://sdb.univention.de/1273"
307
msgstr ""
308
263
#: umc/python/diagnostic/plugins/package_status.py:28
309
#: umc/python/diagnostic/plugins/package_status.py:28
264
msgid "some"
310
msgid "some"
265
msgstr "einigen"
311
msgstr "einigen"
266
- 

Return to bug 40393