Example #1
0
def validate_arguments(arguments):
    """
    Validate argument values:
        <PEER_IP>
        <AS_NUM>

    Arguments not validated:

    :param arguments: Docopt processed arguments
    """
    # Validate IPs
    peer_ip_ok = arguments.get("<PEER_IP>") is None or \
                    validate_ip(arguments["<PEER_IP>"], 4) or \
                    validate_ip(arguments["<PEER_IP>"], 6)
    asnum_ok = True
    asnum = arguments.get("<AS_NUM>")
    if asnum:
        asnum_ok = validate_asn(asnum)

    # Print error messages
    if not peer_ip_ok:
        print "Invalid IP address specified."
    if not asnum_ok:
        print "Invalid AS Number specified."

    # Exit if not valid arguments
    if not (peer_ip_ok and asnum_ok):
        sys.exit(1)
Example #2
0
def validate_arguments(arguments):
    """
    Validate argument values:
        <PEER_IP>
        <AS_NUM>

    Arguments not validated:

    :param arguments: Docopt processed arguments
    """
    # Validate IPs
    peer_ip_ok = arguments.get("<PEER_IP>") is None or \
                    validate_ip(arguments["<PEER_IP>"], 4) or \
                    validate_ip(arguments["<PEER_IP>"], 6)
    asnum_ok = True
    asnum = arguments.get("<AS_NUM>")
    if asnum:
        asnum_ok = validate_asn(asnum)

    # Print error messages
    if not peer_ip_ok:
        print "Invalid IP address specified."
    if not asnum_ok:
        print "Invalid AS Number specified."

    # Exit if not valid arguments
    if not (peer_ip_ok and asnum_ok):
        sys.exit(1)
Example #3
0
    def test_validate_asn(self, input_str, expected_result):
        """
        Test validate_asn function
        """
        test_result = util.validate_asn(input_str)

        self.assertEqual(test_result, expected_result)
Example #4
0
def main():
    # If we're running with the k8s backend, don't do any of this,
    # since it currently doesn't support BGP, Calico IPAM, and doesn't
    # require any of the etcd interactions below.
    if os.getenv("DATASTORE_TYPE", "") == "kubernetes":
        print "Using k8s backend"
        with open('startup.env', 'w') as f:
            f.write("DATASTORE_TYPE=kubernetes\n")
            f.write("HOSTNAME=%s\n" % hostname)
        return

    # Check to see if etcd is available.  If not, wait until it is before
    # continuing.  This is to avoid etcd / node startup race conditions.
    print "Waiting for etcd connection..."
    while os.getenv("WAIT_FOR_DATASTORE", "false") == "true":
        try:
            # Just try accessing etcd to see if we can reach it or not.
            client.get_host_as(hostname)
        except DataStoreError:
            # Not connected to etcd yet, wait a bit.
            time.sleep(1)
            continue
        else:
            # Connected to etcd - break out of loop.
            print "Connected to etcd"
            break

    # Start node.
    ip = os.getenv("IP")
    ip = ip or None
    if ip and not netaddr.valid_ipv4(ip):
        print "IP environment (%s) is not a valid IPv4 address." % ip
        sys.exit(1)

    ip6 = os.getenv("IP6")
    ip6 = ip6 or None
    if ip6 and not netaddr.valid_ipv6(ip6):
        print "IP6 environment (%s) is not a valid IPv6 address." % ip6
        sys.exit(1)

    as_num = os.getenv("AS")
    as_num = as_num or None
    if as_num and not validate_asn(as_num):
        print "AS environment (%s) is not a AS number." % as_num
        sys.exit(1)

    # Get IP address of host, if none was specified
    if not ip:
        ips = get_host_ips(exclude=[
            "^docker.*", "^cbr.*", "virbr.*", "lxcbr.*", "veth.*", "cali.*",
            "tunl.*", "flannel.*"
        ])
        try:
            ip = str(ips.pop())
        except IndexError:
            print "Couldn't autodetect a management IP address. Please " \
                  "provide an IP address by rerunning the container with the" \
                  " IP environment variable set."
            sys.exit(1)
        else:
            print "No IP provided. Using detected IP: %s" % ip

    # Write a startup environment file containing the IP address that may have
    # just been detected.
    # This is required because the confd templates expect to be able to fill in
    # some templates by fetching them from the environment.
    with open('startup.env', 'w') as f:
        f.write("IP=%s\n" % ip)
        f.write("HOSTNAME=%s\n" % hostname)

    warn_if_hostname_conflict(ip)

    # Verify that IPs are not already in use by another host.
    error_if_bgp_ip_conflict(ip, ip6)

    # Verify that the chosen IP exists on the current host
    warn_if_unknown_ip(ip, ip6)

    if os.getenv("NO_DEFAULT_POOLS", "").lower() != "true":
        # Set up etcd
        ipv4_pools = client.get_ip_pools(4)
        ipv6_pools = client.get_ip_pools(6)

        # Create default pools if required
        if not ipv4_pools:
            client.add_ip_pool(4, DEFAULT_IPV4_POOL)

        # If the OS has not been built with IPv6 then the /proc config for IPv6
        # will not be present.
        if not ipv6_pools and os.path.exists('/proc/sys/net/ipv6'):
            client.add_ip_pool(6, DEFAULT_IPV6_POOL)

    client.ensure_global_config()
    client.create_host(hostname, ip, ip6, as_num)

    # If IPIP is enabled, the host requires an IP address for its tunnel
    # device, which is in an IPIP pool.  Without this, a host can't originate
    # traffic to a pool address because the response traffic would not be
    # routed via the tunnel (likely being dropped by RPF checks in the fabric).
    ipv4_pools = client.get_ip_pools(4)
    ipip_pools = [p for p in ipv4_pools if p.ipip]

    if ipip_pools:
        # IPIP is enabled, make sure the host has an address for its tunnel.
        _ensure_host_tunnel_addr(ipv4_pools, ipip_pools)
    else:
        # No IPIP pools, clean up any old address.
        _remove_host_tunnel_addr()
