config_path = join(base_path, 'config')
class Root(Handler):
- ip = IpHandler(
- pickle_dir = join(pickle_path, 'ip'),
- config_dir = join(config_path, 'ip'))
+
firewall = FirewallHandler(
pickle_dir = join(pickle_path, 'firewall'),
- config_dir = join(config_path, 'firewall'))
+ config_dir = '/tmp')
+
nat = NatHandler(pickle_dir = join(pickle_path, 'nat'))
+
+ ppp = PppHandler(
+ pickle_dir = join(pickle_path, 'ppp'),
+ config_dir = {
+ 'pap-secrets': '/etc/ppp',
+ 'chap-secrets': '/etc/ppp',
+ 'options.X': '/etc/ppp',
+ 'nameX': '/etc/ppp/peers',
+ })
+
+ ip = IpHandler(
+ pickle_dir = join(pickle_path, 'ip'),
+ config_dir = join(config_path, 'ip'))
+
dns = DnsHandler(
pickle_dir = join(pickle_path, 'dns'),
config_dir = {
- 'named.conf': join(config_path, 'dns'),
- 'zoneX.zone': join(config_path, 'dns', 'zones'),
+ 'named.conf': '/etc',
+ 'zoneX.zone': '/var/lib/named',
})
+
dhcp = DhcpHandler(
pickle_dir = join(pickle_path, 'dhcp'),
- config_dir = join(config_path, 'dhcp'))
- ppp = PppHandler(
- pickle_dir = join(pickle_path, 'ppp'),
- config_dir = join(config_path, 'ppp'))
- vrrp = VrrpHandler(
- pickle_dir = join(pickle_path, 'vrrp'),
- config_dir = join(config_path, 'vrrp'))
+ config_dir = '/etc')
+
proxy = ProxyHandler(
pickle_dir = join(pickle_path, 'proxy'),
config_dir = join(config_path, 'proxy'))
+
+ vrrp = VrrpHandler(
+ pickle_dir = join(pickle_path, 'vrrp'),
+ config_dir = join(config_path, 'vrrp'),
+ pid_dir = '/var/run')
+
qos = QoSHandler(
pickle_dir = join(pickle_path, 'qos'),
config_dir = join(config_path, 'qos'))
# If we use a timer, we set up the signal
if self.timer is not None:
signal.signal(signal.SIGALRM, alarm_handler)
+ self.handle_timer()
signal.alarm(self.timer)
while True:
try:
from pymin.services.util import Restorable, ConfigWriter, InitdHandler, \
TransactionalHandler, SubHandler, call, \
get_network_devices, ListComposedSubHandler, \
- DictComposedSubHandler
+ DictComposedSubHandler, Device, Address, ExecutionError
__ALL__ = ('IpHandler',)
_comp_subhandler_attr = 'routes'
_comp_subhandler_class = Route
-class Address(Sequence):
- def __init__(self, ip, netmask, broadcast=None):
- self.ip = ip
- self.netmask = netmask
- self.broadcast = broadcast
- def update(self, netmask=None, broadcast=None):
- if netmask is not None: self.netmask = netmask
- if broadcast is not None: self.broadcast = broadcast
- def as_tuple(self):
- return (self.ip, self.netmask, self.broadcast)
class AddressHandler(DictComposedSubHandler):
handler_help = u"Manage IP addresses"
_comp_subhandler_attr = 'addrs'
_comp_subhandler_class = Address
-class Device(Sequence):
- def __init__(self, name, mac):
- self.name = name
- self.mac = mac
- self.addrs = dict()
- self.routes = list()
- def as_tuple(self):
- return (self.name, self.mac)
class DeviceHandler(SubHandler):
_persistent_attrs = ('devices','hops')
_restorable_defaults = dict(
- devices=dict((dev, Device(dev, mac))
- for (dev, mac) in get_network_devices().items()),
+ devices=get_network_devices(),
hops = list()
)
def _write_config(self):
r"_write_config() -> None :: Execute all commands."
for device in self.devices.values():
- call(self._render_config('route_flush', dict(dev=device.name)), shell=True)
- call(self._render_config('ip_flush', dict(dev=device.name)), shell=True)
+ try:
+ call(self._render_config('route_flush', dict(dev=device.name)), shell=True)
+ except ExecutionError, e:
+ print e
+ try:
+ call(self._render_config('ip_flush', dict(dev=device.name)), shell=True)
+ except ExecutionError, e:
+ print e
for address in device.addrs.values():
broadcast = address.broadcast
if broadcast is None:
broadcast = '+'
- call(self._render_config('ip_add', dict(
+ try:
+ call(self._render_config('ip_add', dict(
dev = device.name,
addr = address.ip,
netmask = address.netmask,
+ peer = address.peer,
broadcast = broadcast,
- )
- ), shell=True)
+ )
+ ), shell=True)
+ except ExecutionError, e:
+ print e
for route in device.routes:
- call(self._render_config('route_add', dict(
- dev = device.name,
- net_addr = route.net_addr,
- prefix = route.prefix,
- gateway = route.gateway,
- )
- ), shell=True)
-
+ try:
+ call(self._render_config('route_add', dict(
+ dev = device.name,
+ net_addr = route.net_addr,
+ prefix = route.prefix,
+ gateway = route.gateway,
+ )
+ ), shell=True)
+ except ExecutionError, e:
+ print e
if self.hops:
- call('ip route del default', shell=True)
- call(self._render_config('hop', dict(
- hops = self.hops,
- )
- ), shell=True)
+ try:
+ call('ip route del default', shell=True)
+ except ExecutionError, e:
+ print e
+ try:
+ call(self._render_config('hop', dict(
+ hops = self.hops,
+ )
+ ), shell=True)
+ except ExecutionError, e:
+ print e
def handle_timer(self):
#add not registered devices
for k,v in devices.items():
if k not in self.devices:
- self.devices[k] = Device(k,v)
+ self.devices[k] = v
#delete dead devices
for k in self.devices.keys():
if k not in devices:
-ip addr add dev ${dev} ${addr}/${netmask} broadcast ${broadcast}
\ No newline at end of file
+%if peer is None:
+ip addr add dev ${dev} ${addr}/${netmask} broadcast ${broadcast}
+%else:
+ip addr add dev ${dev} ${addr} peer ${peer}
+%endif
# vim: set encoding=utf-8 et sw=4 sts=4 :
import os
+import subprocess
from os import path
from signal import SIGTERM
for name in names:
if name in self.conns:
if self.conns[name]._running:
- call(('poff', name))
if path.exists('/var/run/ppp-' + name + '.pid'):
pid = file('/var/run/ppp-' + name + '.pid').readline()
try:
else:
raise ConnectionNotFoundError(name)
+ def handle_timer(self):
+ for c in self.conns.values():
+ p = subprocess.Popen(('pgrep', '-f', 'pppd call ' + c.name),
+ stdout=subprocess.PIPE)
+ pid = p.communicate()[0]
+ if p.wait() == 0 and len(pid) > 0:
+ c._running = True
+ else:
+ c._running = False
+
def _write_config(self):
r"_write_config() -> None :: Generate all the configuration files."
#guardo los pass que van el pap-secrets
updetach
% if conn.type != 'TUNNEL':
-name ${conn.username}
+user ${conn.username}
file /etc/ppp/options.${conn.name}
ipparam ${conn.name}
# pppoe has a lower mtu/mru
# this is recommended
novjccomp
noccp
+noauth
% else:
pty "pptp ${conn.server} --nolaunchpppd"
name ${conn.username}
from pymin.dispatcher import Handler, handler, HandlerError, \
CommandNotFoundError
+from pymin.seqtools import Sequence
-#DEBUG = False
-DEBUG = True
+DEBUG = False
+#DEBUG = True
__ALL__ = ('Error', 'ReturnNot0Error', 'ExecutionError', 'ItemError',
'ItemAlreadyExistsError', 'ItemNotFoundError', 'ContainerError',
'Persistent', 'Restorable', 'ConfigWriter', 'ServiceHandler',
'RestartHandler', 'ReloadHandler', 'InitdHandler', 'SubHandler',
'DictSubHandler', 'ListSubHandler', 'ComposedSubHandler',
- 'ListComposedSubHandler', 'DictComposedSubHandler')
+ 'ListComposedSubHandler', 'DictComposedSubHandler', 'Device','Address')
class Error(HandlerError):
r"""
r"Initialize the object. See class documentation for more info."
self.message = u'Container not found: "%s"' % key
+class Address(Sequence):
+ def __init__(self, ip, netmask, broadcast=None, peer=None):
+ self.ip = ip
+ self.netmask = netmask
+ self.broadcast = broadcast
+ self.peer = peer
+ def update(self, netmask=None, broadcast=None):
+ if netmask is not None: self.netmask = netmask
+ if broadcast is not None: self.broadcast = broadcast
+ def as_tuple(self):
+ return (self.ip, self.netmask, self.broadcast, self.peer)
+
+
+class Device(Sequence):
+ def __init__(self, name, mac, ppp):
+ self.name = name
+ self.mac = mac
+ self.ppp = ppp
+ self.addrs = dict()
+ self.routes = list()
+ def as_tuple(self):
+ return (self.name, self.mac, self.addrs)
+
+
def get_network_devices():
p = subprocess.Popen(('ip', '-o', 'link'), stdout=subprocess.PIPE,
if dev.find('link/ether') != -1:
i = dev.find('link/ether')
mac = dev[i+11 : i+11+17]
- i = dev.find(':',2)
- name = dev[3: i]
- d[name] = mac
+ i = dev.find(':')
+ j = dev.find(':', i+1)
+ name = dev[i+2: j]
+ d[name] = Device(name,mac,False)
elif dev.find('link/ppp') != -1:
i = dev.find('link/ppp')
mac = '00:00:00:00:00:00'
- i = dev.find(':',2)
- name = dev[3 : i]
- d[name] = mac
+ i = dev.find(':')
+ j = dev.find(':', i+1)
+ name = dev[i+2 : j]
+ d[name] = Device(name,mac,True)
+ #since the device is ppp, get the address and peer
+ try:
+ p = subprocess.Popen(('ip', '-o', 'addr', 'show', name), stdout=subprocess.PIPE,
+ close_fds=True, stderr=subprocess.PIPE)
+ string = p.stdout.read()
+ p.wait()
+ addrs = string.splitlines()
+ inet = addrs[1].find('inet')
+ peer = addrs[1].find('peer')
+ bar = addrs[1].find('/')
+ from_addr = addrs[1][inet+5 : peer-1]
+ to_addr = addrs[1][peer+5 : bar]
+ d[name].addrs[from_addr] = Address(from_addr,24, peer=to_addr)
+ except IndexError:
+ pass
+
return d
+
+def get_peers():
+ p = subprocess.Popen(('ip', '-o', 'addr'), stdout=subprocess.PIPE,
+ close_fds=True)
def call(command, stdin=subprocess.PIPE, stdout=subprocess.PIPE,
stderr=subprocess.PIPE, close_fds=True, universal_newlines=True,
print 'Executing command:', command
return
try:
+ print 'Executing command:', command
r = subprocess.call(command, stdin=stdin, stdout=stdout, stderr=stderr,
universal_newlines=universal_newlines,
close_fds=close_fds, **kw)
action)
ServiceHandler.__init__(self, **actions)
+ def handle_timer(self):
+ p = subprocess.Popen(('pgrep', '-f', self._initd_name),
+ stdout=subprocess.PIPE)
+ pid = p.communicate()[0]
+ if p.wait() == 0 and len(pid) > 0:
+ c._service_running = True
+ else:
+ c._service_running = False
+
class TransactionalHandler(Handler):
r"""Handle command transactions providing a commit and rollback commands.
if __name__ == '__main__':
+ import sys
+
# Execution tests
class STestHandler1(ServiceHandler):
_service_start = ('service', 'start')
os.rmdir('templates')
print
+ print get_network_devices()
+
--- /dev/null
+# vim: set encoding=utf-8 et sw=4 sts=4 :
+
+import os
+from os import path
+
+from pymin.seqtools import Sequence
+from pymin.dispatcher import Handler, handler, HandlerError
+from pymin.services.util import Restorable, ConfigWriter, InitdHandler, \
+ TransactionalHandler, DictSubHandler, DictComposedSubHandler, call, ExecutionError
+
+
+class Host(Sequence):
+ def __init__(self, vpn_src, ip, vpn_src_net, key):
+ self.name = vpn_src
+ self.ip = ip
+ self.src_net = vpn_src_net
+ self.pub_key = key
+ self.dele = False
+
+ def as_tuple(self):
+ return(self.name, self.ip, self.src_net, self.pub_key)
+
+class HostHandler(DictComposedSubHandler):
+
+ handler_help = u"Manage hosts for a vpn"
+ _comp_subhandler_cont = 'vpns'
+ _comp_subhandler_attr = 'hosts'
+ _comp_subhandler_class = Host
+
+ @handler('usage: add <vpn_src> <ip> <vpn_src_net> <key>')
+ def delete(self, vpn_src, host):
+ DictComposedSubHandler.delete(self, vpn_src, host)
+ if vpn_src in parent.vpns:
+ if host in parent.vpns[vpn_src].hosts:
+ parent.vpns[vpn_src].hosts[host].dele = True
+
+
+class Vpn(Sequence):
+ def __init__(self, vpn_src, vpn_dst, vpn_src_ip, vpn_src_mask, pub_key, priv_key):
+ self.vpn_src = vpn_src
+ self.vpn_dst = vpn_dst
+ self.vpn_src_ip = vpn_src_ip
+ self.vpn_src_mask = vpn_src_mask
+ self.pub_key = pub_key
+ self.priv_key = priv_key
+ self.hosts = dict()
+ self.dele = False
+
+ def as_tuple(self):
+ return(self.vpn_src, self.vpn_dst, self.vpn_src_ip, self.vpn_src_mask, self.pub_key, self.priv_key)
+
+ def update(self, vpn_dst=None, vpn_src_ip=None, vpn_src_mask=None):
+ if vpn_dst is not None:
+ self.vpn_dst = vpn_dst
+ if vpn_src_ip is not None:
+ self.vpn_src_ip = vpn_src_ip
+ if vpn_src_mask is not None:
+ self.vpn_src_mask = vpn_src_mask
+
+
+class VpnHandler(Restorable, ConfigWriter,
+ TransactionalHandler, DictSubHandler):
+
+ handler_help = u"Manage vpn service"
+
+ _cont_subhandler_attr = 'vpns'
+ _cont_subhandler_class = Vpn
+
+ _persistent_attrs = ('vpns','hosts')
+
+ _restorable_defaults = dict(
+ vpns = dict(),
+ hosts = dict(),
+ )
+
+ _config_writer_files = ('tinc.conf','tinc-up','host')
+ _config_writer_tpl_dir = path.join(path.dirname(__file__), 'templates')
+
+ def __init__(self, pickle_dir='.', config_dir='/etc/tinc'):
+ DictSubHandler.__init__(self,self)
+ self._config_writer_cfg_dir = config_dir
+ self._persistent_dir = pickle_dir
+ self._config_build_templates()
+ self._restore()
+ self.host = HostHandler(self)
+
+ @handler('usage : add <vpn_name> <vpn_dst> <vpn_src_ip> <vpn_src_mask>')
+ def add(self, vpn_src, vpn_dst, vpn_src_ip, vpn_src_mask):
+ if not vpn_src in self.vpns:
+ DictSubHandler.add(self, vpn_src, vpn_dst, vpn_src_ip, vpn_src_mask, None, None)
+ elif vpn_src in self.vpns:
+ if self.vpns[vpn_src].dele :
+ self.vpns[vpn_src] = False
+
+ @handler('usage : delete <vpn_name>')
+ def delete(self, vpn_src):
+ if vpn_src in self.vpns:
+ self.vpns[vpn_src].dele = True;
+
+
+ @handler('usage: start <vpn_name>')
+ def start(self, vpn_src):
+ if vpn_src in self.vpns:
+ call(('tincd','--net=',vpn_src))
+
+ @handler('usage: stop <vpn_name>')
+ def stop(self, vpn_src):
+ if vpn_src in self.vpns:
+ if path.exists('/var/lib/run/tincd.' + vpn_src + '.pid'):
+ pid = file('/var/lib/run/tincd.' + vpn_src + '.pid').readline()
+ try:
+ os.kill(int(pid.strip()), SIGTERM)
+ except OSError:
+ pass # XXX report error?
+
+ def _write_config(self):
+ for v in self.vpns.values():
+ #chek whether it's been created or not.
+ if not v.dele:
+ if v.pub_key is None :
+ try:
+ print 'douugh'
+ #first create the directory for the vpn
+ call(('mkdir','-p', path.join(self._config_writer_cfg_dir, v.vpn_src ,'hosts')))
+ #this command should generate 2 files inside the vpn
+ #dir, one rsa_key.priv and one rsa_key.pub
+ #for some reason debian does not work like this
+ call(('tincd','-n', v.vpn_src,'-K','<','/dev/null'))
+ #open the created files and load the keys
+ f = file(path.join(self._config_writer_cfg_dir, v.vpn_src , 'rsa_key.priv'), 'r')
+ priv = f.read()
+ f.close()
+ f = file(path.join(self._config_writer_cfg_dir, v.vpn_src ,'rsa_key.pub'), 'r')
+ pub = f.read()
+ f.close()
+ v.pub_key = pub
+ v.priv_key = priv
+ except ExecutionError, e:
+ print e
+
+ vars = dict(
+ vpn = v,
+ )
+ self._write_single_config('tinc.conf',path.join(v.vpn_src,'tinc.conf'),vars)
+ self._write_single_config('tinc-up',path.join(v.vpn_src,'tinc-up'),vars)
+ for h in v.hosts.values():
+ if not h.dele:
+ vars = dict(
+ host = h,
+ )
+ self._write_single_config('host',path.join(v.vpn_src,'hosts',h.name),vars)
+ else:
+ try:
+ call(('rm','-f', path.join(v.vpn_src,'hosts',h.name)))
+ del v.hosts[h.name]
+ except ExecutionError, e:
+ print e
+ else:
+ #delete the vpn root at tinc dir
+ if path.exists('/etc/tinc/' + v.vpn_src):
+ self.stop(v.vpn_src)
+ call(('rm','-rf','/etc/tinc/' + v.vpn_src))
+ del self.vpns[v.vpn_src]
+
+
+if __name__ == '__main__':
+ v = VpnHandler()
+ v.add('test','127.0.0.1','192.168.0.1','255.255.255.0')
+ #v.host.add('test', 'sarasa' ,'127.0.0.1', '205.25.36.36','kjdhfkbdskljvkjblkbjeslkjbvkljbselvslberjhbvslbevlhb')
+ v.delete('test')
+ v.commit()
--- /dev/null
+Address = ${host.ip}
+Subnet = ${host.src_net}
+${host.pub_key}
--- /dev/null
+ifconfig $INTERFACE ${vpn.vpn_src_ip} netmask ${vpn.vpn_src_mask}
--- /dev/null
+Name = ${vpn.vpn_src}
+Device = /dev/net/tun
+PrivateKeyFile = /etc/tinc/${vpn.vpn_src}/rsa_key.priv
+ConnectTo = ${vpn.vpn_dst}