1 # vim: set encoding=utf-8 et sw=4 sts=4 :
4 import logging ; log = logging.getLogger('pymin.services.ip')
6 from pymin.service.util import Restorable, ConfigWriter, call, \
7 TransactionalHandler, ExecutionError, \
10 from hop import HopHandler
11 from route import RouteHandler
12 from addr import AddressHandler
13 from dev import DeviceHandler
15 __all__ = ('IpHandler',)
18 class IpHandler(Restorable, ConfigWriter, TransactionalHandler):
20 handler_help = u"Manage IP devices, addresses, routes and hops"
22 _persistent_attrs = ('devices','hops','no_device_routes')
24 _restorable_defaults = dict(
25 devices=get_network_devices(),
27 no_device_routes = list(),
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')
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()
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()
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)
55 self._write_config_for_device(device)
56 self._bring_up_no_dev_routes()
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:
63 log.debug(u'IpHandler._bring_up_no_dev_routes: add %r', route)
64 call(self._render_config('route_add', dict(
66 net_addr = route.net_addr,
67 prefix = route.prefix,
68 gateway = route.gateway,
71 except ExecutionError, e:
72 log.debug(u'IpHandler._write_config: error flushing -> %r', e)
74 def _write_hops(self):
75 r"_write_hops() -> None :: Execute all hops."
76 log.debug(u'IpHandler._write_hops()')
78 log.debug(u'IpHandler._write_hops: we have hops: %r', self.hops)
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)
85 log.debug(u'IpHandler._write_hops: configuring hops')
86 #get hops for active devices
89 if h.device in self.devices:
90 if self.devices[h.device].active:
92 call(self._render_config('hop', dict(
96 except ExecutionError, e:
97 log.debug(u'IpHandler._write_hops: error adding -> %r', e)
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()')
103 log.debug(u'IpHandler._write_config_for_device: flushing routes...')
104 call(self._render_config('route_flush', dict(dev=device.name)),
106 except ExecutionError, e:
107 log.debug(u'IpHandler._write_config_for_device: error flushing '
110 log.debug(u'IpHandler._write_config_for_device: flushing addrs...')
111 call(self._render_config('ip_flush', dict(dev=device.name)),
113 except ExecutionError, e:
114 log.debug(u'IpHandler._write_config_for_device: error flushing '
116 for address in device.addrs.values():
117 broadcast = address.broadcast
118 if broadcast is None:
121 log.debug(u'IpHandler._write_config_for_device: adding %r',
123 call(self._render_config('ip_add', dict(
126 netmask = address.netmask,
128 broadcast = broadcast,
131 except ExecutionError, e:
132 log.debug(u'IpHandler._write_config_for_device: error adding '
134 for route in device.routes:
136 log.debug(u'IpHandler._write_config_for_device: adding %r',
138 call(self._render_config('route_add', dict(
140 net_addr = route.net_addr,
141 prefix = route.prefix,
142 gateway = route.gateway,
145 except ExecutionError, e:
146 log.debug(u'IpHandler._write_config_for_device: error adding '
149 def handle_timer(self):
150 log.debug(u'IpHandler.handle_timer()')
151 self.refresh_devices()
153 def refresh_devices(self):
154 log.debug(u'IpHandler.update_devices()')
155 devices = get_network_devices()
156 #add not registered and active devices
158 for k,v in devices.items():
159 if k not in self.devices:
160 log.debug(u'IpHandler.update_devices: adding %r', v)
162 elif not self.devices[k].active:
165 self._write_config_for_device(self.devices[k])
168 self._bring_up_no_dev_routes()
169 self._restart_services()
171 #mark inactive devices
172 for k in self.devices.keys():
175 log.debug(u'IpHandler.update_devices: removing %s', k)
176 self.devices[k].active = False
179 self._bring_up_no_dev_routes()
181 def _restart_services(self):
182 for s in self.services:
183 if s._service_running:
186 except ExecutionError:
190 except ExecutionError:
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)
204 if __name__ == '__main__':
207 level = logging.DEBUG,
208 format = '%(asctime)s %(levelname)-8s %(message)s',
209 datefmt = '%H:%M:%S',
213 print '----------------------'
214 ip.hop.add('201.21.32.53','eth0')
215 ip.hop.add('205.65.65.25','eth1')
218 ip.addr.add('eth0','192.168.0.23','24','192.168.255.255')
219 ip.addr.add('eth0','192.168.0.26','24')
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')
224 ip.hop.delete('201.21.32.53','eth0')
225 ip.route.clear('eth0')