def main():
    # If we're running with the k8s backend, don't do any of this,
    # since it currently doesn't support BGP, Calico IPAM, and doesn't
    # require any of the etcd interactions below.
    if os.getenv("DATASTORE_TYPE", "") == "kubernetes":
        print "Using k8s backend"
        with open("startup.env", "w") as f:
            f.write("export DATASTORE_TYPE=kubernetes\n")
            f.write("export HOSTNAME=%s\n" % hostname)
        return

    # Check to see if etcd is available.  If not, wait until it is before
    # continuing.  This is to avoid etcd / node startup race conditions.
    print "Waiting for etcd connection..."
    while os.getenv("WAIT_FOR_DATASTORE", "false") == "true":
        try:
            # Just try accessing etcd to see if we can reach it or not.
            client.get_host_as(hostname)
        except DataStoreError:
            # Not connected to etcd yet, wait a bit.
            time.sleep(1)
            continue
        else:
            # Connected to etcd - break out of loop.
            print "Connected to etcd"
            break

    # Query the currently configured host IPs
    try:
        current_ip, current_ip6 = client.get_host_bgp_ips(hostname)
    except KeyError:
        current_ip, current_ip6 = None, None

    # Determine the IP addresses and AS Number to use
    ip = os.getenv("IP") or None
    if ip == "autodetect":
        # If explicitly requesting auto-detection, set the ip to None to force
        # auto-detection.  We print below if we are auto-detecting the IP.
        ip = None
    elif ip:
        if not netaddr.valid_ipv4(ip):
            print "IP environment (%s) is not a valid IPv4 address." % ip
            sys.exit(1)
        print "Using IPv4 address from IP environment: %s" % ip
    elif current_ip:
        print "Using configured IPv4 address: %s" % current_ip
        ip = current_ip

    # Get IP address of host, if none was specified or previously configured.
    if not ip:
        ips = get_host_ips(
            exclude=["^docker.*", "^cbr.*", "dummy.*", "virbr.*", "lxcbr.*", "veth.*", "cali.*", "tunl.*", "flannel.*"]
        )
        try:
            ip = str(ips.pop())
        except IndexError:
            print "Couldn't autodetect a management IPv4 address. Please " "provide an IP address either by configuring one in the " "node resource, or by re-running the container with the " "IP environment variable set."
            sys.exit(1)
        else:
            print "Using auto-detected IPv4 address: %s" % ip

    ip6 = os.getenv("IP6") or None
    if ip6:
        if not netaddr.valid_ipv6(ip6):
            print "IP6 environment (%s) is not a valid IPv6 address." % ip6
            sys.exit(1)
        print "Using IPv6 address from IP6 environment: %s" % ip6
    elif current_ip6:
        print "Using configured IPv6 address: %s" % current_ip6
        ip6 = current_ip6
    else:
        print "No IPv6 address configured"

    as_num = os.getenv("AS")
    if as_num:
        if not validate_asn(as_num):
            print "AS environment (%s) is not a valid AS number." % as_num
            sys.exit(1)
        print "Using AS number from AS environment: %s" % as_num
    else:
        as_num = client.get_host_as(hostname)
        if as_num:
            print "Using configured AS number: %s" % as_num
        else:
            print "Using global AS number"

    # Write a startup environment file containing the IP address that may have
    # just been detected.
    # This is required because the confd templates expect to be able to fill in
    # some templates by fetching them from the environment.
    with open("startup.env", "w") as f:
        f.write("export IP=%s\n" % ip)
        f.write("export HOSTNAME=%s\n" % hostname)

    warn_if_hostname_conflict(ip)

    # Verify that IPs are not already in use by another host.
    error_if_bgp_ip_conflict(ip, ip6)

    # Verify that the chosen IP exists on the current host
    warn_if_unknown_ip(ip, ip6)

    if os.getenv("NO_DEFAULT_POOLS", "").lower() != "true":
        # Set up etcd
        ipv4_pools = client.get_ip_pools(4)
        ipv6_pools = client.get_ip_pools(6)

        # Create default pools if required
        if not ipv4_pools:
            client.add_ip_pool(4, DEFAULT_IPV4_POOL)

        # If the OS has not been built with IPv6 then the /proc config for IPv6
        # will not be present.
        if not ipv6_pools and os.path.exists("/proc/sys/net/ipv6"):
            client.add_ip_pool(6, DEFAULT_IPV6_POOL)

    client.ensure_global_config()
    client.create_host(hostname, ip, ip6, as_num)

    # If IPIP is enabled, the host requires an IP address for its tunnel
    # device, which is in an IPIP pool.  Without this, a host can't originate
    # traffic to a pool address because the response traffic would not be
    # routed via the tunnel (likely being dropped by RPF checks in the fabric).
    ipv4_pools = client.get_ip_pools(4)
    ipip_pools = [p for p in ipv4_pools if p.ipip]

    if ipip_pools:
        # IPIP is enabled, make sure the host has an address for its tunnel.
        _ensure_host_tunnel_addr(ipv4_pools, ipip_pools)
    else:
        # No IPIP pools, clean up any old address.
        _remove_host_tunnel_addr()

    # Tell the user what the name of the node is.
    print "Calico node name: ", hostname
