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")
Exemple #2
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")

        ips = [ip for ip in self.address.get_ips() if ip.is_public()]
        for ip in ips:
            CsHelper.execute("ifconfig %s down" % ip.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")

        ips = [ip for ip in self.address.get_ips() if ip.needs_vrrp()]
        for ip in ips:
            CsPasswdSvc(ip.get_gateway()).stop()

        self.cl.set_fault_state()
        self.cl.save()
        self.release_lock()
        logging.info("Router switched to fault mode")
 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)
Exemple #4
0
    def delete_leases(self):
        changed = []
        leases = []
        try:
            for line in open(LEASES):
                bits = line.strip().split(' ')
                to = {"device": bits[0],
                      "mac": bits[1],
                      "ip": bits[2],
                      "host": bits[3:],
                      "del": False
                      }
                changed.append(to)

                for v in changed:
                    if v['mac'] == to['mac'] or v['ip'] == to['ip'] or v['host'] == to['host']:
                        to['del'] = True
                leases.append(to)

            for o in leases:
                if o['del']:
                    cmd = "dhcp_release eth%s %s %s" % (o['device'], o['ip'], o['mac'])
                    logging.info(cmd)
                    CsHelper.execute(cmd)
        except IOError:
            return
    def compare(self, list):
        """ Compare reality with what is needed """
        for c in self.chain.get("filter"):
            # Ensure all inbound/outbound chains have a default drop rule
            if c.startswith("ACL_INBOUND") or c.startswith("ACL_OUTBOUND"):
                list.append(["filter", "", "-A %s -j DROP" % c])
        # PASS 1:  Ensure all chains are present
        for fw in list:
            new_rule = CsNetfilter()
            new_rule.parse(fw[2])
            new_rule.set_table(fw[0])
            self.add_chain(new_rule)
        # PASS 2: Create rules
        for fw in list:
            new_rule = CsNetfilter()
            new_rule.parse(fw[2])
            new_rule.set_table(fw[0])
            if isinstance(fw[1], int):
                new_rule.set_count(fw[1])
            if self.has_rule(new_rule):
                logging.debug("rule %s exists in table %s", fw[2], new_rule.get_table())
            else:
                # print "Add rule %s in table %s" % ( fw[2], new_rule.get_table())
                logging.info("Add rule %s in table %s", fw[2], new_rule.get_table())
                # front means insert instead of append
                cpy = fw[2]
                if fw[1] == "front":
                    cpy = cpy.replace('-A', '-I')
                if isinstance(fw[1], int):
                    cpy = cpy.replace("-A %s" % new_rule.get_chain(), '-I %s %s' % (new_rule.get_chain(), fw[1]))

                CsHelper.execute("iptables -t %s %s" % (new_rule.get_table(), cpy))
        self.del_standard()
        self.get_unseen()
 def get_unseen(self):
     del_list = [x for x in self.rules if x.unseen()]
     for r in del_list:
         cmd = "iptables -t %s %s" % (r.get_table(), r.to_str(True))
         CsHelper.execute(cmd)
         # print "Delete rule %s from table %s" % (r.to_str(True), r.get_table())
         logging.info("Delete rule %s from table %s", r.to_str(True), r.get_table())
    def __update(self, vm_ip, password):
        token = ""
        try:
            tokenFile = open(self.TOKEN_FILE)
            token = tokenFile.read()
        except IOError:
            logging.debug("File %s does not exist" % self.TOKEN_FILE)

        logging.debug("Got VM '%s' and password '%s'" % (vm_ip, password))
        get_cidrs_cmd = "ip addr show | grep inet | grep -v secondary | awk '{print $2}'"
        cidrs = CsHelper.execute(get_cidrs_cmd)
        logging.debug("Found these CIDRs: %s" % cidrs)
        for cidr in cidrs:
            logging.debug("Processing CIDR '%s'" % cidr)
            if IPAddress(vm_ip) in IPNetwork(cidr):
                ip = cidr.split('/')[0]
                logging.debug("Cidr %s matches vm ip address %s so adding passwd to passwd server at %s" % (cidr, vm_ip, ip))
                proc = CsProcess(['/opt/cloud/bin/passwd_server_ip.py', ip])
                if proc.find():
                    update_command = 'curl --header "DomU_Request: save_password" "http://{SERVER_IP}:8080/" -F "ip={VM_IP}" -F "password={PASSWORD}" ' \
                                     '-F "token={TOKEN}" --interface 127.0.0.1 >/dev/null 2>/dev/null &'.format(SERVER_IP=ip, VM_IP=vm_ip, PASSWORD=password, TOKEN=token)
                    result = CsHelper.execute(update_command)
                    logging.debug("Update password server result ==> %s" % result)
                else:
                    logging.debug("Update password server skipped because we didn't find a passwd server process for %s (makes sense on backup routers)" % ip)
Exemple #8
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 = ''
        ips = [ip for ip in self.address.get_ips() if ip.is_public()]
        for ip in ips:
            if dev == ip.get_device():
                continue
            logging.info("Bringing public interface %s down" % ip.get_device())
            cmd2 = "ip link set %s down" % ip.get_device()
            CsHelper.execute(cmd2)
            dev = ip.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()
        CsHelper.service("dnsmasq", "stop")

        self.cl.set_master_state(False)
        self.cl.save()
        self.release_lock()
        logging.info("Router switched to backup mode")
Exemple #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")

        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)
            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:
            CsPasswdSvc(interface.get_ip()).restart()
            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 __update(self, route):
     if route['revoke']:
         command = "ip route del %s via %s" % (route['network'], route['gateway'])
         CsHelper.execute(command)
     else:
         command = "ip route show | grep %s | awk '{print $1, $3}'" % route['network']
         result = CsHelper.execute(command)
         if not result:
             route_command = "ip route add %s via %s" % (route['network'], route['gateway'])
             CsHelper.execute(route_command)
Exemple #11
0
 def add_table(self, devicename):
     tablenumber = 100 + int(devicename[3:])
     tablename = self.get_tablename(devicename)
     str = "%s %s" % (tablenumber, tablename)
     filename = "/etc/iproute2/rt_tables"
     logging.info("Adding route table: " + str + " to " + filename + " if not present ")
     if not CsHelper.definedinfile(filename, str):
         CsHelper.execute("sudo echo " + str + " >> /etc/iproute2/rt_tables")
     # remove "from all table tablename" if exists, else it will interfer with
     # routing of unintended traffic
     if self.findRule("from all lookup " + tablename):
         CsHelper.execute("sudo ip rule delete from all table " + tablename)
Exemple #12
0
 def check_is_up(self):
     """ Ensure device is up """
     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 do not bring up public interfaces
             # master.py and keepalived deal with tham
             if self.cl.is_redundant() and not self.is_public():
                 CsHelper.execute(cmd2)
             # if not redundant bring everything up
             if not self.cl.is_redundant():
                 CsHelper.execute(cmd2)
Exemple #13
0
    def configure(self, address):
        # When "add" is false, it means that the IP has to be removed.
        if address["add"]:
            try:
                logging.info("Configuring address %s on device %s", self.ip(), self.dev)
                cmd = "ip addr add dev %s %s brd +" % (self.dev, self.ip())
                CsHelper.execute(cmd)
            except Exception as e:
                logging.info("Exception occurred ==> %s" % e)

        else:
            self.delete(self.ip())
        self.post_configure(address)
Exemple #14
0
 def check_is_up(self):
     """ Ensure device is up """
     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 (not self.is_public() or self.getDevice() not in PUBLIC_INTERFACE):
                 CsHelper.execute(cmd2)
             # if not redundant bring everything up
             if not self.cl.is_redundant():
                 CsHelper.execute(cmd2)
    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")
Exemple #16
0
 def set_route(self, cmd, method="add"):
     """ Add a route if it is not already defined """
     found = False
     for i in CsHelper.execute("ip route show " + cmd):
         found = True
     if not found and method == "add":
         logging.info("Add " + cmd)
         cmd = "ip route add " + cmd
     elif found and method == "delete":
         logging.info("Delete " + cmd)
         cmd = "ip route delete " + cmd
     else:
         return
     CsHelper.execute(cmd)
Exemple #17
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")
Exemple #18
0
 def list(self):
     self.iplist = {}
     cmd = ("ip addr show dev " + self.dev)
     for i in CsHelper.execute(cmd):
         vals = i.lstrip().split()
         if (vals[0] == 'inet'):
             self.iplist[vals[1]] = self.dev
Exemple #19
0
 def check_if_link_up(self,dev):
     cmd="ip link show dev %s | tr '\n' ' ' | cut -d ' ' -f 9"%dev
     result = CsHelper.execute(cmd)
     if(result and result[0].lower() == "up"):
         return True
     else:
         return False
Exemple #20
0
 def check_if_link_exists(self,dev):
     cmd="ip link show dev %s"%dev
     result = CsHelper.execute(cmd)
     if(len(result) != 0):
        return True
     else:
        return False
Exemple #21
0
    def compare(self, list):
        """ Compare reality with what is needed """
        # PASS 1:  Ensure all chains are present
        for fw in list:
            new_rule = CsNetfilter()
            new_rule.parse(fw[2])
            new_rule.set_table(fw[0])
            self.add_chain(new_rule)

        ruleSet = set()
        # PASS 2: Create rules
        for fw in list:
            tupledFw = tuple(fw)
            if tupledFw in ruleSet :
                logging.debug("Already processed : %s", tupledFw)
                continue

            new_rule = CsNetfilter()
            new_rule.parse(fw[2])
            new_rule.set_table(fw[0])
            if isinstance(fw[1], int):
                new_rule.set_count(fw[1])

            rule_chain = new_rule.get_chain()

            logging.debug("Checking if the rule already exists: rule=%s table=%s chain=%s", new_rule.get_rule(), new_rule.get_table(), new_rule.get_chain())
            if self.has_rule(new_rule):
                logging.debug("Exists: rule=%s table=%s", fw[2], new_rule.get_table())
            else:
                # print "Add rule %s in table %s" % ( fw[2], new_rule.get_table())
                logging.info("Add: rule=%s table=%s", fw[2], new_rule.get_table())
                # front means insert instead of append
                cpy = fw[2]
                if fw[1] == "front":
                    cpy = cpy.replace('-A', '-I')
                if isinstance(fw[1], int):
                    # if the rule is for ACLs, we want to insert them in order, right before the DROP all
                    if rule_chain.startswith("ACL_INBOUND"):
                        rule_count = self.chain.get_count(rule_chain)
                        cpy = cpy.replace("-A %s" % new_rule.get_chain(), '-I %s %s' % (new_rule.get_chain(), rule_count))
                    else:
                        cpy = cpy.replace("-A %s" % new_rule.get_chain(), '-I %s %s' % (new_rule.get_chain(), fw[1]))
                CsHelper.execute("iptables -t %s %s" % (new_rule.get_table(), cpy))
                ruleSet.add(tupledFw)
                self.chain.add_rule(rule_chain)
        self.del_standard()
        self.get_unseen()
