]> git.llucax.com Git - software/pymin.git/blob - pymin/services/ppp/__init__.py
Add support for service running status and restoring at startup.
[software/pymin.git] / pymin / services / ppp / __init__.py
1 # vim: set encoding=utf-8 et sw=4 sts=4 :
2
3 from os import path
4
5 from pymin.seqtools import Sequence
6 from pymin.dispatcher import Handler, handler, HandlerError
7 from pymin.services.util import Restorable, ConfigWriter, ReloadHandler, \
8                                 TransactionalHandler, DictSubHandler, call
9
10 __ALL__ = ('PppHandler',)
11
12 class ConnectionError(HandlerError, KeyError):
13     r"""
14     ConnectionError(hostname) -> ConnectionError instance
15
16     This is the base exception for all connection related errors.
17     """
18
19     def __init__(self, connection):
20         r"Initialize the object. See class documentation for more info."
21         self.message = u'Connection error: "%s"' % connection
22
23 class ConnectionNotFoundError(ConnectionError):
24     def __init__(self, connection):
25         r"Initialize the object. See class documentation for more info."
26         self.message = u'Connection not found error: "%s"' % connection
27
28 class Connection(Sequence):
29
30     def __init__(self, name, username, password, type, **kw):
31         self.name = name
32         self.username = username
33         self.password = password
34         self.type = type
35         self._running = False
36         if type == 'OE':
37             if not 'device' in kw:
38                 raise ConnectionError('Bad arguments for type=OE')
39             self.device = kw['device']
40         elif type == 'TUNNEL':
41             if not 'server' in kw:
42                 raise ConnectionError('Bad arguments for type=TUNNEL')
43             self.server = kw['server']
44             self.username = self.username.replace('\\','\\\\')
45         elif type == 'PPP':
46             if not 'device' in kw:
47                 raise ConnectionError('Bad arguments for type=PPP')
48             self.device = kw['device']
49         else:
50             raise ConnectionError('Bad arguments, unknown or unspecified type')
51
52     def as_tuple(self):
53         if self.type == 'TUNNEL':
54             return (self.name, self.username, self.password, self.type, self.server)
55         elif self.type == 'PPP' or self.type == 'OE':
56             return (self.name, self.username, self.password, self.type, self.device)
57
58     def update(self, device=None, username=None, password=None):
59         if device is not None:
60             self.device = device
61         if username is not None:
62             self.username = username
63         if password is not None:
64             self.password = password
65
66
67 class ConnectionHandler(DictSubHandler):
68
69     handler_help = u"Manages connections for the ppp service"
70
71     _cont_subhandler_attr = 'conns'
72     _cont_subhandler_class = Connection
73
74 class PppHandler(Restorable, ConfigWriter, ReloadHandler, TransactionalHandler):
75
76     handler_help = u"Manage ppp service"
77
78     _persistent_attrs = ['conns']
79
80     _restorable_defaults = dict(
81         conns  = dict(),
82     )
83
84     _config_writer_files = ('options.X','pap-secrets','chap-secrets','nameX')
85     _config_writer_tpl_dir = path.join(path.dirname(__file__), 'templates')
86
87     def __init__(self, pickle_dir='.', config_dir='.'):
88         r"Initialize Ppphandler object, see class documentation for details."
89         self._persistent_dir = pickle_dir
90         self._config_writer_cfg_dir = config_dir
91         self._config_build_templates()
92         self._restore()
93         for conn in self.conns.values():
94             if conn._running:
95                 conn._running = False
96                 self.start(conn.name)
97         self.conn = ConnectionHandler(self)
98
99     @handler(u'Start one or all the connections.')
100     def start(self, name=None):
101         names = [name]
102         if name is None:
103             names = self.conns.keys()
104         for name in names:
105             if name in self.conns:
106                 if not self.conns[name]._running:
107                     call(('pon', name))
108                     self.conns[name]._running = True
109                     self._dump_attr('conns')
110             else:
111                 raise ConnectionNotFoundError(name)
112
113     @handler(u'Stop one or all the connections.')
114     def stop(self, name=None):
115         names = [name]
116         if name is None:
117             names = self.conns.keys()
118         for name in names:
119             if name in self.conns:
120                 if self.conns[name]._running:
121                     call(('poff', name))
122                     self.conns[name]._running = False
123                     self._dump_attr('conns')
124             else:
125                 raise ConnectionNotFoundError(name)
126
127     @handler(u'Restart one or all the connections (even disconnected ones).')
128     def restart(self, name=None):
129         names = [name]
130         if name is None:
131             names = self.conns.keys()
132         for name in names:
133             self.stop(name)
134             self.start(name)
135
136     @handler(u'Restart only one or all the already running connections.')
137     def reload(self, name=None):
138         r"reload() -> None :: Reload the configuration of the service."
139         names = [name]
140         if name is None:
141             names = self.conns.keys()
142         for name in names:
143             if self.conns[name]._running:
144                 self.stop(name)
145                 self.start(name)
146
147     @handler(u'Tell if the service is running.')
148     def running(self, name=None):
149         r"reload() -> None :: Reload the configuration of the service."
150         if name is None:
151             return [c.name for c in self.conns.values() if c._running]
152         if name in self.conns:
153             return int(self.conns[name]._running)
154         else:
155             raise ConnectionNotFoundError(name)
156
157     def _write_config(self):
158         r"_write_config() -> None :: Generate all the configuration files."
159         #guardo los pass que van el pap-secrets
160         vars_pap = dict()
161         for conn in self.conns.values():
162             if conn.type == 'OE' or conn.type == 'PPP':
163                 vars_pap[conn.name] = conn
164         vars = dict(conns=vars_pap)
165         self._write_single_config('pap-secrets','pap-secrets',vars)
166         #guardo los pass que van el chap-secrets
167         vars_chap = dict()
168         for conn in self.conns.values():
169             if conn.type == 'TUNNEL' :
170                 vars_chap[conn.name] = conn
171         vars = dict(conns=vars_chap)
172         self._write_single_config('chap-secrets','chap-secrets',vars)
173         #guard las conns
174         for conn in self.conns.values():
175             vars = dict(conn=conn)
176             self._write_single_config('nameX',conn.name, vars)
177             self._write_single_config('options.X','options.' + conn.name, vars)
178
179
180 if __name__ == '__main__':
181     p = PppHandler()
182     p.conn.add('ppp_c','nico','nico',type='PPP',device='tty0')
183     p.conn.add('pppoe_c','fede','fede',type='OE',device='tty1')
184     p.conn.add('ppptunnel_c','dominio\luca','luca',type='TUNNEL',server='192.168.0.23')
185     p.commit()
186     print p.conn.list()
187     print p.conn.show()