]> git.llucax.com Git - software/pymin.git/blob - pymin/services/ip/__init__.py
Se agrega el manejo de usuarios al proxy
[software/pymin.git] / pymin / services / ip / __init__.py
1 # vim: set encoding=utf-8 et sw=4 sts=4 :
2
3 from subprocess import Popen, PIPE
4 from os import path
5
6 from pymin.seqtools import Sequence
7 from pymin.dispatcher import handler, HandlerError, Handler
8 from pymin.services.util import Restorable, ConfigWriter, InitdHandler, \
9                                 TransactionalHandler
10
11 __ALL__ = ('IpHandler', 'Error','DeviceError', 'DeviceNotFoundError',
12            'RouteError', 'RouteNotFoundError', 'RouteAlreadyExistsError',
13            'AddressError', 'AddressNotFoundError', 'AddressAlreadyExistsError')
14
15 class Error(HandlerError):
16     r"""
17     Error(command) -> Error instance :: Base IpHandler exception class.
18
19     All exceptions raised by the IpHandler inherits from this one, so you can
20     easily catch any IpHandler exception.
21
22     message - A descriptive error message.
23     """
24
25     def __init__(self, message):
26         r"Initialize the Error object. See class documentation for more info."
27         self.message = message
28
29     def __str__(self):
30         return self.message
31
32 class DeviceError(Error):
33
34     def __init__(self, device):
35         self.message = 'Device error : "%s"' % device
36
37 class DeviceNotFoundError(DeviceError):
38
39     def __init__(self, device):
40         self.message = 'Device not found : "%s"' % device
41
42 class AddressError(Error):
43
44     def __init__(self, addr):
45         self.message = 'Address error : "%s"' % addr
46
47 class AddressNotFoundError(AddressError):
48
49     def __init__(self, address):
50         self.message = 'Address not found : "%s"' % address
51
52 class AddressAlreadyExistsError(AddressError):
53
54     def __init__(self, address):
55         self.message = 'Address already exists : "%s"' % address
56
57 class RouteError(Error):
58
59     def __init__(self, route):
60         self.message = 'Route error : "%s"' % route
61
62 class RouteNotFoundError(RouteError):
63
64     def __init__(self, route):
65         self.message = 'Route not found : "%s"' % route
66
67 class RouteAlreadyExistsError(RouteError):
68
69     def __init__(self, route):
70         self.message = 'Route already exists : "%s"' % route
71
72
73 class Route(Sequence):
74
75     def __init__(self, net_addr, prefix, gateway):
76         self.net_addr = net_addr
77         self.prefix = prefix
78         self.gateway = gateway
79
80     def as_tuple(self):
81         return(self.addr, self.prefix, self.gateway)
82
83     def __cmp__(self, other):
84         if self.net_addr == other.net_addr \
85                 and self.prefix == other.prefix \
86                 and self.gateway == other.gateway:
87             return 0
88         return cmp(id(self), id(other))
89
90 class RouteHandler(Handler):
91
92     def __init__(self, devices):
93         self.devices = devices
94
95     @handler(u'Adds a route to a device')
96     def add(self, device, net_addr, prefix, gateway):
97         if not device in self.devices:
98             raise DeviceNotFoundError(device)
99         r = Route(net_addr, prefix, gateway)
100         try:
101             self.devices[device].routes.index(r)
102             raise RouteAlreadyExistsError(net_addr + '/' + prefix + '->' + gateway)
103         except ValueError:
104             self.devices[device].routes.append(r)
105
106     @handler(u'Deletes a route from a device')
107     def delete(self, device, net_addr, prefix, gateway):
108         if not device in self.devices:
109             raise DeviceNotFoundError(device)
110         r = Route(net_addr, prefix, gateway)
111         try:
112             self.devices[device].routes.remove(r)
113         except ValueError:
114             raise RouteNotFoundError(net_addr + '/' + prefix + '->' + gateway)
115
116     @handler(u'Flushes routes from a device')
117     def flush(self, device):
118         if not device in self.devices:
119             raise DeviceNotFoundError(device)
120         self.devices[device].routes = list()
121
122
123     @handler(u'List routes')
124     def list(self, device):
125         try:
126             k = self.devices[device].routes.keys()
127         except ValueError:
128             k = list()
129         return k
130
131     @handler(u'Get information about all routes')
132     def show(self):
133         try:
134             k = self.devices[device].routes.values()
135         except ValueError:
136             k = list()
137         return k
138
139
140 class Address(Sequence):
141
142     def __init__(self, ip, prefix, broadcast):
143         self.ip = ip
144         self.prefix = prefix
145         self.broadcast = broadcast
146
147     def as_tuple(self):
148         return (self.ip, self.prefix, self.broadcast)
149
150 class AddressHandler(Handler):
151
152     def __init__(self, devices):
153         self.devices = devices
154
155     @handler(u'Adds an address to a device')
156     def add(self, device, ip, prefix, broadcast='+'):
157         if not device in self.devices:
158             raise DeviceNotFoundError(device)
159         if ip in self.devices[device].addrs:
160             raise AddressAlreadyExistsError(ip)
161         self.devices[device].addrs[ip] = Address(ip, prefix, broadcast)
162
163     @handler(u'Deletes an address from a device')
164     def delete(self, device, ip):
165         if not device in self.devices:
166             raise DeviceNotFoundError(device)
167         if not ip in self.devices[device].addrs:
168             raise AddressNotFoundError(ip)
169         del self.devices[device].addrs[ip]
170
171     @handler(u'Flushes addresses from a device')
172     def flush(self, device):
173         if not device in self.devices:
174             raise DeviceNotFoundError(device)
175         self.devices[device].addrs = dict()
176
177     @handler(u'List all addresses from a device')
178     def list(self, device):
179         try:
180             k = self.devices[device].addrs.keys()
181         except ValueError:
182             k = list()
183         return k
184
185     @handler(u'Get information about addresses from a device')
186     def show(self, device):
187         try:
188             k = self.devices[device].addrs.values()
189         except ValueError:
190             k = list()
191         return k
192
193
194 class Device(Sequence):
195
196     def __init__(self, name, mac):
197         self.name = name
198         self.mac = mac
199         self.addrs = dict()
200         self.routes = list()
201
202     def as_tuple(self):
203         return (self.name, self.mac)
204
205 class DeviceHandler(Handler):
206
207     def __init__(self, devices):
208         # FIXME remove templates to execute commands
209         from mako.template import Template
210         self.devices = devices
211         template_dir = path.join(path.dirname(__file__), 'templates')
212         dev_fn = path.join(template_dir, 'device')
213         self.device_template = Template(filename=dev_fn)
214
215     @handler(u'Bring the device up')
216     def up(self, name):
217         if name in self.devices:
218             print self.device_template.render(dev=name, action='up')
219         else:
220             raise DeviceNotFoundError(name)
221
222     @handler(u'Bring the device down')
223     def down(self, name):
224         if name in self.devices:
225             print self.device_template.render(dev=name, action='down')
226         else:
227             raise DeviceNotFoundError(name)
228
229     @handler(u'List all devices')
230     def list(self):
231         return self.devices.keys()
232
233     @handler(u'Get information about a device')
234     def show(self):
235         return self.devices.items()
236
237
238 def get_devices():
239     p = Popen(('ip', 'link', 'list'), stdout=PIPE, close_fds=True)
240     string = p.stdout.read()
241     p.wait()
242     d = dict()
243     i = string.find('eth')
244     while i != -1:
245         eth = string[i:i+4]
246         m = string.find('link/ether', i+4)
247         mac = string[ m+11 : m+11+17]
248         d[eth] = Device(eth, mac)
249         i = string.find('eth', m+11+17)
250     return d
251
252 class IpHandler(Restorable, ConfigWriter, TransactionalHandler):
253
254     _persistent_attrs = 'devices'
255
256     _restorable_defaults = dict(devices=get_devices())
257
258     _config_writer_files = ('device', 'ip_add', 'ip_del', 'ip_flush',
259                             'route_add', 'route_del', 'route_flush')
260     _config_writer_tpl_dir = path.join(path.dirname(__file__), 'templates')
261
262     def __init__(self, pickle_dir='.', config_dir='.'):
263         r"Initialize DhcpHandler object, see class documentation for details."
264         self._persistent_dir = pickle_dir
265         self._config_writer_cfg_dir = config_dir
266         self._config_build_templates()
267         self._restore()
268         self.addr = AddressHandler(self.devices)
269         self.route = RouteHandler(self.devices)
270         self.dev = DeviceHandler(self.devices)
271
272     def _write_config(self):
273         r"_write_config() -> None :: Execute all commands."
274         for device in self.devices.values():
275             print self._render_config('route_flush', dict(dev=device.name))
276             print self._render_config('ip_flush', dict(dev=device.name))
277             for address in device.addrs.values():
278                 print self._render_config('ip_add', dict(
279                         dev = device.name,
280                         addr = address.ip,
281                         prefix = address.prefix,
282                         broadcast = address.broadcast,
283                     )
284                 )
285             for route in device.routes:
286                 print self._render_config('route_add', dict(
287                         dev = device.name,
288                         net_addr = route.net_addr,
289                         prefix = route.prefix,
290                         gateway = route.gateway,
291                     )
292                 )
293
294
295 if __name__ == '__main__':
296
297     ip = IpHandler()
298     print '----------------------'
299     ip.dev.up('eth0')
300     ip.addr.add('eth0','192.168.0.23','24','192.168.255.255')
301     ip.addr.add('eth0','192.168.0.26','24')
302     ip.commit()
303     ip.route.add('eth0','192.168.0.0','24','192.168.0.1')
304     ip.route.add('eth0','192.168.0.5','24','192.168.0.1')
305     ip.commit()
306     ip.route.flush('eth0')
307     ip.commit()
308     ip.addr.delete('eth0','192.168.0.23')
309     ip.commit()
310
311
312
313