示例#1
0
    def set_fault(self):
        """ Set fault mode on this router """
        if not self.cl.is_redundant():
            logging.error("Set fault called on non-redundant router")
            return

        self.set_lock()
        logging.info("Router switched to fault mode")

        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)
        CsHelper.service("ipsec", "stop")
        CsHelper.service("xl2tpd", "stop")
        CsHelper.service("dnsmasq", "stop")

        interfaces = [interface for interface in self.address.get_interfaces() if interface.needs_vrrp()]
        for interface in interfaces:
            CsPasswdSvc(interface.get_ip()).stop()
            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)
示例#2
0
    def post_config_change(self, method):
        route = CsRoute()
        if method == "add":
            route.add_table(self.dev)
            route.add_route(self.dev, str(self.address["network"]))
        elif method == "delete":
            logging.warn("delete route not implemented")

        self.fw_router()
        self.fw_vpcrouter()

        # On deletion nw_type will no longer be known
        if self.get_type() in ('guest'):
            if self.config.is_vpc() or self.config.is_router():
                CsDevice(self.dev, self.config).configure_rp()
                logging.error(
                    "Not able to setup source-nat for a regular router yet")

            if self.config.has_dns() or self.config.is_dhcp():
                dns = CsDnsmasq(self)
                dns.add_firewall_rules()

            if self.config.has_metadata():
                app = CsApache(self)
                app.setup()

        cmdline = self.config.cmdline()
        # Start passwd server on non-redundant routers and on the master router of redundant pairs
        # CsRedundant will handle fail-over.
        if self.get_type() in ["guest"] and (not self.cl.is_redundant()
                                             or self.cl.is_master()):
            CsPasswdSvc(self.address['public_ip']).start()
        elif self.get_type() in ["guest"]:
            # Or else make sure it's stopped
            CsPasswdSvc(self.address['public_ip']).stop()

        if self.get_type() == "public" and self.config.is_vpc():
            if self.address["source_nat"]:
                logging.info("Adding SourceNAT for interface %s to %s" %
                             (self.dev, self.address['public_ip']))
                self.fw.append([
                    "nat", "",
                    "-A POSTROUTING -j SNAT -o %s --to-source %s" %
                    (self.dev, self.address['public_ip'])
                ])
            else:
                logging.info(
                    "Not adding SourceNAT for interface %s to %s, because source_nat=False"
                    % (self.dev, self.address['public_ip']))
示例#3
0
    def set_backup(self):
        """ Set the current router to backup """
        if not self.cl.is_redundant():
            logging.error("Set backup called on non-redundant router")
            return

        self.set_lock()
        logging.debug("Setting router to backup")

        dev = ''
        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" %
                         interface.get_device())
            cmd2 = "ip link set %s down" % interface.get_device()
            CsHelper.execute(cmd2)
            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")

        interfaces = [
            interface for interface in self.address.get_interfaces()
            if interface.needs_vrrp()
        ]
        for interface in interfaces:
            CsPasswdSvc(interface.get_ip()).stop()
            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")
示例#4
0
 def set_backup(self):
     """ Set the current router to backup """
     if not self.cl.is_redundant():
         logging.error("Set backup called on non-redundant router")
         return
     """
     if not self.cl.is_master():
         logging.error("Set backup called on node that is already backup")
         return
     """
     self.set_lock()
     logging.debug("Setting router to backup")
     ads = [o for o in self.address.get_ips() if o.is_public()]
     dev = ''
     for o in ads:
         if dev == o.get_device():
             continue
         logging.info("Bringing public interface %s down" % o.get_device())
         cmd2 = "ip link set %s up" % o.get_device()
         CsHelper.execute(cmd2)
         dev = o.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")
     ads = [o for o in self.address.get_ips() if o.needs_vrrp()]
     for o in ads:
         CsPasswdSvc(o.get_gateway()).stop()
     CsHelper.service("dnsmasq", "stop")
     # self._set_priority(self.CS_PRIO_DOWN)
     self.cl.set_master_state(False)
     self.cl.save()
     self.release_lock()
     logging.info("Router switched to backup mode")
