]> git.llucax.com Git - software/pymin.git/blob - services/ip/handler.py
Import HandlerError in vpn service handler (closes #32)
[software/pymin.git] / services / ip / handler.py
1 # vim: set encoding=utf-8 et sw=4 sts=4 :
2
3 from os import path
4 import logging ; log = logging.getLogger('pymin.services.ip')
5
6 from pymin.service.util import Restorable, ConfigWriter, call, \
7                                TransactionalHandler, ExecutionError, \
8                                get_network_devices
9
10 from hop import HopHandler
11 from route import RouteHandler
12 from addr import AddressHandler
13 from dev import DeviceHandler
14
15 __all__ = ('IpHandler',)
16
17
18 class IpHandler(Restorable, ConfigWriter, TransactionalHandler):
19
20     handler_help = u"Manage IP devices, addresses, routes and hops"
21
22     _persistent_attrs = ('devices','hops','no_device_routes')
23
24     _restorable_defaults = dict(
25                             devices=get_network_devices(),
26                             hops = list(),
27                             no_device_routes = list(),
28                             )
29
30     _config_writer_files = ('device', 'ip_add', 'ip_del', 'ip_flush',
31                             'route_add', 'route_del', 'route_flush', 'hop')
32     _config_writer_tpl_dir = path.join(path.dirname(__file__), 'templates')
33
34     def __init__(self, pickle_dir='.', config_dir='.'):
35         r"Initialize DhcpHandler object, see class documentation for details."
36         log.debug(u'IpHandler(%r, %r)', pickle_dir, config_dir)
37         self._persistent_dir = pickle_dir
38         self._config_writer_cfg_dir = config_dir
39         self._config_build_templates()
40         self._restore()
41         self._write_config()
42         self.addr = AddressHandler(self)
43         self.route = RouteHandler(self)
44         self.dev = DeviceHandler(self)
45         self.hop = HopHandler(self)
46         self.no_device_routes = list()
47         self.services = list()
48
49     def _write_config(self):
50         r"_write_config() -> None :: Execute all commands."
51         log.debug(u'IpHandler._write_config()')
52         for device in self.devices.values():
53             log.debug(u'IpHandler._write_config: processing device %s', device)
54             if device.active:
55                 self._write_config_for_device(device)
56         self._bring_up_no_dev_routes()
57         self._write_hops()
58
59     def _bring_up_no_dev_routes(self):
60         log.debug(u'IpHandler._bring_up_no_dev_routes()')
61         for route in self.no_device_routes:
62             try:
63                 log.debug(u'IpHandler._bring_up_no_dev_routes: add %r', route)
64                 call(self._render_config('route_add', dict(
65                         dev = None,
66                         net_addr = route.net_addr,
67                         prefix = route.prefix,
68                         gateway = route.gateway,
69                     )
70                 ), shell=True)
71             except ExecutionError, e:
72                 log.debug(u'IpHandler._write_config: error flushing -> %r', e)
73
74     def _write_hops(self):
75         r"_write_hops() -> None :: Execute all hops."
76         log.debug(u'IpHandler._write_hops()')
77         if self.hops:
78             log.debug(u'IpHandler._write_hops: we have hops: %r', self.hops)
79             try:
80                 log.debug(u'IpHandler._write_hops: flushing default hops')
81                 call('ip route del default', shell=True)
82             except ExecutionError, e:
83                 log.debug(u'IpHandler._write_hops: error adding -> %r', e)
84             try:
85                 log.debug(u'IpHandler._write_hops: configuring hops')
86                 #get hops for active devices
87                 active_hops = dict()
88                 for h in self.hops:
89                     if h.device in self.devices:
90                         if self.devices[h.device].active:
91                             active_hops.append(h)
92                 call(self._render_config('hop', dict(
93                     hops = active_hops,
94                         )
95                 ), shell=True)
96             except ExecutionError, e:
97                 log.debug(u'IpHandler._write_hops: error adding -> %r', e)
98
99     def _write_config_for_device(self, device):
100         r"_write_config_for_device(self, device) -> None :: Execute commands."
101         log.debug(u'IpHandler._write_config_for_device()')
102         try:
103             log.debug(u'IpHandler._write_config_for_device: flushing routes...')
104             call(self._render_config('route_flush', dict(dev=device.name)),
105                         shell=True)
106         except ExecutionError, e:
107             log.debug(u'IpHandler._write_config_for_device: error flushing '
108                         u'-> %r', e)
109         try:
110             log.debug(u'IpHandler._write_config_for_device: flushing addrs...')
111             call(self._render_config('ip_flush', dict(dev=device.name)),
112                         shell=True)
113         except ExecutionError, e:
114             log.debug(u'IpHandler._write_config_for_device: error flushing '
115                         u'-> %r', e)
116         for address in device.addrs.values():
117             broadcast = address.broadcast
118             if broadcast is None:
119                 broadcast = '+'
120             try:
121                 log.debug(u'IpHandler._write_config_for_device: adding %r',
122                             address)
123                 call(self._render_config('ip_add', dict(
124                     dev = device.name,
125                     addr = address.ip,
126                     netmask = address.netmask,
127                     peer = address.peer,
128                     broadcast = broadcast,
129                     )
130                 ), shell=True)
131             except ExecutionError, e:
132                 log.debug(u'IpHandler._write_config_for_device: error adding '
133                             u'-> %r', e)
134         for route in device.routes:
135             try:
136                 log.debug(u'IpHandler._write_config_for_device: adding %r',
137                             route)
138                 call(self._render_config('route_add', dict(
139                         dev = device.name,
140                         net_addr = route.net_addr,
141                         prefix = route.prefix,
142                         gateway = route.gateway,
143                     )
144                 ), shell=True)
145             except ExecutionError, e:
146                 log.debug(u'IpHandler._write_config_for_device: error adding '
147                             u'-> %r', e)
148
149     def handle_timer(self):
150         log.debug(u'IpHandler.handle_timer()')
151         self.refresh_devices()
152
153     def refresh_devices(self):
154         log.debug(u'IpHandler.update_devices()')
155         devices = get_network_devices()
156         #add not registered and active devices
157         go_active = False
158         for k,v in devices.items():
159             if k not in self.devices:
160                 log.debug(u'IpHandler.update_devices: adding %r', v)
161                 self.devices[k] = v
162             elif not self.devices[k].active:
163                 self.active = True
164                 go_active = True
165                 self._write_config_for_device(self.devices[k])
166         if go_active:
167             self._write_hops()
168             self._bring_up_no_dev_routes()
169             self._restart_services()
170
171         #mark inactive devices
172         for k in self.devices.keys():
173             go_down = False
174             if k not in devices:
175                 log.debug(u'IpHandler.update_devices: removing %s', k)
176                 self.devices[k].active = False
177                 go_down = True
178             if go_down:
179                 self._bring_up_no_dev_routes()
180
181     def _restart_services(self):
182         for s in self.services:
183             if s._service_running:
184                 try:
185                      s.stop()
186                 except ExecutionError:
187                     pass
188                 try:
189                     s.start()
190                 except ExecutionError:
191                     pass
192
193         #hooks a service to the ip handler, so when
194         #a device is brought up one can restart the service
195         #that need to refresh their device list
196     def device_up_hook(self, serv):
197         if hasattr(serv, 'stop') and hasattr(serv, 'start'):
198             self.services.append(serv)
199
200
201
202
203
204 if __name__ == '__main__':
205
206     logging.basicConfig(
207         level   = logging.DEBUG,
208         format  = '%(asctime)s %(levelname)-8s %(message)s',
209         datefmt = '%H:%M:%S',
210     )
211
212     ip = IpHandler()
213     print '----------------------'
214     ip.hop.add('201.21.32.53','eth0')
215     ip.hop.add('205.65.65.25','eth1')
216     ip.commit()
217     ip.dev.up('eth0')
218     ip.addr.add('eth0','192.168.0.23','24','192.168.255.255')
219     ip.addr.add('eth0','192.168.0.26','24')
220     ip.commit()
221     ip.route.add('eth0','192.168.0.0','24','192.168.0.1')
222     ip.route.add('eth0','192.168.0.5','24','192.168.0.1')
223     ip.commit()
224     ip.hop.delete('201.21.32.53','eth0')
225     ip.route.clear('eth0')
226     ip.commit()
227
228
229