Exemple #22
0
 def set_route(self, cmd, method="add"):
     """ Add a route if it is not already defined """
     found = False
     search = cmd
     if "throw" in search:
         search = "type " + search
     for i in CsHelper.execute("ip route show " + search):
         found = True
     if not found and method == "add":
         logging.info("Add " + cmd)
         cmd = "ip route add " + cmd
     elif found and method == "delete":
         logging.info("Delete " + cmd)
         cmd = "ip route delete " + cmd
     else:
         return
     CsHelper.execute(cmd)
Exemple #23
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_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 process(self):
        route = CsRoute()
        found_defaultroute = False

        for dev in self.dbag:
            if dev == "id":
                continue
            ip = CsIP(dev, self.config)

            for address in self.dbag[dev]:
                # check if link is up
                if not self.check_if_link_up(dev):
                    cmd = "ip link set %s up" % dev
                    CsHelper.execute(cmd)

                gateway = str(address["gateway"])
                network = str(address["network"])

                ip.setAddress(address)

                if ip.configured():
                    logging.info("Address %s on device %s already configured", ip.ip(), dev)

                    ip.post_configure()

                else:
                    logging.info("Address %s on device %s not configured", ip.ip(), dev)
                    if CsDevice(dev, self.config).waitfordevice():
                        ip.configure()

                route.add_route(dev, network)

                # 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 address["nw_type"] == "public" and not found_defaultroute:
                    if not route.defaultroute_exists():
                        if route.add_defaultroute(gateway):
                            found_defaultroute = True

        # once we start processing public ip's we need to verify there
        # is a default route and add if needed
        if not route.defaultroute_exists():
            cmdline = self.config.cmdline()
            if cmdline.get_gateway():
                route.add_defaultroute(cmdline.get_gateway())
Exemple #25
0
 def list(self):
     self.iplist = {}
     cmd = ("ip addr show dev " + self.dev)
     for i in CsHelper.execute(cmd):
         vals = i.lstrip().split()
         if (vals[0] == 'inet'):
             cidr = vals[1]
             self.iplist[cidr] = self.dev
Exemple #26
0
    def __update(self, vm_ip, password):
        token = ""
        try:
            token_file = open(self.TOKEN_FILE)
            token = token_file.read()
        except IOError:
            logging.debug("File %s does not exist" % self.TOKEN_FILE)

        logging.debug("Got VM '%s' and password '%s'" % (vm_ip, password))
        get_cidrs_cmd = "ip addr show | grep inet | grep -v secondary | awk '{print $2}'"
        cidrs = CsHelper.execute(get_cidrs_cmd)
        logging.debug("Found these CIDRs: %s" % cidrs)
        for cidr in cidrs:
            logging.debug("Processing CIDR '%s'" % cidr)
            if CsHelper.IPAddress(vm_ip) in CsHelper.IPNetwork(cidr):
                ip = cidr.split('/')[0]
                logging.debug(
                    "Cidr %s matches vm ip address %s so adding passwd to passwd server at %s"
                    % (cidr, vm_ip, ip))
                proc = CsProcess(
                    ['/opt/cosmic/router/bin/passwd_server_ip.py', ip])

                max_tries = 5
                test_tries = 0
                while test_tries < max_tries:
                    logging.debug("Updating passwd server on %s" % ip)
                    if proc.find():
                        url = "http://{SERVER_IP}:8080/".format(SERVER_IP=ip)
                        headers = {'DomU_Request': 'save_password'}
                        params = {
                            'ip': vm_ip,
                            'password': password,
                            'token': token
                        }
                        req = urllib2.Request(url,
                                              urllib.urlencode(params),
                                              headers=headers)
                        try:
                            res = urllib2.urlopen(req).read()
                            if res.code == 200:
                                logging.debug(
                                    "Update password server result ==> %s" %
                                    res)
                                return res
                        except Exception as e:
                            logging.debug(
                                "Error while querying password server ==> %s" %
                                e.message)

                    test_tries += 1
                    logging.debug(
                        "Testing password server process round %s/%s" %
                        (test_tries, max_tries))
                    time.sleep(2)

                logging.debug(
                    "Update password server skipped because we didn't find a passwd server process for "
                    "%s (makes sense on backup routers)" % ip)
Exemple #27
0
    def __update(self, vm_ip, password):
        token = ""
        try:
            token_file = open(self.TOKEN_FILE)
            token = token_file.read()
        except IOError:
            logging.debug("File %s does not exist" % self.TOKEN_FILE)

        logging.debug("Got VM '%s' and password '%s'" % (vm_ip, password))
        get_cidrs_cmd = "ip addr show | grep inet | grep -v secondary | awk '{print $2}'"
        cidrs = CsHelper.execute(get_cidrs_cmd)
        logging.debug("Found these CIDRs: %s" % cidrs)
        for cidr in cidrs:
            logging.debug("Processing CIDR '%s'" % cidr)
            if CsHelper.IPAddress(vm_ip) in CsHelper.IPNetwork(cidr):
                ip = cidr.split('/')[0]
                logging.debug(
                    "Cidr %s matches vm ip address %s so adding passwd to passwd server at %s"
                    % (cidr, vm_ip, ip))
                proc = CsProcess(
                    ['/opt/cosmic/router/bin/passwd_server_ip.py', ip])

                max_tries = 5
                test_tries = 0
                while test_tries < max_tries:
                    logging.debug("Updating passwd server on %s" % ip)
                    if proc.find():
                        update_command = 'curl --header "DomU_Request: save_password" "http://{SERVER_IP}:8080/" -F "ip=' \
                                         '{VM_IP}" -F "password={PASSWORD}" -F "token={TOKEN}" --interface 127.0.0.1 ' \
                                         '>/dev/null 2>/dev/null &'.format(SERVER_IP=ip, VM_IP=vm_ip, PASSWORD=password,
                                                                           TOKEN=token)
                        result = CsHelper.execute(update_command)
                        logging.debug("Update password server result ==> %s" %
                                      result)
                        return result

                    test_tries += 1
                    self.logger.debug(
                        "Testing password server process round %s/%s" %
                        (test_tries, max_tries))
                    time.sleep(2)

                logging.debug(
                    "Update password server skipped because we didn't find a passwd server process for "
                    "%s (makes sense on backup routers)" % ip)