示例#5
0
 def set_master(self):
     """ Set the current router to master """
     if not self.cl.is_redundant():
         logging.error("Set master called on non-redundant router")
         return
     """
     if self.cl.is_master():
         logging.error("Set master called on master node")
         return
     """
     s = self.set_lock()
     logging.debug("Setting router to master")
     ads = [o for o in self.address.get_ips() if o.is_public()]
     for o in ads:
         # cmd2 = "ip link set %s up" % self.getDevice()
         CsHelper.execute("ifconfig %s down" % o.get_device())
         CsHelper.execute("ifconfig %s up" % o.get_device())
         CsHelper.execute("arping -I %s -A %s -c 1" %
                          (o.get_device(), o.get_ip()))
     # FIXME Need to add in the default routes but I am unsure what the gateway is
     # ip route add default via $gw table Table_$dev proto static
     cmd = "%s -C %s" % (self.CONNTRACKD_BIN, self.CONNTRACKD_CONF)
     CsHelper.execute("%s -c" % cmd)
     CsHelper.execute("%s -f" % cmd)
     CsHelper.execute("%s -R" % cmd)
     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:
         pwdsvc = CsPasswdSvc(o.get_gateway()).restart()
     CsHelper.service("dnsmasq", "restart")
     self.cl.set_master_state(True)
     self.cl.save()
     logging.info("Router switched to master mode")
示例#6
0
    def post_config_change(self, method):
        route = CsRoute(self.dev)
        route.routeTable()
        route.add(self.address, method)
        self.fw_router()
        self.fw_vpcrouter()
        # On deletion nw_type will no longer be known
        if self.get_type() in ["guest"] and self.config.is_vpc():

            CsDevice(self.dev, self.config).configure_rp()

            logging.error(
                "Not able to setup sourcenat for a regular router yet")
            dns = CsDnsmasq(self)
            dns.add_firewall_rules()
            app = CsApache(self)
            app.setup()

        # If redundant then this is dealt with by the master backup functions
        if self.get_type() in ["guest"] and not self.config.cl.is_redundant():
            pwdsvc = CsPasswdSvc(self.address['public_ip']).start()

        if self.get_type() == "public" and self.config.is_vpc():
            if self.address["source_nat"]:
                vpccidr = self.config.cmdline().get_vpccidr()
                self.fw.append([
                    "filter", "",
                    "-A FORWARD -s %s ! -d %s -j ACCEPT" % (vpccidr, vpccidr)
                ])
                self.fw.append([
                    "nat", "",
                    "-A POSTROUTING -j SNAT -o %s --to-source %s" %
                    (self.dev, self.address['public_ip'])
                ])
示例#7
0
    def set_master(self):
        """ Set the current router to master """
        if not self.cl.is_redundant():
            logging.error("Set master called on non-redundant router")
            return

        self.set_lock()
        logging.debug("Setting router to master")
        self.address.process()
        logging.info("added default routes")

        # ip route add default via $gw table Table_$dev proto static
        cmd = "%s -C %s" % (self.CONNTRACKD_BIN, self.CONNTRACKD_CONF)
        CsHelper.execute("%s -c" % cmd)
        CsHelper.execute("%s -f" % cmd)
        CsHelper.execute("%s -R" % cmd)
        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()
        CsHelper.service("dnsmasq", "restart")
        self.cl.set_master_state(True)
        self.cl.save()
        self.release_lock()
        logging.info("Router switched to master mode")
