Commit 17888275 by Bach Dániel

add netns support

parent d59f5827
from celery import Celery, task from celery import Celery, task
from os import getenv from os import getenv
import subprocess
import re import re
import json import json
import socket
from ovs import Switch from ovs import Switch
IRC_CHANNEL = getenv('IRC_CHANNEL', '/home/cloud/irc/irc.atw.hu/#ik/in') IRC_CHANNEL = getenv('IRC_CHANNEL', '/home/cloud/irc/irc.atw.hu/#ik/in')
DHCP_LOGFILE = getenv('DHCP_LOGFILE', '/var/log/syslog') DHCP_LOGFILE = getenv('DHCP_LOGFILE', '/var/log/syslog')
VLAN_CONF = getenv('VLAN_CONF', 'vlan.conf') VLAN_CONF = getenv('VLAN_CONF', 'vlan.conf')
FIREWALL_CONF = getenv('FIREWALL_CONF', 'firewall.conf') FIREWALL_CONF = getenv('FIREWALL_CONF', 'firewall.conf')
from utils import NETNS, ns_exec
celery = Celery('tasks', backend='amqp', ) celery = Celery('tasks', backend='amqp', )
celery.conf.update(CELERY_TASK_RESULT_EXPIRES=300, celery.conf.update(CELERY_TASK_RESULT_EXPIRES=300,
...@@ -21,16 +19,14 @@ celery.conf.update(CELERY_TASK_RESULT_EXPIRES=300, ...@@ -21,16 +19,14 @@ celery.conf.update(CELERY_TASK_RESULT_EXPIRES=300,
@task(name="firewall.reload_firewall") @task(name="firewall.reload_firewall")
def reload_firewall(data4, data6, onstart=False): def reload_firewall(data4, data6, onstart=False):
print "fw" print "fw"
process = subprocess.Popen(['/usr/bin/sudo',
'/sbin/ip6tables-restore', '-c'], ns_exec(NETNS, ('/sbin/ip6tables-restore', '-c'),
shell=False, stdin=subprocess.PIPE) '\n'.join(data6['filter']) + '\n')
process.communicate("\n".join(data6['filter']) + "\n")
ns_exec(NETNS, ('/sbin/iptables-restore', '-c'),
process = subprocess.Popen(['/usr/bin/sudo', ('\n'.join(data4['filter']) + '\n' +
'/sbin/iptables-restore', '-c'], '\n'.join(data4['nat']) + '\n'))
shell=False, stdin=subprocess.PIPE)
process.communicate("\n".join(data4['filter'])
+ "\n" + "\n".join(data4['nat']) + "\n")
if onstart is False: if onstart is False:
with open(FIREWALL_CONF, 'w') as f: with open(FIREWALL_CONF, 'w') as f:
json.dump([data4, data6], f) json.dump([data4, data6], f)
...@@ -39,22 +35,24 @@ def reload_firewall(data4, data6, onstart=False): ...@@ -39,22 +35,24 @@ def reload_firewall(data4, data6, onstart=False):
@task(name="firewall.reload_firewall_vlan") @task(name="firewall.reload_firewall_vlan")
def reload_firewall_vlan(data, onstart=False): def reload_firewall_vlan(data, onstart=False):
print "fw vlan" print "fw vlan"
# print data
br = Switch('firewall') br = Switch('firewall')
br.migrate(data) br.migrate(data)
# print br.list_ports()
if onstart is False: if onstart is False:
with open(VLAN_CONF, 'w') as f: with open(VLAN_CONF, 'w') as f:
json.dump(data, f) json.dump(data, f)
subprocess.call("/sbin/ip ro add default via 10.7.255.254", shell=True) GATEWAY = getenv('GATEWAY', '152.66.243.254')
try:
ns_exec(NETNS, ('/sbin/ip', 'ro', 'add', 'default', 'via', GATEWAY))
except:
pass
@task(name="firewall.reload_dhcp") @task(name="firewall.reload_dhcp")
def reload_dhcp(data): def reload_dhcp(data):
print "dhcp" print "dhcp"
with open('/tools/dhcp3/dhcpd.conf.generated', 'w') as f: with open('/tools/dhcp3/dhcpd.conf.generated', 'w') as f:
f.write("\n".join(data) + "\n") f.write("\n".join(data) + "\n")
subprocess.call(['sudo', '/etc/init.d/isc-dhcp-server', ns_exec(NETNS, ('/etc/init.d/isc-dhcp-server', 'restart'))
'restart'], shell=False)
def ipset_save(data): def ipset_save(data):
...@@ -63,9 +61,8 @@ def ipset_save(data): ...@@ -63,9 +61,8 @@ def ipset_save(data):
data_new = [x['ipv4'] for x in data] data_new = [x['ipv4'] for x in data]
data_old = [] data_old = []
p = subprocess.Popen(['/usr/bin/sudo', '/usr/sbin/ipset', 'save', lines = ns_exec(NETNS, ('/usr/sbin/ipset', 'save', 'blacklist'))
'blacklist'], shell=False, stdout=subprocess.PIPE) for line in lines.splitlines():
for line in p.stdout:
x = r.match(line.rstrip()) x = r.match(line.rstrip())
if x: if x:
data_old.append(x.group(1)) data_old.append(x.group(1))
...@@ -73,7 +70,7 @@ def ipset_save(data): ...@@ -73,7 +70,7 @@ def ipset_save(data):
l_add = list(set(data_new).difference(set(data_old))) l_add = list(set(data_new).difference(set(data_old)))
l_del = list(set(data_old).difference(set(data_new))) l_del = list(set(data_old).difference(set(data_new)))
return (l_add, l_del, ) return (l_add, l_del)
def ipset_restore(l_add, l_del): def ipset_restore(l_add, l_del):
...@@ -83,29 +80,8 @@ def ipset_restore(l_add, l_del): ...@@ -83,29 +80,8 @@ def ipset_restore(l_add, l_del):
ipset = ipset + ['add blacklist %s' % x for x in l_add] ipset = ipset + ['add blacklist %s' % x for x in l_add]
ipset = ipset + ['del blacklist %s' % x for x in l_del] ipset = ipset + ['del blacklist %s' % x for x in l_del]
print "\n".join(ipset) + "\n" ns_exec(NETNS, ('/usr/sbin/ipset', 'restore', '-exist'),
'\n'.join(ipset) + '\n')
p = subprocess.Popen(['/usr/bin/sudo', '/usr/sbin/ipset', 'restore',
'-exist'], shell=False, stdin=subprocess.PIPE)
p.communicate("\n".join(ipset) + "\n")
def irc_message(data, l_add):
try:
with open(IRC_CHANNEL, 'w+') as f:
for x in data:
try:
hostname = socket.gethostbyaddr(x['ipv4'])[0]
except:
hostname = x['ipv4']
if x['ipv4'] in l_add:
f.write('%(ip)s(%(hostname)s) kibachva %(reason)s '
'miatt\n' % {'ip': x['ipv4'],
'reason': x['reason'],
'hostname': hostname})
except:
print "nem sikerult mircre irni"
# raise
@task(name="firewall.reload_blacklist") @task(name="firewall.reload_blacklist")
...@@ -114,7 +90,6 @@ def reload_blacklist(data): ...@@ -114,7 +90,6 @@ def reload_blacklist(data):
l_add, l_del = ipset_save(data) l_add, l_del = ipset_save(data)
ipset_restore(l_add, l_del) ipset_restore(l_add, l_del)
irc_message(data, l_add)
# 2013-06-26 12:16:59 DHCPACK on 10.4.0.14 to 5c:b5:24:e6:5c:81 # 2013-06-26 12:16:59 DHCPACK on 10.4.0.14 to 5c:b5:24:e6:5c:81
...@@ -131,8 +106,6 @@ dhcp_ack_re = re.compile(r'\S DHCPACK on (?P<ip>[0-9.]+) to ' ...@@ -131,8 +106,6 @@ dhcp_ack_re = re.compile(r'\S DHCPACK on (?P<ip>[0-9.]+) to '
dhcp_no_free_re = re.compile(r'\S DHCPDISCOVER ' dhcp_no_free_re = re.compile(r'\S DHCPDISCOVER '
r'from (?P<mac>[a-zA-Z0-9:]+) ' r'from (?P<mac>[a-zA-Z0-9:]+) '
r'via (?P<interface>[a-zA-Z0-9]+):') r'via (?P<interface>[a-zA-Z0-9]+):')
# r'.* no free leases')
# r'(\((?P<hostnamename>[^)]+)\) )?'
@task(name="firewall.get_dhcp_clients") @task(name="firewall.get_dhcp_clients")
...@@ -152,21 +125,26 @@ def get_dhcp_clients(): ...@@ -152,21 +125,26 @@ def get_dhcp_clients():
ip = m.get('ip', None) ip = m.get('ip', None)
hostname = m.get('hostname', None) hostname = m.get('hostname', None)
interface = m.get('interface', None) interface = m.get('interface', None)
clients[mac] = {'ip': ip, 'hostname': hostname, 'interface': interface} clients[mac] = {'ip': ip, 'hostname': hostname,
'interface': interface}
return clients return clients
def start_firewall(): def start_firewall():
try: try:
subprocess.call('sudo ipset create blacklist hash:ip family ' ns_exec(NETNS, ('/usr/sbin/ipset', 'create', 'blacklist',
'inet hashsize 4096 maxelem 65536 2>/dev/null', 'hash:ip', 'family', 'inet', 'hashsize',
shell=True) '4096', 'maxelem', '65536'))
except:
pass
try:
with open(FIREWALL_CONF, 'r') as f: with open(FIREWALL_CONF, 'r') as f:
data4, data6 = json.load(f) data4, data6 = json.load(f)
reload_firewall(data4, data6, True) reload_firewall(data4, data6, True)
except: except:
print 'nemsikerult:(' print 'nemsikerult:('
raise
def start_networking(): def start_networking():
...@@ -176,6 +154,7 @@ def start_networking(): ...@@ -176,6 +154,7 @@ def start_networking():
reload_firewall_vlan(data, True) reload_firewall_vlan(data, True)
except: except:
print 'nemsikerult:(' print 'nemsikerult:('
raise
def main(): def main():
......
import subprocess
from netaddr import IPNetwork from netaddr import IPNetwork
import logging import logging
from utils import NETNS, sudo, ns_exec
class IPDevice: class IPDevice:
def __init__(self, devname): def __init__(self, devname):
self.devname = devname self.devname = devname
def _run(self, *args): def _run(self, *args):
args = ('sudo', 'ip', 'addr', ) + args args = ('/sbin/ip', 'addr', ) + args
logging.debug('subprocess_check_output: {}'.format(args)) return ns_exec(NETNS, args)
return subprocess.check_output(args)
def show(self): def show(self):
retval = [] retval = []
...@@ -28,6 +28,9 @@ class IPDevice: ...@@ -28,6 +28,9 @@ class IPDevice:
def add(self, address): def add(self, address):
self._run('add', str(address), 'dev', self.devname) self._run('add', str(address), 'dev', self.devname)
def up(self):
ns_exec(NETNS, ('/sbin/ip', 'link', 'set', 'up', self.devname))
def migrate(self, new_addresses): def migrate(self, new_addresses):
old_addresses = [str(x) for x in self.show()] old_addresses = [str(x) for x in self.show()]
new_addresses = [str(x) for x in new_addresses] new_addresses = [str(x) for x in new_addresses]
...@@ -53,8 +56,12 @@ class Switch: ...@@ -53,8 +56,12 @@ class Switch:
pass pass
def _run(self, *args): def _run(self, *args):
args = ('sudo', 'ovs-vsctl', ) + args args = ('ovs-vsctl', ) + args
return subprocess.check_output(args) return sudo(args)
def _setns(self, dev):
args = ('/sbin/ip', 'link', 'set', dev, 'netns', NETNS)
return sudo(args)
def list_ports(self): def list_ports(self):
retval = {} retval = {}
...@@ -88,22 +95,17 @@ class Switch: ...@@ -88,22 +95,17 @@ class Switch:
params = ['add-bond', self.brname, params = ['add-bond', self.brname,
name] + interfaces + ['tag=%d' % int(tag)] name] + interfaces + ['tag=%d' % int(tag)]
else: else:
params = ['add-port', self.brname, name, 'tag=%d' % int(tag)] params = ['add-port', self.brname, name]
if tag is not None:
params = params + ['tag=%d' % int(tag)]
if internal: if internal:
params = params + ['--', 'set', 'Interface', interfaces[0], params = params + ['--', 'set', 'Interface', interfaces[0],
'type=internal'] 'type=internal']
if trunks is not None and len(trunks) > 0: if trunks is not None and len(trunks) > 0:
params.append('trunks=%s' % trunks) params.append('trunks=%s' % trunks)
self._run(*params) self._run(*params)
self.ip_link_up(interfaces) if not internal:
self._setns(name)
def ip_link_up(self, interfaces):
for interface in interfaces:
try:
subprocess.check_output(['sudo', 'ip', 'link',
'set', 'up', interface])
except:
pass
def delete_port(self, name): def delete_port(self, name):
self._run('del-port', self.brname, name) self._run('del-port', self.brname, name)
...@@ -139,7 +141,7 @@ class Switch: ...@@ -139,7 +141,7 @@ class Switch:
self.delete_port(i) self.delete_port(i)
for i in add: for i in add:
internal = new_ports[i].get('type', '') == 'internal' internal = new_ports[i].get('type', '') == 'internal'
tag = new_ports[i]['tag'] tag = new_ports[i].get('tag', None)
trunks = new_ports[i].get('trunks', []) trunks = new_ports[i].get('trunks', [])
interfaces = new_ports[i]['interfaces'] interfaces = new_ports[i]['interfaces']
self.add_port(i, interfaces, tag, trunks, internal) self.add_port(i, interfaces, tag, trunks, internal)
...@@ -150,5 +152,7 @@ class Switch: ...@@ -150,5 +152,7 @@ class Switch:
interface.migrate([IPNetwork(x) interface.migrate([IPNetwork(x)
for x in data.get('addresses', []) for x in data.get('addresses', [])
if x != 'None']) if x != 'None'])
if new_ports[i].get('type', '') == 'internal':
interface.up()
except: except:
pass pass
from os import getenv, devnull
import subprocess as sp
import logging
logger = logging.getLogger(__name__)
logger.setLevel(logging.DEBUG)
NETNS = getenv('NETNS', 'fw')
def sudo(args, stdin=None):
FNULL = open(devnull, 'w')
args = ('/usr/bin/sudo', ) + args
logger.debug('EXEC {}'.format(' '.join(args)))
if isinstance(stdin, basestring):
proc = sp.Popen(args, stdin=sp.PIPE, stderr=FNULL)
return proc.communicate(stdin)
else:
return sp.check_output(args, stderr=FNULL)
def ns_exec(netns, args, stdin=None):
return sudo(('/sbin/ip', 'netns', 'exec',
NETNS) + args, stdin)
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment