1 # vim: set encoding=utf-8 et sw=4 sts=4 :
5 from pymin.seqtools import Sequence
6 from pymin.dispatcher import handler
7 from pymin.service.util import Restorable, ConfigWriter, \
8 TransactionalHandler, SubHandler, call, \
9 get_network_devices, ExecutionError, \
10 ContainerNotFoundError, ItemNotFoundError, \
11 ItemAlreadyExistsError
13 __all__ = ('QoSHandler')
16 class Class(Sequence):
18 def __init__(self, cid, rate=None):
24 return (self.cid, self.rate)
26 def __cmp__(self, other):
27 if self.cid == other.cid:
29 return cmp(id(self), id(other))
32 class ClassHandler(SubHandler):
34 def __init__(self, parent):
37 @handler('Adds a class : add <id> <device> <rate>')
38 def add(self, dev, cid, rate):
39 if not dev in self.parent.devices:
40 raise ContainerNotFoundError(dev)
43 self.parent.devices[dev].classes[cid] = Class(cid, rate)
45 raise ItemAlreadyExistsError(cid + ' -> ' + dev)
47 @handler(u'Deletes a class : delete <id> <device>')
48 def delete(self, dev, cid):
49 if not dev in self.parent.devices:
50 raise ContainerNotFoundError(dev)
53 del self.parent.devices[dev].classes[cid]
55 raise ItemNotFoundError(cid + ' -> ' + dev)
57 @handler(u'Lists classes : list <dev>')
60 k = self.parent.devices[dev].classes.items()
68 def __init__(self, ip):
74 def __cmp__(self, other):
75 if self.ip == other.ip:
77 return cmp(id(self), id(other))
80 class HostHandler(SubHandler):
82 def __init__(self, parent):
85 @handler('Adds a host to a class : add <device> <class id> <ip>')
86 def add(self, dev, cid, ip):
87 if not dev in self.parent.devices:
88 raise ContainerNotFoundError(dev)
90 if not cid in self.parent.devices[dev].classes:
91 raise ContainerNotFoundError(cid)
94 self.parent.devices[dev].classes[cid].hosts[ip] = Host(ip)
96 raise ItemAlreadyExistsError(h + ' -> ' + dev)
98 @handler(u'Lists hosts : list <dev> <class id>')
99 def list(self, dev, cid):
101 k = self.parent.devices[dev].classes[cid].hosts.keys()
107 class Device(Sequence):
109 def __init__(self, name, mac):
112 self.classes = dict()
115 return (self.name, self.mac)
118 class DeviceHandler(SubHandler):
120 handler_help = u"Manage network devices"
122 def __init__(self, parent):
123 # FIXME remove templates to execute commands
124 from mako.template import Template
126 template_dir = path.join(path.dirname(__file__), 'templates')
127 dev_fn = path.join(template_dir, 'device')
128 self.device_template = Template(filename=dev_fn)
130 @handler(u'Bring the device up')
132 if name in self.parent.devices:
134 call(self.device_template.render(dev=name, action='add'), shell=True)
135 except ExecutionError:
138 raise ItemNotFoundError(name)
140 @handler(u'Bring the device down')
141 def down(self, name):
142 if name in self.parent.devices:
144 call(self.device_template.render(dev=name, action='del'), shell=True)
145 except ExecutionError:
148 raise ItemNotFoundError(name)
150 @handler(u'List all devices')
152 return self.parent.devices.keys()
154 @handler(u'Get information about a device')
156 return self.parent.devices.items()
159 class QoSHandler(Restorable, ConfigWriter, TransactionalHandler):
161 handler_help = u"Manage QoS devices, classes and hosts"
163 _persistent_attrs = ('devices')
165 _restorable_defaults = dict(
166 devices=dict((dev, Device(dev, mac))
167 for (dev, mac) in get_network_devices().items())
170 _config_writer_files = ('device', 'class_add', 'class_del', 'host_add')
172 _config_writer_tpl_dir = path.join(path.dirname(__file__), 'templates')
174 def __init__(self, pickle_dir='.', config_dir='.'):
175 r"Initialize QoSHandler object, see class documentation for details."
176 self._persistent_dir = pickle_dir
177 self._config_writer_cfg_dir = config_dir
178 self._config_build_templates()
181 self.dev = DeviceHandler(self)
182 self.cls = ClassHandler(self)
183 self.host = HostHandler(self)
185 def _write_config(self):
186 r"_write_config() -> None :: Execute all commands."
187 for device in self.devices.values():
189 call(self._render_config('device', dict(dev=device.name, action='del')), shell=True)
190 except ExecutionError:
194 call(self._render_config('device', dict(dev=device.name, action='add')), shell=True)
195 except ExecutionError:
198 for cls in device.classes.values():
200 call(self._render_config('class_add', dict(
206 except ExecutionError:
209 for host in cls.hosts.values():
211 call(self._render_config('host_add', dict(
217 except ExecutionError:
220 def handle_timer(self):
221 self.refresh_devices()
223 def refresh_devices(self):
224 devices = get_network_devices()
225 #add not registered devices
226 for k, v in devices.items():
227 if k not in self.devices:
228 self.devices[k] = Device(k, v)
230 for k in self.devices.keys():
235 if __name__ == '__main__':
238 print '----------------------'