示例#8
0
    def set_master(self):
        """ Set the current router to master """
        if not self.cl.is_redundant():
            logging.error("Set master called on non-redundant router")
            return

        self.set_lock()
        logging.debug("Setting router to master")

        dev = ''
        interfaces = [interface for interface in self.address.get_interfaces() if interface.is_public()]
        route = CsRoute()
        for interface in interfaces:
            if dev == interface.get_device():
                continue
            dev = interface.get_device()
            logging.info("Will proceed configuring device ==> %s" % dev)
            cmd = "ip link set %s up" % dev
            if CsDevice(dev, self.config).waitfordevice():
                CsHelper.execute(cmd)
                logging.info("Bringing public interface %s up" % dev)

                try:
                    gateway = interface.get_gateway()
                    logging.info("Adding gateway ==> %s to device ==> %s" % (gateway, dev))
                    if dev == CsHelper.PUBLIC_INTERFACES[self.cl.get_type()]:
                        route.add_defaultroute(gateway)
                except:
                    logging.error("ERROR getting gateway from device %s" % dev)
            else:
                logging.error("Device %s was not ready could not bring it up" % dev)

        logging.debug("Configuring static routes")
        static_routes = CsStaticRoutes("staticroutes", self.config)
        static_routes.process()

        cmd = "%s -C %s" % (self.CONNTRACKD_BIN, self.CONNTRACKD_CONF)
        CsHelper.execute("%s -c" % cmd)
        CsHelper.execute("%s -f" % cmd)
        CsHelper.execute("%s -R" % cmd)
        CsHelper.execute("%s -B" % cmd)
        CsHelper.service("ipsec", "restart")
        CsHelper.service("xl2tpd", "restart")
        interfaces = [interface for interface in self.address.get_interfaces() if interface.needs_vrrp()]
        for interface in interfaces:
            # Listen on local ip address, as cloud-init uses the 'dhcp-server-identifier' address,
            #  which unfortunately is not the gateway address.
            CsPasswdSvc(interface.get_ip()).start()

        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")
示例#9
0
    def set_master(self):
        """ Set the current router to master """
        if not self.cl.is_redundant():
            logging.error("Set master called on non-redundant router")
            return

        self.set_lock()
        logging.debug("Setting router to master")

        ads = [o for o in self.address.get_ips() if o.is_public()]
        dev = ''
        route = CsRoute()
        for o in ads:
            if dev == o.get_device():
                continue
            dev = o.get_device()
            logging.info("Will proceed configuring device ==> %s" % dev)
            cmd2 = "ip link set %s up" % dev
            if CsDevice(dev, self.config).waitfordevice():
                CsHelper.execute(cmd2)
                logging.info("Bringing public interface %s up" % dev)

                try:
                    gateway = o.get_gateway()
                    logging.info("Adding gateway ==> %s to device ==> %s" %
                                 (gateway, dev))
                    route.add_defaultroute(gateway)
                except:
                    logging.error("ERROR getting gateway from device %s" % dev)
            else:
                logging.error("Device %s was not ready could not bring it up" %
                              dev)

        # ip route add default via $gw table Table_$dev proto static
        cmd = "%s -C %s" % (self.CONNTRACKD_BIN, self.CONNTRACKD_CONF)
        CsHelper.execute("%s -c" % cmd)
        CsHelper.execute("%s -f" % cmd)
        CsHelper.execute("%s -R" % cmd)
        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()

        CsHelper.service("dnsmasq", "restart")
        self.cl.set_master_state(True)
        self.cl.save()
        self.release_lock()
        logging.info("Router switched to master mode")
示例#10
0
    def post_config_change(self, method):
        route = CsRoute()
        if method == "add":
            route.add_table(self.dev)
            route.add_route(self.dev, str(self.address["network"]))
        elif method == "delete":
            logging.warn("delete route not implemented")

        self.fw_router()
        self.fw_vpcrouter()

        # On deletion nw_type will no longer be known
        if self.get_type() in ('guest'):
            if self.config.is_vpc() or self.config.is_router():
                CsDevice(self.dev, self.config).configure_rp()
                logging.error(
                    "Not able to setup source-nat for a regular router yet")

            if self.config.has_dns() or self.config.is_dhcp():
                dns = CsDnsmasq(self)
                dns.add_firewall_rules()

            if self.config.has_metadata():
                app = CsApache(self)
                app.setup()

        cmdline = self.config.cmdline()
        # If redundant then this is dealt with by the master backup functions
        if self.get_type() in ["guest"] and not cmdline.is_redundant():
            pwdsvc = CsPasswdSvc(self.address['public_ip']).start()

        if self.get_type() == "public" and self.config.is_vpc():
            if self.address["source_nat"]:
                vpccidr = cmdline.get_vpccidr()
                self.fw.append([
                    "filter", 3,
                    "-A FORWARD -s %s ! -d %s -j ACCEPT" % (vpccidr, vpccidr)
                ])
                self.fw.append([
                    "nat", "",
                    "-A POSTROUTING -j SNAT -o %s --to-source %s" %
                    (self.dev, self.address['public_ip'])
                ])
