]> git.llucax.com Git - software/pymin.git/blob - services/dns/handler.py
Add GPL v3 license to the project
[software/pymin.git] / services / dns / handler.py
1 # vim: set encoding=utf-8 et sw=4 sts=4 :
2
3 # TODO documentation, validation
4
5 from os import path
6 from os import unlink
7 import logging ; log = logging.getLogger('pymin.services.dns')
8
9 from pymin.service.util import Restorable, ConfigWriter, \
10                                TransactionalHandler, ParametersHandler, \
11                                InitdHandler, call
12
13 from host import HostHandler
14 from mx import MailExchangeHandler
15 from ns import NameServerHandler
16 from zone import ZoneHandler
17
18 __all__ = ('DnsHandler',)
19
20
21 class DnsHandler(Restorable, ConfigWriter, InitdHandler, TransactionalHandler,
22                  ParametersHandler):
23     r"""DnsHandler([pickle_dir[, config_dir]]) -> DnsHandler instance.
24
25     Handles DNS service commands for the dns program.
26
27     pickle_dir - Directory where to write the persistent configuration data.
28
29     config_dir - Directory where to store de generated configuration files.
30
31     Both defaults to the current working directory.
32     """
33
34     handler_help = u"Manage DNS service"
35
36     _initd_name = 'named'
37
38     _persistent_attrs = ('params', 'zones')
39
40     _restorable_defaults = dict(
41             zones = dict(),
42             params  = dict(
43                 isp_dns1 = '',
44                 isp_dns2 = '',
45                 bind_addr1 = '',
46                 bind_addr2 = ''
47             ),
48     )
49
50     _config_writer_files = ('named.conf', 'zoneX.zone')
51     _config_writer_tpl_dir = path.join(path.dirname(__file__), 'templates')
52
53     def __init__(self, pickle_dir='.', config_dir='.'):
54         r"Initialize DnsHandler object, see class documentation for details."
55         log.debug(u'DnsHandler(%r, %r)', pickle_dir, config_dir)
56         self._persistent_dir = pickle_dir
57         self._config_writer_cfg_dir = config_dir
58         self._update = False
59         self._config_build_templates()
60         InitdHandler.__init__(self)
61         self.host = HostHandler(self)
62         self.zone = ZoneHandler(self)
63         self.mx = MailExchangeHandler(self)
64         self.ns = NameServerHandler(self)
65
66     def _zone_filename(self, zone):
67         return zone.name + '.zone'
68
69     def _get_config_vars(self, config_file):
70         return dict(zones=self.zones.values(), **self.params)
71
72     def _write_config(self):
73         r"_write_config() -> None :: Generate all the configuration files."
74         log.debug(u'DnsHandler._write_config()')
75         delete_zones = list()
76         for a_zone in self.zones.values():
77             log.debug(u'DnsHandler._write_config: processing zone %s', a_zone)
78             if a_zone._update or a_zone._add:
79                 if not a_zone._add and self._service_running:
80                     log.debug(u'DnsHandler._write_config: zone updated and '
81                                 u'the service is running, freezing zone')
82                     call(('rndc', 'freeze', a_zone.name))
83                 vars = dict(
84                     zone = a_zone,
85                     hosts = a_zone.hosts.values(),
86                     mxs = a_zone.mxs.values(),
87                     nss = a_zone.nss.values()
88                 )
89                 self._write_single_config('zoneX.zone',
90                                             self._zone_filename(a_zone), vars)
91                 a_zone._update = False
92                 if not a_zone._add and self._service_running:
93                     log.debug(u'DnsHandler._write_config: unfreezing zone')
94                     call(('rndc', 'thaw', a_zone.name))
95                 else :
96                     self._update = True
97                     a_zone._add = False
98             if a_zone._delete:
99                 #borro el archivo .zone
100                 log.debug(u'DnsHandler._write_config: zone deleted, removing '
101                             u'the file %r', self._zone_filename(a_zone))
102                 try:
103                     self._update = True
104                     unlink(self._zone_filename(a_zone))
105                 except OSError:
106                     #la excepcion pude darse en caso que haga un add de una zona y
107                     #luego el del, como no hice commit, no se crea el archivo
108                     log.debug(u'DnsHandler._write_config: file not found')
109                     pass
110                 delete_zones.append(a_zone.name)
111         #borro las zonas
112         for z in delete_zones:
113             del self.zones[z]
114         #archivo general
115         if self._update:
116             self._write_single_config('named.conf')
117             self._update = False
118             return False # Do reload
119         return True # we don't need to reload
120
121     # HACK!!!!
122     def handle_timer(self):
123         log.debug(u'DnsHandler.handle_timer()')
124         import subprocess
125         p = subprocess.Popen(('pgrep', '-f', '/usr/sbin/named'),
126                                 stdout=subprocess.PIPE)
127         pid = p.communicate()[0]
128         if p.returncode == 0 and len(pid) > 0:
129             log.debug(u'DnsHandler.handle_timer: pid present, running')
130             self._service_running = True
131         else:
132             log.debug(u'DnsHandler.handle_timer: pid absent, NOT running')
133             self._service_running = False
134
135
136
137 if __name__ == '__main__':
138
139     logging.basicConfig(
140         level   = logging.DEBUG,
141         format  = '%(asctime)s %(levelname)-8s %(message)s',
142         datefmt = '%H:%M:%S',
143     )
144
145     dns = DnsHandler();
146
147     dns.set('isp_dns1','la_garcha.com')
148     dns.set('bind_addr1','localhost')
149     dns.zone.add('zona_loca.com')
150     #dns.zone.update('zona_loca.com','ns1.dominio.com')
151
152     dns.host.add('zona_loca.com','hostname_loco','192.168.0.23')
153     dns.host.update('zona_loca.com','hostname_loco','192.168.0.66')
154
155     dns.host.add('zona_loca.com','hostname_kuak','192.168.0.23')
156     dns.host.delete('zona_loca.com','hostname_kuak')
157
158     dns.host.add('zona_loca.com','hostname_kuang','192.168.0.24')
159     dns.host.add('zona_loca.com','hostname_chan','192.168.0.25')
160     dns.host.add('zona_loca.com','hostname_kaine','192.168.0.26')
161
162     dns.mx.add('zona_loca.com','mx1.sarasa.com',10)
163     dns.mx.update('zona_loca.com','mx1.sarasa.com',20)
164     dns.mx.add('zona_loca.com','mx2.sarasa.com',30)
165     dns.mx.add('zona_loca.com','mx3.sarasa.com',40)
166     dns.mx.delete('zona_loca.com','mx3.sarasa.com')
167
168     dns.ns.add('zona_loca.com','ns1.jua.com')
169     dns.ns.add('zona_loca.com','ns2.jua.com')
170     dns.ns.add('zona_loca.com','ns3.jua.com')
171     dns.ns.delete('zona_loca.com','ns3.jua.com')
172
173     dns.zone.add('zona_oscura')
174
175     dns.host.add('zona_oscura','hostname_a','192.168.0.24')
176     dns.host.add('zona_oscura','hostname_b','192.168.0.25')
177     dns.host.add('zona_oscura','hostname_c','192.168.0.26')
178
179     dns.zone.delete('zona_oscura')
180
181     dns.commit()
182
183     print 'ZONAS :', dns.zone.show()
184     for z in dns.zones:
185         print 'HOSTS from', z, ':', dns.host.show(z)
186
187     from pymin.services.util import ItemNotFoundError, ItemAlreadyExistsError, \
188                                     ContainerNotFoundError
189
190     try:
191         dns.zone.delete('zone-sarasa')
192     except ItemNotFoundError, inst:
193         print 'Error: ', inst
194
195
196     #test hosts errors
197     try:
198         dns.host.update('zone-sarasa','kuak','192.68')
199     except ContainerNotFoundError, inst:
200         print 'Error: ', inst
201
202     try:
203         dns.host.update('zona_loca.com','kuak','192.68')
204     except ItemNotFoundError, inst:
205         print 'Error: ', inst
206
207     try:
208         dns.host.delete('zone-sarasa','lala')
209     except ContainerNotFoundError, inst:
210         print 'Error: ', inst
211
212     try:
213         dns.host.delete('zona_loca.com','lala')
214     except ItemNotFoundError, inst:
215         print 'Error: ', inst
216
217     try:
218         dns.host.add('zona','hostname_loco','192.168.0.23')
219     except ContainerNotFoundError, inst:
220         print 'Error: ', inst
221
222     try:
223         dns.host.add('zona_loca.com','hostname_loco','192.168.0.23')
224     except ItemAlreadyExistsError, inst:
225         print 'Error: ', inst