Exemple #28
0
 def _disable_radvd(self, dev):
     """
     Disable radvd for non-primary VR
     """
     if dev == '':
         return
     CsHelper.service("radvd", "stop")
     CsHelper.service("radvd", "disable")
     logging.info(CsHelper.execute("systemctl status radvd"))
Exemple #29
0
 def find_pid(self):
     self.pid = []
     for i in CsHelper.execute("ps aux"):
         items = len(self.search)
         proc = re.split("\s+", i)[items*-1:]
         matches = len([m for m in proc if m in self.search])
         if matches == items:
             self.pid.append(re.split("\s+", i)[1])
     return self.pid
    def compare(self, list):
        """ Compare reality with what is needed """
        for c in self.chain.get("filter"):
            # Ensure all inbound/outbound chains have a default drop rule
            if c.startswith("ACL_INBOUND") or c.startswith("ACL_OUTBOUND"):
                list.append(["filter", "", "-A %s -j DROP" % c])
        # PASS 1:  Ensure all chains are present
        for fw in list:
            new_rule = CsNetfilter()
            new_rule.parse(fw[2])
            new_rule.set_table(fw[0])
            self.add_chain(new_rule)
        # PASS 2: Create rules
        for fw in list:
            new_rule = CsNetfilter()
            new_rule.parse(fw[2])
            new_rule.set_table(fw[0])
            if isinstance(fw[1], int):
                new_rule.set_count(fw[1])

            logging.debug(
                "Checking if the rule already exists: rule=%s table=%s chain=%s",
                new_rule.get_rule(), new_rule.get_table(),
                new_rule.get_chain())
            if self.has_rule(new_rule):
                logging.debug("Exists: rule=%s table=%s", fw[2],
                              new_rule.get_table())
            else:
                # print "Add rule %s in table %s" % ( fw[2], new_rule.get_table())
                logging.info("Add: rule=%s table=%s", fw[2],
                             new_rule.get_table())
                # front means insert instead of append
                cpy = fw[2]
                if fw[1] == "front":
                    cpy = cpy.replace('-A', '-I')
                if isinstance(fw[1], int):
                    cpy = cpy.replace(
                        "-A %s" % new_rule.get_chain(),
                        '-I %s %s' % (new_rule.get_chain(), fw[1]))

                CsHelper.execute("iptables -t %s %s" %
                                 (new_rule.get_table(), cpy))
        self.del_standard()
        self.get_unseen()
Exemple #31
0
    def process(self):
        route = CsRoute()

        for dev in self.dbag:
            if dev == "id":
                continue
            ip = CsIP(dev, self.config)

            for address in self.dbag[dev]:
                if(address["nw_type"]!="public"):
                    continue

                #check if link is up
                if (not self.check_if_link_exists(dev)):
                    logging.info("link %s does not exist, so not processing"%dev)
                    continue
                if not self.check_if_link_up(dev):
                   cmd="ip link set %s up"%dev
                   CsHelper.execute(cmd)

                network = str(address["network"])

                ip.setAddress(address)

                if ip.configured():
                    logging.info(
                        "Address %s on device %s already configured", ip.ip(), dev)

                    ip.post_configure()

                else:
                    logging.info(
                        "Address %s on device %s not configured", ip.ip(), dev)
                    if CsDevice(dev, self.config).waitfordevice():
                        ip.configure()
                route.add_route(dev, network)

        # once we start processing public ip's we need to verify there
        # is a default route and add if needed
        if not route.defaultroute_exists():
            cmdline=self.config.get_cmdline_instance()
            if(cmdline.get_gateway()):
                route.add_defaultroute(cmdline.get_gateway())
Exemple #32
0
    def find_pid(self):
        self.pid = []
        for i in CsHelper.execute("ps aux"):
            items = len(self.search)
            proc = re.split(r"\s+", i)[items*-1:]
            matches = len([m for m in proc if m in self.search])
            if matches == items:
                self.pid.append(re.split(r"\s+", i)[1])

        logging.debug("CsProcess:: Searching for process ==> %s and found PIDs ==> %s", self.search, self.pid)
        return self.pid
Exemple #33
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("Setting router to fault")

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

        interfaces = [
            interface for interface in self.address.get_interfaces()
            if interface.needs_vrrp()
        ]
        for interface in interfaces:
            CsPasswdSvc(interface.get_gateway() + "," +
                        interface.get_ip()).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)