示例#11
0
 def set_fault(self):
     """ Set fault mode on this router """
     if not self.cl.is_redundant():
         logging.error("Set fault called on non-redundant router")
         return
     s = self.set_lock()
     logging.info("Router switched to fault mode")
     ads = [o for o in self.address.get_ips() if o.is_public()]
     for o in ads:
         CsHelper.execute("ifconfig %s down" % o.get_device())
     cmd = "%s -C %s" % (self.CONNTRACKD_BIN, self.CONNTRACKD_CONF)
     CsHelper.execute("%s -s" % cmd)
     CsHelper.service("ipsec", "stop")
     CsHelper.service("xl2tpd", "stop")
     CsHelper.service("dnsmasq", "stop")
     ads = [o for o in self.address.get_ips() if o.needs_vrrp()]
     for o in ads:
         pwdsvc = CsPasswdSvc(o.get_gateway()).stop()
     self.cl.set_fault_state()
     self.cl.save()
     logging.info("Router switched to fault mode")
示例#12
0
    def post_config_change(self, method):
        route = CsRoute()
        tableName = "Table_" + self.dev

        if method == "add":
            if not self.config.is_vpc():
                if self.get_type() in ["public"]:
                    route.set_route(
                        "table %s throw %s proto static" %
                        (tableName,
                         self.config.address().dbag['eth0'][0]['network']))
                    route.set_route(
                        "table %s throw %s proto static" %
                        (tableName,
                         self.config.address().dbag['eth1'][0]['network']))

                # add 'default via gateway' rule in the device specific routing table
                if "gateway" in self.address and self.address[
                        "gateway"] and self.address["gateway"] != "None":
                    route.add_route(self.dev, self.address["gateway"])
                if "network" in self.address and self.address["network"]:
                    route.add_network_route(self.dev,
                                            str(self.address["network"]))

                if self.get_type() in ["public"]:
                    CsRule(self.dev).addRule("from " +
                                             str(self.address["network"]))

            if self.config.is_vpc():
                if self.get_type() in [
                        "public"
                ] and "gateway" in self.address and self.address[
                        "gateway"] and self.address["gateway"] != "None":
                    route.add_route(self.dev, self.address["gateway"])
                    for inf, addresses in self.config.address().dbag.iteritems(
                    ):
                        if not inf.startswith("eth"):
                            continue
                        for address in addresses:
                            if "nw_type" in address and address[
                                    "nw_type"] == "guest":
                                route.add_network_route(
                                    self.dev, str(address["network"]))

                route.add_network_route(self.dev, str(self.address["network"]))

            CsHelper.execute("sudo ip route flush cache")

        elif method == "delete":
            # treat the last IP to be dis-associated with interface as special case to clean up the routing rules
            if self.get_type() in [
                    "public"
            ] and (not self.config.is_vpc()) and (len(self.iplist) == 0):
                CsHelper.execute("sudo ip rule delete table " + tableName)
                CsHelper.execute("sudo ip route flush table " + tableName)
                CsHelper.execute("sudo ip route flush cache")
                CsRule(self.dev).delMark()

        self.fw_router()
        self.fw_vpcrouter()

        cmdline = self.config.cmdline()

        # On deletion nw_type will no longer be known
        if self.get_type() in ('guest'):
            if self.config.is_vpc() or self.config.is_router():
                CsDevice(self.dev, self.config).configure_rp()

                logging.error(
                    "Not able to setup source-nat for a regular router yet")

            if (self.config.has_dns()
                    or self.config.is_dhcp()) and self.config.expose_dns():
                logging.info("Making dns publicly available")
                dns = CsDnsmasq(self)
                dns.add_firewall_rules()
            else:
                logging.info("Not making dns publicly available")

            if self.config.has_metadata():
                app = CsApache(self)
                app.setup()

                # If redundant then this is dealt with
                # by the primary backup functions
                if not cmdline.is_redundant():
                    if method == "add":
                        CsPasswdSvc(self.address['public_ip']).start()
                    elif method == "delete":
                        CsPasswdSvc(self.address['public_ip']).stop()
                elif cmdline.is_primary():
                    if method == "add":
                        CsPasswdSvc(self.get_gateway() + "," +
                                    self.address['public_ip']).start()
                    elif method == "delete":
                        CsPasswdSvc(self.get_gateway() + "," +
                                    self.address['public_ip']).stop()

        if self.get_type() == "public" and self.config.is_vpc(
        ) and method == "add":
            if self.address["source_nat"]:
                vpccidr = cmdline.get_vpccidr()
                self.fw.append([
                    "filter", 3,
                    "-A FORWARD -s %s ! -d %s -j ACCEPT" % (vpccidr, vpccidr)
                ])
                self.fw.append([
                    "nat", "",
                    "-A POSTROUTING -j SNAT -o %s --to-source %s" %
                    (self.dev, self.address['public_ip'])
                ])