Example #6
0
def validate_arguments(arguments):
    """
    Validate argument values:
        <IP>
        <IP6>
        <PEER_IP>
        <AS_NUM>
        <DETACH>

    Arguments not validated:
        <DOCKER_IMAGE_NAME>
        <LOG_DIR>

    :param arguments: Docopt processed arguments
    """
    # Validate IPs
    ip_ok = arguments.get("--ip") is None or \
            arguments.get("--ip") is "" or \
            validate_ip(arguments.get("--ip"), 4)
    ip6_ok = arguments.get("--ip6") is None or \
             arguments.get("--ip6") is "" or \
             validate_ip(arguments.get("--ip6"), 6)
    container_ip_ok = arguments.get("<IP>") is None or \
                      validate_ip(arguments["<IP>"], 4) or \
                      validate_ip(arguments["<IP>"], 6)
    peer_ip_ok = arguments.get("<PEER_IP>") is None or \
                 validate_ip(arguments["<PEER_IP>"], 4) or \
                 validate_ip(arguments["<PEER_IP>"], 6)
    runtime_ok = arguments.get("--runtime") in [None, "none", "docker", "rkt"]

    asnum_ok = True
    asnum = arguments.get("<AS_NUM>") or arguments.get("--as")
    if asnum:
        asnum_ok = validate_asn(asnum)

    detach_ok = True
    if arguments.get("<DETACH>") or arguments.get("--detach"):
        detach_ok = arguments.get("--detach") in ["true", "false"]

    detach_libnetwork_ok = (arguments.get("--detach") == "true"
                            or not arguments.get("--libnetwork"))

    # Print error message
    if not ip_ok:
        print "Invalid IPv4 address specified with --ip argument."
    if not ip6_ok:
        print "Invalid IPv6 address specified with --ip6 argument."
    if not container_ip_ok or not peer_ip_ok:
        print "Invalid IP address specified."
    if not asnum_ok:
        print "Invalid AS Number specified."
    if not detach_ok:
        print "Valid values for --detach are 'true' and 'false'"
    if not detach_libnetwork_ok:
        print "The only valid value for --detach is 'true' when using libnetwork"
    if not runtime_ok:
        print "Runtime must be 'docker', 'rkt' or 'none'."

    # Exit if not valid argument
    if not (ip_ok and ip6_ok and container_ip_ok and peer_ip_ok and asnum_ok
            and detach_ok and detach_libnetwork_ok and runtime_ok):
        sys.exit(1)
