예제 #1
0
def main():
    """Entry point."""
    options = parse()
    setup_logging(options.debug, options.silent, options.name,
                  options.syslog_facility, not options.no_syslog)
    if options.pid:
        options.pid.write("{0}\n".format(os.getpid()))
        options.pid.close()
    try:
        # Setup IP to use
        options.ips = options.ips or loopback_ips(options.label, False)
        if not options.ips:
            logger.error("No IP found")
            sys.exit(1)
        if options.ip_setup:
            setup_ips(options.ips, options.label, options.sudo)
        drop_privileges(options.user, options.group)

        # Parse defined networks into a list of IPs for advertisement
        if options.deaggregate_networks:
            options.ips = [ip_network(ip) for net in options.ips for ip in net]

        options.ips = collections.deque(options.ips)
        options.ips.rotate(-options.start_ip)
        options.ips = list(options.ips)
        # Main loop
        loop(options)
    except Exception as e:  # pylint: disable=W0703
        logger.exception("Uncaught exception: %s", e)
        sys.exit(1)
예제 #2
0
def loopback_ips(label, label_only):
    """Retrieve loopback IP addresses"""
    logger.debug("Retrieve loopback IP addresses")
    addresses = []

    if sys.platform.startswith("linux"):
        # Use "ip" (ifconfig is not able to see all addresses)
        ipre = re.compile(r"^(?P<index>\d+):\s+(?P<name>\S+)\s+inet6?\s+"
                          r"(?P<ip>[\da-f.:]+)/(?P<mask>\d+)\s+.*")
        labelre = re.compile(r".*\s+lo:(?P<label>\S+).*")
        cmd = subprocess.Popen("/sbin/ip -o address show dev lo".split(),
                               shell=False,
                               stdout=subprocess.PIPE)
    else:
        # Try with ifconfig
        ipre = re.compile(r"^inet6?\s+(alias\s+)?(?P<ip>[\da-f.:]+)\s+"
                          r"(?:netmask 0x(?P<netmask>[0-9a-f]+)|"
                          r"prefixlen (?P<mask>\d+)).*")
        cmd = subprocess.Popen("/sbin/ifconfig lo0".split(),
                               shell=False,
                               stdout=subprocess.PIPE)
        labelre = re.compile(r"")
    for line in cmd.stdout:
        line = line.decode("ascii", "ignore").strip()
        mo = ipre.match(line)
        if not mo:
            continue
        if mo.group("mask"):
            mask = int(mo.group("mask"))
        else:
            mask = bin(int(mo.group("netmask"), 16)).count("1")
        try:
            ip = ip_network("{0}/{1}".format(mo.group("ip"), mask))
        except ValueError:
            continue
        if not ip.is_loopback:
            if label:
                lmo = labelre.match(line)
                if not lmo:
                    continue
                if lmo.groupdict().get("label", "").startswith(label):
                    addresses.append(ip)
            elif not label_only:
                addresses.append(ip)

    logger.debug("Loopback addresses: %s", addresses)
    return addresses
예제 #3
0
def remove_ips(ips, label, sudo=False):
    """Remove added IP on loopback interface"""
    existing = set(loopback_ips(label, True))

    # Get intersection of IPs (ips setup, and IPs configured by ExaBGP)
    toremove = set([ip_network(ip) for net in ips for ip in net]) & existing
    for ip in toremove:
        logger.debug("Remove loopback IP address %s", ip)
        with open(os.devnull, "w") as fnull:
            cmd = ["ip", "address", "delete", str(ip), "dev", loopback()]
            if sudo:
                cmd.insert(0, "sudo")
            if label:
                cmd += ["label", "{0}:{1}".format(loopback(), label)]
            try:
                subprocess.check_call(cmd, stdout=fnull, stderr=fnull)
            except subprocess.CalledProcessError:
                logger.warn(
                    "Unable to remove loopback IP address %s - is \
                    healthcheck running as root?", str(ip))
예제 #4
0
def setup_ips(ips, label, sudo=False):
    """Setup missing IP on loopback interface"""

    existing = set(loopback_ips(label, False))
    toadd = set([ip_network(ip) for net in ips for ip in net]) - existing
    for ip in toadd:
        logger.debug("Setup loopback IP address %s", ip)
        with open(os.devnull, "w") as fnull:
            cmd = ["ip", "address", "add", str(ip), "dev", loopback()]
            if sudo:
                cmd.insert(0, "sudo")
            if label:
                cmd += ["label", "{0}:{1}".format(loopback(), label)]
                try:
                    subprocess.check_call(cmd, stdout=fnull, stderr=fnull)
                except subprocess.CalledProcessError as e:
                    # the IP address is already setup, ignoring
                    if cmd[0] == "ip" and cmd[2] == "add" and e.returncode == 2:
                        continue
                    raise e