示例#13
0
    def set_primary(self):
        """ Set the current router to primary """
        if not self.cl.is_redundant():
            logging.error("Set primary called on non-redundant router")
            return

        self.set_lock()
        logging.debug("Setting router to primary")

        dev = ''
        interfaces = [
            interface for interface in self.address.get_interfaces()
            if interface.is_public()
        ]
        route = CsRoute()
        for interface in interfaces:
            if dev == interface.get_device():
                continue
            dev = interface.get_device()
            logging.info("Will proceed configuring device ==> %s" % dev)
            cmd = "ip link set %s up" % dev
            if CsDevice(dev, self.config).waitfordevice():
                CsHelper.execute(cmd)
                logging.info("Bringing public interface %s up" % dev)

                try:
                    gateway = interface.get_gateway()
                    logging.info("Adding gateway ==> %s to device ==> %s" %
                                 (gateway, dev))
                    if dev == CsHelper.PUBLIC_INTERFACES[self.cl.get_type()]:
                        route.add_defaultroute(gateway)
                except Exception:
                    logging.error("ERROR getting gateway from device %s" % dev)
                if dev == CsHelper.PUBLIC_INTERFACES[self.cl.get_type()]:
                    try:
                        self._add_ipv6_to_interface(interface,
                                                    interface.get_ip6())
                        if interface.get_gateway6():
                            route.add_defaultroute_v6(interface.get_gateway6())
                    except Exception as e:
                        logging.error(
                            "ERROR adding IPv6, getting IPv6 gateway from device %s: %s"
                            % (dev, e))
            else:
                logging.error("Device %s was not ready could not bring it up" %
                              dev)

        self._add_ipv6_guest_gateway()

        logging.debug("Configuring static routes")
        static_routes = CsStaticRoutes("staticroutes", self.config)
        static_routes.process()

        cmd = "%s -C %s" % (self.CONNTRACKD_BIN, self.CONNTRACKD_CONF)
        CsHelper.execute("%s -c" % cmd)
        CsHelper.execute("%s -f" % cmd)
        CsHelper.execute("%s -R" % cmd)
        CsHelper.execute("%s -B" % cmd)
        CsHelper.service("ipsec", "restart")
        CsHelper.service("xl2tpd", "restart")

        interfaces = [
            interface for interface in self.address.get_interfaces()
            if interface.needs_vrrp()
        ]
        for interface in interfaces:
            if interface.is_added():
                CsPasswdSvc(interface.get_gateway() + "," +
                            interface.get_ip()).restart()

        CsHelper.service("dnsmasq", "restart")
        self.cl.set_primary_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)

        public_devices = list(
            set([interface.get_device() for interface in interfaces]))
        if len(public_devices) > 1:
            # Handle specific failures when multiple public interfaces

            public_devices.sort()

            # Ensure the default route is added, or outgoing traffic from VMs with static NAT on
            # the subsequent interfaces will go from the wrong IP
            route = CsRoute()
            dev = ''
            for interface in interfaces:
                if dev == interface.get_device():
                    continue
                dev = interface.get_device()
                gateway = interface.get_gateway()
                if gateway:
                    route.add_route(dev, gateway)

            # The first public interface has a static MAC address between VRs.  Subsequent ones don't,
            # so an ARP announcement is needed on failover
            for device in public_devices[1:]:
                logging.info("Sending garp messages for IPs on %s" % device)
                for interface in interfaces:
                    if interface.get_device() == device:
                        CsHelper.execute("arping -I %s -U %s -c 1" %
                                         (device, interface.get_ip()))

        logging.info("Router switched to primary mode")