Example #7
0
def main():
    # Check to see if etcd is available.  If not, wait until it is before
    # continuing.  This is to avoid etcd / node startup race conditions.
    print "Waiting for etcd connection..."
    while os.getenv("WAIT_FOR_DATASTORE", "false") == "true":
        try:
            # Just try accessing etcd to see if we can reach it or not.
            client.get_host_as(hostname)
        except DataStoreError:
            # Not connected to etcd yet, wait a bit.
            time.sleep(1)
            continue
        else:
            # Connected to etcd - break out of loop.
            print "Connected to etcd"
            break

    # Start node.
    ip = os.getenv("IP")
    ip = ip or None
    if ip and not netaddr.valid_ipv4(ip):
        print "IP environment (%s) is not a valid IPv4 address." % ip
        sys.exit(1)

    ip6 = os.getenv("IP6")
    ip6 = ip6 or None
    if ip6 and not netaddr.valid_ipv6(ip6):
        print "IP6 environment (%s) is not a valid IPv6 address." % ip6
        sys.exit(1)

    as_num = os.getenv("AS")
    as_num = as_num or None
    if as_num and not validate_asn(as_num):
        print "AS environment (%s) is not a AS number." % as_num
        sys.exit(1)

    # Get IP address of host, if none was specified
    if not ip:
        ips = get_host_ips(exclude=["^docker.*", "^cbr.*",
                                    "virbr.*", "lxcbr.*", "veth.*",
                                    "cali.*", "tunl.*", "flannel.*"])
        try:
            ip = str(ips.pop())
        except IndexError:
            print "Couldn't autodetect a management IP address. Please " \
                  "provide an IP address by rerunning the container with the" \
                  " IP environment variable set."
            sys.exit(1)
        else:
            print "No IP provided. Using detected IP: %s" % ip

    # Write a startup environment file containing the IP address that may have
    # just been detected.
    # This is required because the confd templates expect to be able to fill in
    # some templates by fetching them from the environment.
    with open('startup.env', 'w') as f:
        f.write("IP=%s\n" % ip)
        f.write("HOSTNAME=%s\n" % hostname)

    warn_if_hostname_conflict(ip)

    # Verify that IPs are not already in use by another host.
    error_if_bgp_ip_conflict(ip, ip6)

    # Verify that the chosen IP exists on the current host
    warn_if_unknown_ip(ip, ip6)

    if os.getenv("NO_DEFAULT_POOLS", "").lower() != "true":
        # Set up etcd
        ipv4_pools = client.get_ip_pools(4)
        ipv6_pools = client.get_ip_pools(6)

        # Create default pools if required
        if not ipv4_pools:
            client.add_ip_pool(4, DEFAULT_IPV4_POOL)

        # If the OS has not been built with IPv6 then the /proc config for IPv6
        # will not be present.
        if not ipv6_pools and os.path.exists('/proc/sys/net/ipv6'):
            client.add_ip_pool(6, DEFAULT_IPV6_POOL)

    client.ensure_global_config()
    client.create_host(hostname, ip, ip6, as_num)

    # If IPIP is enabled, the host requires an IP address for its tunnel
    # device, which is in an IPIP pool.  Without this, a host can't originate
    # traffic to a pool address because the response traffic would not be
    # routed via the tunnel (likely being dropped by RPF checks in the fabric).
    ipv4_pools = client.get_ip_pools(4)
    ipip_pools = [p for p in ipv4_pools if p.ipip]

    if ipip_pools:
        # IPIP is enabled, make sure the host has an address for its tunnel.
        _ensure_host_tunnel_addr(ipv4_pools, ipip_pools)
    else:
        # No IPIP pools, clean up any old address.
        _remove_host_tunnel_addr()
