diff --git a/systemvm/patches/debian/config/opt/cloud/bin/configure.py b/systemvm/patches/debian/config/opt/cloud/bin/configure.py index ab134fcfca7..f5ae830f809 100755 --- a/systemvm/patches/debian/config/opt/cloud/bin/configure.py +++ b/systemvm/patches/debian/config/opt/cloud/bin/configure.py @@ -731,34 +731,34 @@ class CsForwardingRules(CsDataBag): #return the VR guest interface ip def getGuestIp(self): - ipr = [] + interfaces = [] ipAddr = None - for ip in self.config.address().get_ips(): - if ip.is_guest(): - ipr.append(ip) - if len(ipr) > 0: - ipAddr = sorted(ipr)[-1] + for interface in self.config.address().get_interfaces(): + if interface.is_guest(): + interfaces.append(interface) + if len(interfaces) > 0: + ipAddr = sorted(interfaces)[-1] if ipAddr: return ipAddr.get_ip() return None def getDeviceByIp(self, ipa): - for ip in self.config.address().get_ips(): - if ip.ip_in_subnet(ipa): - return ip.get_device() + for interface in self.config.address().get_interfaces(): + if interface.ip_in_subnet(ipa): + return interface.get_device() return None def getNetworkByIp(self, ipa): - for ip in self.config.address().get_ips(): - if ip.ip_in_subnet(ipa): - return ip.get_network() + for interface in self.config.address().get_interfaces(): + if interface.ip_in_subnet(ipa): + return interface.get_network() return None def getGatewayByIp(self, ipa): - for ip in self.config.address().get_ips(): - if ip.ip_in_subnet(ipa): - return ip.get_gateway() + for interface in self.config.address().get_interfaces(): + if interface.ip_in_subnet(ipa): + return interface.get_gateway() return None def portsToString(self, ports, delimiter): diff --git a/systemvm/patches/debian/config/opt/cloud/bin/cs/CsAddress.py b/systemvm/patches/debian/config/opt/cloud/bin/cs/CsAddress.py index f74ff479123..8670cf1deb4 100755 --- a/systemvm/patches/debian/config/opt/cloud/bin/cs/CsAddress.py +++ b/systemvm/patches/debian/config/opt/cloud/bin/cs/CsAddress.py @@ -28,7 +28,6 @@ from CsRoute import CsRoute from CsRule import CsRule VRRP_TYPES = ['guest'] -PUBLIC_INTERFACE = ['eth1'] class CsAddress(CsDataBag): @@ -37,14 +36,14 @@ class CsAddress(CsDataBag): ip = CsIP(dev, self.config) ip.compare(self.dbag) - def get_ips(self): - ret = [] + def get_interfaces(self): + interfaces = [] for dev in self.dbag: if dev == "id": continue for ip in self.dbag[dev]: - ret.append(CsInterface(ip, self.config)) - return ret + interfaces.append(CsInterface(ip, self.config)) + return interfaces def get_guest_if(self): """ @@ -52,13 +51,13 @@ class CsAddress(CsDataBag): """ guest_interface = None lowest_device = 1000 - for ip in self.get_ips(): - if ip.is_guest() and ip.is_added(): - device = ip.get_device() + for interface in self.get_interfaces(): + if interface.is_guest() and interface.is_added(): + device = interface.get_device() device_suffix = int(''.join([digit for digit in device if digit.isdigit()])) if device_suffix < lowest_device: lowest_device = device_suffix - guest_interface = ip + guest_interface = interface logging.debug("Guest interface will be set on device '%s' and IP '%s'" % (guest_interface.get_device(), guest_interface.get_ip())) return guest_interface @@ -94,9 +93,9 @@ class CsAddress(CsDataBag): """ Return the address object that has the control interface """ - for ip in self.get_ips(): - if ip.is_control(): - return ip + for interface in self.get_interfaces(): + if interface.is_control(): + return interface return None def process(self): @@ -290,24 +289,27 @@ class CsIP: route = CsRoute() if not self.get_type() in ["control"]: route.add_table(self.dev) - + CsRule(self.dev).addMark() - self.check_is_up() + + interfaces = [CsInterface(address, self.config)] + CsHelper.reconfigure_interfaces(self.cl, interfaces) + self.set_mark() self.arpPing() - + CsRpsrfs(self.dev).enable() self.post_config_change("add") '''For isolated/redundant and dhcpsrvr routers, call this method after the post_config is complete ''' if not self.config.is_vpc(): self.setup_router_control() - + if self.config.is_vpc() or self.cl.is_redundant(): # The code looks redundant here, but we actually have to cater for routers and # VPC routers in a different manner. Please do not remove this block otherwise # The VPC default route will be broken. - if self.get_type() in ["public"] and address["device"] in PUBLIC_INTERFACE: + if self.get_type() in ["public"] and address["device"] == CsHelper.PUBLIC_INTERFACES[self.cl.get_type()]: gateway = str(address["gateway"]) route.add_defaultroute(gateway) else: @@ -316,29 +318,6 @@ class CsIP: if(self.cl.get_gateway()): route.add_defaultroute(self.cl.get_gateway()) - def check_is_up(self): - """ Ensure device is up """ - state_commands = {"router" : "ip addr | grep eth0 | grep inet | wc -l | xargs bash -c 'if [ $0 == 2 ]; then echo \"MASTER\"; else echo \"BACKUP\"; fi'", - "vpcrouter" : "ip addr | grep eth1 | grep state | awk '{print $9;}' | xargs bash -c 'if [ $0 == \"UP\" ]; then echo \"MASTER\"; else echo \"BACKUP\"; fi'"} - - cmd = "ip link show %s | grep 'state DOWN'" % self.getDevice() - for i in CsHelper.execute(cmd): - if " DOWN " in i: - cmd2 = "ip link set %s up" % self.getDevice() - # If redundant only bring up public interfaces that are not eth1. - # Reason: private gateways are public interfaces. - # master.py and keepalived will deal with eth1 public interface. - - if self.cl.is_redundant() and self.is_public(): - state_cmd = state_commands[self.cl.get_type()] - logging.info("Check state command => %s" % state_cmd) - state = CsHelper.execute(state_cmd)[0] - logging.info("Route state => %s" % state) - if self.getDevice() not in PUBLIC_INTERFACE and state == "MASTER": - CsHelper.execute(cmd2) - else: - CsHelper.execute(cmd2) - def set_mark(self): cmd = "-A PREROUTING -i %s -m state --state NEW -j CONNMARK --set-xmark %s/0xffffffff" % \ (self.getDevice(), self.dnum) @@ -365,12 +344,12 @@ class CsIP: def setup_router_control(self): if self.config.is_vpc(): return - + self.fw.append( ["filter", "", "-A FW_OUTBOUND -m state --state RELATED,ESTABLISHED -j ACCEPT"]) self.fw.append( ["filter", "", "-A INPUT -i eth1 -p tcp -m tcp --dport 3922 -m state --state NEW,ESTABLISHED -j ACCEPT"]) - + self.fw.append(["filter", "", "-P INPUT DROP"]) self.fw.append(["filter", "", "-P FORWARD DROP"]) diff --git a/systemvm/patches/debian/config/opt/cloud/bin/cs/CsHelper.py b/systemvm/patches/debian/config/opt/cloud/bin/cs/CsHelper.py index 9095558a55f..9036527811e 100755 --- a/systemvm/patches/debian/config/opt/cloud/bin/cs/CsHelper.py +++ b/systemvm/patches/debian/config/opt/cloud/bin/cs/CsHelper.py @@ -27,6 +27,30 @@ import shutil from netaddr import * from pprint import pprint +PUBLIC_INTERFACES = {"router" : "eth0", "vpcrouter" : "eth1"} + +STATE_COMMANDS = {"router" : "ip addr | grep eth0 | grep inet | wc -l | xargs bash -c 'if [ $0 == 2 ]; then echo \"MASTER\"; else echo \"BACKUP\"; fi'", + "vpcrouter" : "ip addr | grep eth1 | grep state | awk '{print $9;}' | xargs bash -c 'if [ $0 == \"UP\" ]; then echo \"MASTER\"; else echo \"BACKUP\"; fi'"} + +def reconfigure_interfaces(router_config, interfaces): + for interface in interfaces: + cmd = "ip link show %s | grep 'state DOWN'" % interface.get_device() + for device in execute(cmd): + if " DOWN " in device: + cmd = "ip link set %s up" % interface.get_device() + # If redundant only bring up public interfaces that are not eth1. + # Reason: private gateways are public interfaces. + # master.py and keepalived will deal with eth1 public interface. + + if router_config.is_redundant() and interface.is_public(): + state_cmd = STATE_COMMANDS[router_config.get_type()] + logging.info("Check state command => %s" % state_cmd) + state = execute(state_cmd)[0] + logging.info("Route state => %s" % state) + if interface.get_device() != PUBLIC_INTERFACES[router_config.get_type()] and state == "MASTER": + execute(cmd) + else: + execute(cmd) def is_mounted(name): for i in execute("mount"): diff --git a/systemvm/patches/debian/config/opt/cloud/bin/cs/CsRedundant.py b/systemvm/patches/debian/config/opt/cloud/bin/cs/CsRedundant.py index 7d34e303fa6..7cc72d8e26e 100755 --- a/systemvm/patches/debian/config/opt/cloud/bin/cs/CsRedundant.py +++ b/systemvm/patches/debian/config/opt/cloud/bin/cs/CsRedundant.py @@ -41,8 +41,6 @@ from CsRoute import CsRoute import socket from time import sleep -PUBLIC_INTERFACE = ['eth0', 'eth1'] - class CsRedundant(object): CS_RAMDISK_DIR = "/ramdisk" @@ -89,7 +87,7 @@ class CsRedundant(object): self._redundant_off() return - interfaces = [interface for interface in self.address.get_ips() if interface.is_guest()] + interfaces = [interface for interface in self.address.get_interfaces() if interface.is_guest()] isDeviceReady = False dev = '' for interface in interfaces: @@ -229,9 +227,9 @@ class CsRedundant(object): self.set_lock() logging.info("Router switched to fault mode") - ips = [ip for ip in self.address.get_ips() if ip.is_public() and ip.get_device() in PUBLIC_INTERFACE] - for ip in ips: - CsHelper.execute("ifconfig %s down" % ip.get_device()) + interfaces = [interface for interface in self.address.get_interfaces() if interface.is_public()] + for interface in interfaces: + CsHelper.execute("ifconfig %s down" % interface.get_device()) cmd = "%s -C %s" % (self.CONNTRACKD_BIN, self.CONNTRACKD_CONF) CsHelper.execute("%s -s" % cmd) @@ -239,15 +237,18 @@ class CsRedundant(object): CsHelper.service("xl2tpd", "stop") CsHelper.service("dnsmasq", "stop") - ips = [ip for ip in self.address.get_ips() if ip.needs_vrrp()] - for ip in ips: - CsPasswdSvc(ip.get_gateway()).stop() + interfaces = [interface for interface in self.address.get_interfaces() if interface.needs_vrrp()] + for interface in interfaces: + CsPasswdSvc(interface.get_gateway()).stop() self.cl.set_fault_state() self.cl.save() self.release_lock() logging.info("Router switched to fault mode") + interfaces = [interface for interface in self.address.get_interfaces() if interface.is_public()] + CsHelper.reconfigure_interfaces(self.cl, interfaces) + def set_backup(self): """ Set the current router to backup """ if not self.cl.is_redundant(): @@ -258,28 +259,31 @@ class CsRedundant(object): logging.debug("Setting router to backup") dev = '' - ips = [ip for ip in self.address.get_ips() if ip.is_public() and ip.get_device() in PUBLIC_INTERFACE] - for ip in ips: - if dev == ip.get_device(): + interfaces = [interface for interface in self.address.get_interfaces() if interface.is_public()] + for interface in interfaces: + if dev == interface.get_device(): continue - logging.info("Bringing public interface %s down" % ip.get_device()) - cmd2 = "ip link set %s down" % ip.get_device() + logging.info("Bringing public interface %s down" % interface.get_device()) + cmd2 = "ip link set %s down" % interface.get_device() CsHelper.execute(cmd2) - dev = ip.get_device() + dev = interface.get_device() cmd = "%s -C %s" % (self.CONNTRACKD_BIN, self.CONNTRACKD_CONF) CsHelper.execute("%s -d" % cmd) CsHelper.service("ipsec", "stop") CsHelper.service("xl2tpd", "stop") - ips = [ip for ip in self.address.get_ips() if ip.needs_vrrp()] - for ip in ips: - CsPasswdSvc(ip.get_gateway()).stop() + interfaces = [interface for interface in self.address.get_interfaces() if interface.needs_vrrp()] + for interface in interfaces: + CsPasswdSvc(interface.get_gateway()).stop() CsHelper.service("dnsmasq", "stop") self.cl.set_master_state(False) self.cl.save() self.release_lock() + + interfaces = [interface for interface in self.address.get_interfaces() if interface.is_public()] + CsHelper.reconfigure_interfaces(self.cl, interfaces) logging.info("Router switched to backup mode") def set_master(self): @@ -292,12 +296,12 @@ class CsRedundant(object): logging.debug("Setting router to master") dev = '' - ips = [ip for ip in self.address.get_ips() if ip.is_public()] + interfaces = [interface for interface in self.address.get_interfaces() if interface.is_public()] route = CsRoute() - for ip in ips: - if dev == ip.get_device(): + for interface in interfaces: + if dev == interface.get_device(): continue - dev = ip.get_device() + dev = interface.get_device() logging.info("Will proceed configuring device ==> %s" % dev) cmd2 = "ip link set %s up" % dev if CsDevice(dev, self.config).waitfordevice(): @@ -305,9 +309,9 @@ class CsRedundant(object): logging.info("Bringing public interface %s up" % dev) try: - gateway = ip.get_gateway() + gateway = interface.get_gateway() logging.info("Adding gateway ==> %s to device ==> %s" % (gateway, dev)) - if ip.get_device() in PUBLIC_INTERFACE: + if dev == CsHelper.PUBLIC_INTERFACES[self.cl.get_type()]: route.add_defaultroute(gateway) except: logging.error("ERROR getting gateway from device %s" % dev) @@ -322,14 +326,17 @@ class CsRedundant(object): CsHelper.execute("%s -B" % cmd) CsHelper.service("ipsec", "restart") CsHelper.service("xl2tpd", "restart") - ads = [o for o in self.address.get_ips() if o.needs_vrrp()] - for o in ads: - CsPasswdSvc(o.get_gateway()).restart() + interfaces = [interface for interface in self.address.get_interfaces() if interface.needs_vrrp()] + for interface in interfaces: + CsPasswdSvc(interface.get_gateway()).restart() CsHelper.service("dnsmasq", "restart") self.cl.set_master_state(True) self.cl.save() self.release_lock() + + interfaces = [interface for interface in self.address.get_interfaces() if interface.is_public()] + CsHelper.reconfigure_interfaces(self.cl, interfaces) logging.info("Router switched to master mode") def _collect_ignore_ips(self): @@ -355,23 +362,14 @@ class CsRedundant(object): that could function as a router and VPC router at the same time """ lines = [] - for ip in self.address.get_ips(): - if ip.needs_vrrp(): + for interface in self.address.get_interfaces(): + if interface.needs_vrrp(): cmdline=self.config.get_cmdline_instance() - if not ip.is_added(): + if not interface.is_added(): continue if(cmdline.get_type()=='router'): - str = " %s brd %s dev %s\n" % (cmdline.get_guest_gw(), ip.get_broadcast(), ip.get_device()) + str = " %s brd %s dev %s\n" % (cmdline.get_guest_gw(), interface.get_broadcast(), interface.get_device()) else: - str = " %s brd %s dev %s\n" % (ip.get_gateway_cidr(), ip.get_broadcast(), ip.get_device()) + str = " %s brd %s dev %s\n" % (interface.get_gateway_cidr(), interface.get_broadcast(), interface.get_device()) lines.append(str) return lines - - def check_is_up(self, device): - """ Ensure device is up """ - cmd = "ip link show %s | grep 'state DOWN'" % device - - for i in CsHelper.execute(cmd): - if " DOWN " in i: - cmd2 = "ip link set %s up" % device - CsHelper.execute(cmd2)