Exemple #34
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")
Exemple #35
0
    def delete_leases(self):
        macs_dhcphosts = []
        try:
            logging.info("Attempting to delete entries from dnsmasq.leases file for VMs which are not on dhcphosts file")
            for host in open(DHCP_HOSTS):
                macs_dhcphosts.append(host.split(',')[0])

            removed = 0
            for leaseline in open(LEASES):
                lease = leaseline.split(' ')
                mac = lease[1]
                ip = lease[2]
                if mac not in macs_dhcphosts:
                    cmd = "dhcp_release $(ip route get %s | grep eth | head -1 | awk '{print $3}') %s %s" % (ip, ip, mac)
                    logging.info(cmd)
                    CsHelper.execute(cmd)
                    removed = removed + 1
                    self.del_host(ip)
            logging.info("Deleted %s entries from dnsmasq.leases file" % str(removed))
        except Exception as e:
            logging.error("Caught error while trying to delete entries from dnsmasq.leases file: %s" % e)
Exemple #36
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
     """
     self.set_lock()
     logging.debug("Setting router to master")
     ads = [o for o in self.address.get_ips() if o.is_public()]
     dev = ''
     for o in ads:
         if dev == o.get_device():
             continue
         cmd2 = "ip link set %s up" % o.get_device()
         if CsDevice(o.get_device(), self.config).waitfordevice():
             CsHelper.execute(cmd2)
             dev = o.get_device()
             logging.info("Bringing public interface %s up" % o.get_device())
         else:
             logging.error("Device %s was not ready could not bring it up" % o.get_device())
     # 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")
Exemple #37
0
    def defaultroute_exists(self):
        """ Return True if a default route is present
        :return: bool
        """
        logging.info("Checking if default ipv4 route is present")
        route_found = CsHelper.execute("ip -4 route list 0/0")

        if len(route_found) > 0:
            logging.info("Default route found: " + route_found[0])
            return True
        else:
            logging.warn("No default route found!")
            return False
    def defaultroute_exists(self):
        """ Return True if a default route is present
        :return: bool
        """
        logging.info("Checking if default ipv4 route is present")
        route_found = CsHelper.execute("ip -4 route list 0/0")

        if len(route_found) > 0:
            logging.info("Default route found: " + route_found[0])
            return True
        else:
            logging.warn("No default route found!")
            return False
    def find_pid(self):
        self.pid = []
        items = len(self.search)
        for i in CsHelper.execute("ps aux"):
            proc = re.split(r"\s+", i)[10:]
            matches = len([m for m in proc if m in self.search])
            if matches == items:
                self.pid.append(re.split(r"\s+", i)[1])

        logging.debug(
            "CsProcess:: Searching for process ==> %s and found PIDs ==> %s",
            self.search, self.pid)
        return self.pid
 def get_all_rules(self):
     for i in CsHelper.execute("iptables-save"):
         if i.startswith('*'):  # Table
             self.table.add(i[1:])
         if i.startswith(':'):  # Chain
             self.chain.add(self.table.last(), i[1:].split(' ')[0])
         if i.startswith('-A'):  # Rule
             self.chain.add_rule(i.split()[1])
             rule = CsNetfilter()
             rule.parse(i)
             rule.set_table(self.table.last())
             rule.set_chain(i.split()[1])
             rule.set_count(self.chain.get_count(i.split()[1]))
             self.save(rule)
Exemple #41
0
 def get_all_rules(self):
     for i in CsHelper.execute("iptables-save"):
         if i.startswith('*'):  # Table
             self.table.add(i[1:])
         if i.startswith(':'):  # Chain
             self.chain.add(self.table.last(), i[1:].split(' ')[0])
         if i.startswith('-A'):  # Rule
             self.chain.add_rule(i.split()[1])
             rule = CsNetfilter()
             rule.parse(i)
             rule.set_table(self.table.last())
             rule.set_chain(i.split()[1])
             rule.set_count(self.chain.get_count(i.split()[1]))
             self.save(rule)
    def __update(self, vm_ip, password):
        token = ""
        try:
            token_file = open(self.TOKEN_FILE)
            token = token_file.read()
        except IOError:
            logging.debug("File %s does not exist" % self.TOKEN_FILE)

        logging.debug("Got VM '%s' and password '%s'" % (vm_ip, password))
        get_cidrs_cmd = "ip addr show | grep inet | grep -v secondary | awk '{print $2}'"
        cidrs = CsHelper.execute(get_cidrs_cmd)
        logging.debug("Found these CIDRs: %s" % cidrs)
        for cidr in cidrs:
            logging.debug("Processing CIDR '%s'" % cidr)
            if CsHelper.IPAddress(vm_ip) in CsHelper.IPNetwork(cidr):
                ip = cidr.split('/')[0]
                logging.debug(
                    "Cidr %s matches vm ip address %s so adding passwd to passwd server at %s" % (cidr, vm_ip, ip))
                proc = CsProcess(['/opt/cosmic/router/bin/passwd_server_ip.py', ip])

                max_tries = 5
                test_tries = 0
                while test_tries < max_tries:
                    logging.debug("Updating passwd server on %s" % ip)
                    if proc.find():
                        url = "http://{SERVER_IP}:8080/".format(SERVER_IP=ip)
                        headers = {'DomU_Request': 'save_password'}
                        params = {'ip': vm_ip, 'password': password, 'token': token}
                        req = urllib2.Request(url, urllib.urlencode(params), headers=headers)
                        try:
                            res = urllib2.urlopen(req)
                            if res.getcode() == 200:
                                logging.debug("Update password server result ==> %s" % res.read())
                                return 0
                        except Exception as e:
                            logging.debug("Error while querying password server ==> %s" % e.message)
                            return 1


                    test_tries += 1
                    logging.debug("Testing password server process round %s/%s" % (test_tries, max_tries))
                    time.sleep(2)

                logging.debug("Update password server skipped because we didn't find a passwd server process for "
                              "%s (makes sense on backup routers)" % ip)
                return 1

        # on a non-master router no passwords to set, so we finish with success
        return 0
Exemple #43
0
    def list(self):
        self.iplist = {}
        cmd = ("ip addr show dev " + self.dev)
        for i in CsHelper.execute(cmd):
            vals = i.lstrip().split()
            if (vals[0] == 'inet'):
                
                cidr = vals[1]
                for ip, device in self.iplist.iteritems():
                    logging.info(
                                 "Iterating over the existing IPs. CIDR to be configured ==> %s, existing IP ==> %s on device ==> %s",
                                 cidr, ip, device)

                    if cidr[0] != ip[0] and device != self.dev:
                        self.iplist[cidr] = self.dev
Exemple #44
0
    def list(self):
        self.iplist = {}
        cmd = ("ip addr show dev " + self.dev)
        for i in CsHelper.execute(cmd):
            vals = i.lstrip().split()
            if (vals[0] == 'inet'):
                
                cidr = vals[1]
                for ip, device in self.iplist.iteritems():
                    logging.info(
                                 "Iterating over the existing IPs. CIDR to be configured ==> %s, existing IP ==> %s on device ==> %s",
                                 cidr, ip, device)

                    if cidr[0] != ip[0] and device != self.dev:
                        self.iplist[cidr] = self.dev
Exemple #45
0
    def process(self):
        for dev in self.dbag:
            if dev == "id":
                continue
            ip = CsIP(dev, self.config)

            for address in self.dbag[dev]:
                #check if link is up
                if not self.check_if_link_up(dev):
                   cmd="ip link set %s up" % dev
                   CsHelper.execute(cmd)

                ip.setAddress(address)

                if ip.configured():
                    logging.info(
                        "Address %s on device %s already configured", ip.ip(), dev)

                    ip.post_configure(address)
                else:
                    logging.info(
                        "Address %s on device %s not configured", ip.ip(), dev)
                    if CsDevice(dev, self.config).waitfordevice():
                        ip.configure(address)
Exemple #46
0
    def apply_rules(self):
        s = []
        for r in self.iptablerules:
            r.replace('  ', ' ')  # Remove duplicate spaces
            if r not in s:
                s.append(r)

        chains = Tables(s)
        chains.table_printout()

        # COMMIT all rules.
        result = CsHelper.execute("iptables-restore < /tmp/rules.save")
        if result:
            logging.info("iptables-restore result: %s", result)
        else:
            logging.info("iptables-restore result: success!")
Exemple #47
0
 def add_address_route(self, entry):
     if 'router_guest_ip6' in entry.keys() and entry['router_guest_ip6']:
         self.enable_ipv6(entry['device'])
         cidr_size = entry['router_guest_ip6_cidr'].split("/")[-1]
         full_addr = entry['router_guest_ip6_gateway'] + "/" + cidr_size
         if not CsHelper.execute("ip -6 addr show dev %s | grep -w %s" %
                                 (entry['device'], full_addr)):
             CsHelper.execute("ip -6 addr add %s dev %s" %
                              (full_addr, entry['device']))
         if 'router_ip6' in entry.keys() and entry['router_ip6']:
             self.__disable_dad(VPC_PUBLIC_INTERFACE)
             full_public_addr = entry['router_ip6'] + "/" + cidr_size
             if not CsHelper.execute(
                     "ip -6 addr show dev %s | grep -w %s" %
                 (VPC_PUBLIC_INTERFACE, full_public_addr)):
                 CsHelper.execute("ip -6 addr add %s dev %s" %
                                  (full_public_addr, VPC_PUBLIC_INTERFACE))
             if not CsHelper.execute("ip -6 route list default via %s" %
                                     entry['router_ip6_gateway']):
                 CsHelper.execute("ip -6 route add default via %s" %
                                  entry['router_ip6_gateway'])
     else:
         return
Exemple #48
0
    def add_defaultroute_v6(self, gateway):
        """  Add a default route
        # for example, ip -6 route add default via fd80:20:20:20::1
        :param str gateway
        :return: bool
        """
        if not gateway:
            raise Exception("Gateway cannot be None.")

        logging.info("Checking if default ipv6 route is present")
        route_found = CsHelper.execute("ip -6 route list default")
        if len(route_found) > 0:
            logging.info("Default IPv6 route found: " + route_found[0])
            return False
        else:
            cmd = "default via " + gateway
            logging.info("Adding default IPv6 route")
            self.set_route_v6(cmd)
            return True
Exemple #49
0
    def _redundant_on(self):
        guest = self.address.get_guest_if()
        # No redundancy if there is no guest network
        if self.cl.is_master() or guest is None:
            for obj in [o for o in self.address.get_ips() if o.is_public()]:
                self.check_is_up(obj.get_device())
        if guest is None:
            self._redundant_off()
            return
        CsHelper.mkdir(self.CS_RAMDISK_DIR, 0755, False)
        CsHelper.mount_tmpfs(self.CS_RAMDISK_DIR)
        CsHelper.mkdir(self.CS_ROUTER_DIR, 0755, False)
        for s in self.CS_TEMPLATES:
            d = s
            if s.endswith(".templ"):
                d = s.replace(".templ", "")
            CsHelper.copy_if_needed("%s/%s" % (self.CS_TEMPLATES_DIR, s), "%s/%s" % (self.CS_ROUTER_DIR, d))
        CsHelper.copy_if_needed("%s/%s" % (self.CS_TEMPLATES_DIR, "keepalived.conf.templ"), self.KEEPALIVED_CONF)
        CsHelper.copy_if_needed("%s/%s" % (self.CS_TEMPLATES_DIR, "conntrackd.conf.templ"), self.CONNTRACKD_CONF)
        CsHelper.copy_if_needed("%s/%s" % (self.CS_TEMPLATES_DIR, "checkrouter.sh.templ"), "/opt/cloud/bin/checkrouter.sh")

        CsHelper.execute('sed -i "s/--exec\ \$DAEMON;/--exec\ \$DAEMON\ --\ --vrrp;/g" /etc/init.d/keepalived')
        # checkrouter.sh configuration
        file = CsFile("/opt/cloud/bin/checkrouter.sh")
        file.greplace("[RROUTER_LOG]", self.RROUTER_LOG)
        file.commit()

        # keepalived configuration
        file = CsFile(self.KEEPALIVED_CONF)
        ads = [o for o in self.address.get_ips() if o.is_public()]
        # Add a comment for each public IP.  If any change this will cause keepalived to restart
        # As things stand keepalived will be configured before the IP is added or deleted
        i = 0
        for o in ads:
            file.addeq("! %s=%s" % (i, o.get_cidr()))
            i = i + 1
        file.search(" router_id ", "    router_id %s" % self.cl.get_name())
        file.search(" priority ", "    priority %s" % self.cl.get_priority())
        file.search(" interface ", "    interface %s" % guest.get_device())
        file.search(" state ", "    state %s" % "EQUAL")
        file.search(" virtual_router_id ", "    virtual_router_id %s" % self.cl.get_router_id())
        file.greplace("[RROUTER_BIN_PATH]", self.CS_ROUTER_DIR)
        file.section("authentication {", "}", ["        auth_type AH \n", "        auth_pass %s\n" % self.cl.get_router_password()])
        file.section("virtual_ipaddress {", "}", self._collect_ips())
        file.commit()

        # conntrackd configuration
        connt = CsFile(self.CONNTRACKD_CONF)
        if guest is not None:
            connt.section("Multicast {", "}", [
                          "IPv4_address 225.0.0.50\n",
                          "Group 3780\n",
                          "IPv4_interface %s\n" % guest.get_ip(),
                          "Interface %s\n" % guest.get_device(),
                          "SndSocketBuffer 1249280\n",
                          "RcvSocketBuffer 1249280\n",
                          "Checksum on\n"])
            connt.section("Address Ignore {", "}", self._collect_ignore_ips())
            connt.commit()

        if connt.is_changed():
            CsHelper.service("conntrackd", "restart")

        if file.is_changed():
            CsHelper.service("keepalived", "reload")

        # Configure heartbeat cron job
        cron = CsFile("/etc/cron.d/heartbeat")
        cron.add("SHELL=/bin/bash", 0)
        cron.add("PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin", 1)
        cron.add("*/1 * * * * root $SHELL %s/check_heartbeat.sh 2>&1 > /dev/null" % self.CS_ROUTER_DIR, -1)
        cron.commit()

        proc = CsProcess(['/usr/sbin/keepalived', '--vrrp'])
        if not proc.find():
            CsHelper.service("keepalived", "restart")
 def add_chain(self, rule):
     """ Add the given chain if it is not already present """
     if not self.has_chain(rule.get_table(), rule.get_chain()):
         CsHelper.execute("iptables -t %s -N %s" %
                          (rule.get_table(), rule.get_chain()))
         self.chain.add(rule.get_table(), rule.get_chain())
Exemple #51
0
 def flush(self):
     CsHelper.execute("ip route flush table %s" % (self.table))
     CsHelper.execute("ip route flush cache")
 def flush_table(self, tablename):
     CsHelper.execute("ip route flush table %s" % (tablename))
     CsHelper.execute("ip route flush cache")
 def findRule(self, rule):
     for i in CsHelper.execute("ip rule show"):
         if rule in i.strip():
             return True
     return False
Exemple #54
0
 def arpPing(self):
     if not self.address['gateway'] or self.address['gateway'] == 'None':
         return
     cmd = "arping -c 1 -I %s -A -U -s %s %s" % (
         self.dev, self.address['public_ip'], self.address['gateway'])
     CsHelper.execute(cmd, wait=False)
Exemple #55
0
 def arpPing(self):
     cmd = "arping -c 1 -I %s -A -U -s %s %s" % (
         self.dev, self.address['public_ip'], self.address['gateway'])
     CsHelper.execute(cmd)
    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'])
                ])
Exemple #57
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")
Exemple #58
0
    def _redundant_on(self):
        guest = self.address.get_guest_if()

        # No redundancy if there is no guest network
        if guest is None:
            self.set_backup()
            self._redundant_off()
            return

        interfaces = [
            interface for interface in self.address.get_interfaces()
            if interface.is_guest()
        ]
        isDeviceReady = False
        dev = ''
        for interface in interfaces:
            if dev == interface.get_device():
                continue
            dev = interface.get_device()
            logging.info(
                "Wait for devices to be configured so we can start keepalived")
            devConfigured = CsDevice(dev, self.config).waitfordevice()
            if devConfigured:
                command = "ip link show %s | grep 'state UP'" % dev
                devUp = CsHelper.execute(command)
                if devUp:
                    logging.info(
                        "Device %s is present, let's start keepalived now." %
                        dev)
                    isDeviceReady = True

        if not isDeviceReady:
            logging.info(
                "Guest network not configured yet, let's stop router redundancy for now."
            )
            CsHelper.service("conntrackd", "stop")
            CsHelper.service("keepalived", "stop")
            return

        CsHelper.mkdir(self.CS_RAMDISK_DIR, 0755, False)
        CsHelper.mount_tmpfs(self.CS_RAMDISK_DIR)
        CsHelper.mkdir(self.CS_ROUTER_DIR, 0755, False)
        for s in self.CS_TEMPLATES:
            d = s
            if s.endswith(".templ"):
                d = s.replace(".templ", "")
            CsHelper.copy_if_needed("%s/%s" % (self.CS_TEMPLATES_DIR, s),
                                    "%s/%s" % (self.CS_ROUTER_DIR, d))

        CsHelper.copy_if_needed(
            "%s/%s" % (self.CS_TEMPLATES_DIR, "keepalived.conf.templ"),
            self.KEEPALIVED_CONF)
        CsHelper.copy_if_needed(
            "%s/%s" % (self.CS_TEMPLATES_DIR, "checkrouter.sh.templ"),
            "/opt/cloud/bin/checkrouter.sh")

        CsHelper.execute(
            'sed -i "s/--exec $DAEMON;/--exec $DAEMON -- --vrrp;/g" /etc/init.d/keepalived'
        )
        # checkrouter.sh configuration
        check_router = CsFile("/opt/cloud/bin/checkrouter.sh")
        check_router.greplace("[RROUTER_LOG]", self.RROUTER_LOG)
        check_router.commit()

        # keepalived configuration
        keepalived_conf = CsFile(self.KEEPALIVED_CONF)
        keepalived_conf.search(" router_id ",
                               "    router_id %s" % self.cl.get_name())
        keepalived_conf.search(" interface ",
                               "    interface %s" % guest.get_device())
        keepalived_conf.search(" advert_int ",
                               "    advert_int %s" % self.cl.get_advert_int())

        keepalived_conf.greplace("[RROUTER_BIN_PATH]", self.CS_ROUTER_DIR)
        keepalived_conf.section("authentication {", "}", [
            "        auth_type AH \n",
            "        auth_pass %s\n" % self.cl.get_router_password()[:8]
        ])
        keepalived_conf.section("virtual_ipaddress {", "}",
                                self._collect_ips())

        # conntrackd configuration
        conntrackd_template_conf = "%s/%s" % (self.CS_TEMPLATES_DIR,
                                              "conntrackd.conf.templ")
        conntrackd_temp_bkp = "%s/%s" % (self.CS_TEMPLATES_DIR,
                                         "conntrackd.conf.templ.bkp")

        CsHelper.copy(conntrackd_template_conf, conntrackd_temp_bkp)

        conntrackd_tmpl = CsFile(conntrackd_template_conf)
        conntrackd_tmpl.section("Multicast {", "}", [
            "IPv4_address 225.0.0.50\n", "Group 3780\n",
            "IPv4_interface %s\n" % guest.get_ip(),
            "Interface %s\n" % guest.get_device(), "SndSocketBuffer 1249280\n",
            "RcvSocketBuffer 1249280\n", "Checksum on\n"
        ])
        conntrackd_tmpl.section("Address Ignore {", "}",
                                self._collect_ignore_ips())
        conntrackd_tmpl.commit()

        conntrackd_conf = CsFile(self.CONNTRACKD_CONF)

        is_equals = conntrackd_tmpl.compare(conntrackd_conf)

        force_keepalived_restart = False
        proc = CsProcess(['/etc/conntrackd/conntrackd.conf'])

        if not proc.find() or not is_equals:
            CsHelper.copy(conntrackd_template_conf, self.CONNTRACKD_CONF)
            CsHelper.service("conntrackd", "restart")
            force_keepalived_restart = True

        # Restore the template file and remove the backup.
        CsHelper.copy(conntrackd_temp_bkp, conntrackd_template_conf)
        CsHelper.execute("rm -rf %s" % conntrackd_temp_bkp)

        # Configure heartbeat cron job - runs every 30 seconds
        heartbeat_cron = CsFile("/etc/cron.d/heartbeat")
        heartbeat_cron.add("SHELL=/bin/bash", 0)
        heartbeat_cron.add(
            "PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin",
            1)
        heartbeat_cron.add(
            "* * * * * root $SHELL %s/check_heartbeat.sh 2>&1 > /dev/null" %
            self.CS_ROUTER_DIR, -1)
        heartbeat_cron.add(
            "* * * * * root sleep 30; $SHELL %s/check_heartbeat.sh 2>&1 > /dev/null"
            % self.CS_ROUTER_DIR, -1)
        heartbeat_cron.commit()

        proc = CsProcess(['/usr/sbin/keepalived'])
        if not proc.find():
            force_keepalived_restart = True
        if keepalived_conf.is_changed() or force_keepalived_restart:
            keepalived_conf.commit()
            os.chmod(self.KEEPALIVED_CONF, 0o644)
            if force_keepalived_restart or not self.cl.is_primary():
                CsHelper.service("keepalived", "restart")
            else:
                CsHelper.service("keepalived", "reload")