def main():
    ip = os.getenv("IP")
    ip = ip or None
    if ip and not netaddr.valid_ipv4(ip):
        print "IP environment (%s) is not a valid IPv4 address." % ip
        sys.exit(1)

    ip6 = os.getenv("IP6")
    ip6 = ip6 or None
    if ip6 and not netaddr.valid_ipv6(ip6):
        print "IP6 environment (%s) is not a valid IPv6 address." % ip6
        sys.exit(1)

    as_num = os.getenv("AS")
    as_num = as_num or None
    if as_num and not validate_asn(as_num):
        print "AS environment (%s) is not a AS number." % as_num
        sys.exit(1)

    # Get IP address of host, if none was specified
    if not ip:
        ips = get_host_ips(exclude=[
            "^docker.*", "^cbr.*", "virbr.*", "lxcbr.*", "veth.*", "cali.*",
            "tunl.*", "flannel.*"
        ])
        try:
            ip = str(ips.pop())
        except IndexError:
            print "Couldn't autodetect a management IP address. Please " \
                  "provide an IP address by rerunning the container with the" \
                  " IP environment variable set."
            sys.exit(1)
        else:
            print "No IP provided. Using detected IP: %s" % ip

    # Write a startup environment file containing the IP address that may have
    # just been detected.
    # This is required because the confd templates expect to be able to fill in
    # some templates by fetching them from the environment.
    with open('startup.env', 'w') as f:
        f.write("IP=%s\n" % ip)
        f.write("HOSTNAME=%s\n" % hostname)

    warn_if_hostname_conflict(ip)

    # Verify that IPs are not already in use by another host.
    error_if_bgp_ip_conflict(ip, ip6)

    # Verify that the chosen IP exists on the current host
    warn_if_unknown_ip(ip, ip6)

    if os.getenv("NO_DEFAULT_POOLS", "").lower() != "true":
        # Set up etcd
        ipv4_pools = client.get_ip_pools(4)
        ipv6_pools = client.get_ip_pools(6)

        # Create default pools if required
        if not ipv4_pools:
            client.add_ip_pool(4, DEFAULT_IPV4_POOL)

        # If the OS has not been built with IPv6 then the /proc config for IPv6
        # will not be present.
        if not ipv6_pools and os.path.exists('/proc/sys/net/ipv6'):
            client.add_ip_pool(6, DEFAULT_IPV6_POOL)

    client.ensure_global_config()
    client.create_host(hostname, ip, ip6, as_num)

    # If IPIP is enabled, the host requires an IP address for its tunnel
    # device, which is in an IPIP pool.  Without this, a host can't originate
    # traffic to a pool address because the response traffic would not be
    # routed via the tunnel (likely being dropped by RPF checks in the fabric).
    ipv4_pools = client.get_ip_pools(4)
    ipip_pools = [p for p in ipv4_pools if p.ipip]

    if ipip_pools:
        # IPIP is enabled, make sure the host has an address for its tunnel.
        _ensure_host_tunnel_addr(ipv4_pools, ipip_pools)
    else:
        # No IPIP pools, clean up any old address.
        _remove_host_tunnel_addr()
Example #9
0
def validate_arguments(arguments):
    """
    Validate argument values:
        <IP>
        <IP6>
        <PEER_IP>
        <AS_NUM>
        <DETACH>

    Arguments not validated:
        <DOCKER_IMAGE_NAME>
        <LOG_DIR>

    :param arguments: Docopt processed arguments
    """
    # Validate IPs
    ip_ok = arguments.get("--ip") is None or \
            arguments.get("--ip") is "" or \
            validate_ip(arguments.get("--ip"), 4)
    ip6_ok = arguments.get("--ip6") is None or \
             arguments.get("--ip6") is "" or \
             validate_ip(arguments.get("--ip6"), 6)
    container_ip_ok = arguments.get("<IP>") is None or \
                      validate_ip(arguments["<IP>"], 4) or \
                      validate_ip(arguments["<IP>"], 6)
    peer_ip_ok = arguments.get("<PEER_IP>") is None or \
                 validate_ip(arguments["<PEER_IP>"], 4) or \
                 validate_ip(arguments["<PEER_IP>"], 6)
    runtime_ok = arguments.get("--runtime") in [None, "none", "docker", "rkt"]

    asnum_ok = True
    asnum = arguments.get("<AS_NUM>") or arguments.get("--as")
    if asnum:
        asnum_ok = validate_asn(asnum)

    detach_ok = True
    if arguments.get("<DETACH>") or arguments.get("--detach"):
        detach_ok = arguments.get("--detach") in ["true", "false"]

    detach_libnetwork_ok = (arguments.get("--detach") == "true" or
                            not arguments.get("--libnetwork"))

    # Print error message
    if not ip_ok:
        print "Invalid IPv4 address specified with --ip argument."
    if not ip6_ok:
        print "Invalid IPv6 address specified with --ip6 argument."
    if not container_ip_ok or not peer_ip_ok:
        print "Invalid IP address specified."
    if not asnum_ok:
        print "Invalid AS Number specified."
    if not detach_ok:
        print "Valid values for --detach are 'true' and 'false'"
    if not detach_libnetwork_ok:
        print "The only valid value for --detach is 'true' when using libnetwork"
    if not runtime_ok:
        print "Runtime must be 'docker', 'rkt' or 'none'."

    # Exit if not valid argument
    if not (ip_ok and ip6_ok and container_ip_ok and peer_ip_ok and asnum_ok
            and detach_ok and detach_libnetwork_ok and runtime_ok):
        sys.exit(1)