Example #1
0
def ip_pool_range_add(start_ip, end_ip, version, ipip, masquerade):
    """
    Add the range of ip addresses as CIDRs to the IP address allocation pool.

    :param start_ip: The first ip address the ip range.
    :param end_ip: The last ip address in the ip range.
    :param version: 4 or 6
    :param ipip: Use IP in IP for this pool.
    :return: None
    """
    if version == 6 and ipip:
        print "IP in IP not supported for IPv6 pools"
        sys.exit(1)

    ip_range = IPRange(start_ip, end_ip)
    pools = client.get_ip_pools(version)
    for pool in pools:
        pool_net = IPNetwork(pool.cidr)
        # Reject the new ip range if any of the following are true:
        # - The new ip range contains all ips of any existing pool
        # - An existing pool overlaps ips with the start of the new ip range
        # - An existing pool overlaps ips with the end of the new ip range
        if (pool_net in ip_range or
            start_ip in pool_net or
            end_ip in pool_net):
            print "Cannot add range - range conflicts with pool %s" % pool.cidr
            sys.exit(1)

    cidrs = netaddr.iprange_to_cidrs(start_ip, end_ip)
    for ip_net in cidrs:
        new_pool = IPPool(ip_net.cidr, ipip=ipip, masquerade=masquerade)
        client.add_ip_pool(version, new_pool)
Example #2
0
def ip_pool_add(cidr_pool, version, ipip, masquerade):
    """
    Add the the given CIDR range to the IP address allocation pool.

    :param cidr_pool: The pool to set in CIDR format, e.g. 192.168.0.0/16
    :param version: v4 or v6
    :param ipip: Use IP in IP for this pool.
    :return: None
    """
    if version == "v6" and ipip:
        print "IP in IP not supported for IPv6 pools"
        sys.exit(1)

    cidr = check_ip_version(cidr_pool, version, IPNetwork)
    pool = IPPool(cidr, ipip=ipip, masquerade=masquerade)
    client.add_ip_pool(version, pool)
Example #3
0
def ip_pool_add(cidrs, version, ipip, masquerade):
    """
    Add the given CIDRS to the IP address allocation pool.

    :param cidrs: The pools to set in CIDR format, e.g. 192.168.0.0/16
    :param version: 4 or 6
    :param ipip: Use IP in IP for this pool.
    :return: None
    """
    if version == 6 and ipip:
        print "IP in IP not supported for IPv6 pools"
        sys.exit(1)

    # TODO Reject any cidrs that overlap with existing cidrs in the pool
    for cidr in cidrs:
        pool = IPPool(cidr, ipip=ipip, masquerade=masquerade)
        client.add_ip_pool(version, pool)
Example #4
0
def node_start(node_image, log_dir, ip, ip6, as_num, detach, kubernetes):
    """
    Create the calico-node container and establish Calico networking on this
    host.

    :param ip:  The IPv4 address of the host.
    :param node_image:  The calico-node image to use.
    :param ip6:  The IPv6 address of the host (or None if not configured)
    :param as_num:  The BGP AS Number to use for this node.  If not specified
    the global default value will be used.
    :param detach: True to run in Docker's "detached" mode, False to run
    attached.
    :return:  None.
    """
    # Ensure log directory exists
    if not os.path.exists(log_dir):
        os.makedirs(log_dir)

    # Print warnings for any known system issues before continuing
    check_system(fix=False, quit_if_error=False)

    # Get IP address of host, if none was specified
    if not ip:
        ips = get_host_ips(exclude=["docker0"])
        try:
            ip = ips.pop()
        except IndexError:
            print "Couldn't autodetect a management IP address. Please provide" \
                  " an IP by rerunning the command with the --ip=<IP_ADDRESS> flag."
            sys.exit(1)
        else:
            print "No IP provided. Using detected IP: %s" % ip

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

    # Warn if this hostname conflicts with an existing host
    warn_if_hostname_conflict(ip)

    # Install kubernetes plugin
    if kubernetes:
        try:
            # Attempt to install to the default kubernetes directory
            install_kubernetes(KUBERNETES_PLUGIN_DIR)
        except OSError:
            # Use the backup directory
            install_kubernetes(KUBERNETES_PLUGIN_DIR_BACKUP)

    # 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 not ipv6_pools:
        client.add_ip_pool(6, DEFAULT_IPV6_POOL)

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

    try:
        docker_client.remove_container("calico-node", force=True)
    except docker.errors.APIError as err:
        if err.response.status_code != 404:
            raise

    etcd_authority = os.getenv(ETCD_AUTHORITY_ENV, ETCD_AUTHORITY_DEFAULT)
    etcd_authority_split = etcd_authority.split(':')
    if len(etcd_authority_split) != 2:
        print_paragraph("Invalid %s. Must take the form <address>:<port>. Value " \
              "provided is '%s'" % (ETCD_AUTHORITY_ENV, etcd_authority))
        sys.exit(1)

    etcd_authority_address = etcd_authority_split[0]
    etcd_authority_port = etcd_authority_split[1]

    # Always try to convert the address(hostname) to an IP. This is a noop if
    # the address is already an IP address.
    etcd_authority = '%s:%s' % (socket.gethostbyname(etcd_authority_address),
                                etcd_authority_port)

    environment = [
        "HOSTNAME=%s" % hostname,
        "IP=%s" % ip,
        "IP6=%s" % (ip6 or ""),
        "ETCD_AUTHORITY=%s" % etcd_authority,  # etcd host:port
        "FELIX_ETCDADDR=%s" % etcd_authority,  # etcd host:port
    ]

    binds = {
        "/proc":
            {
                "bind": "/proc_host",
                "ro": False
            },
        log_dir:
            {
                "bind": "/var/log/calico",
                "ro": False
            },
        "/run/docker/plugins":
            {
                "bind": "/usr/share/docker/plugins",
                "ro": False
            }
    }

    host_config = docker.utils.create_host_config(
        privileged=True,
        restart_policy={"Name": "Always"},
        network_mode="host",
        binds=binds)

    _find_or_pull_node_image(node_image, docker_client)
    container = docker_client.create_container(
        node_image,
        name="calico-node",
        detach=True,
        environment=environment,
        host_config=host_config,
        volumes=["/proc_host",
                 "/var/log/calico",
                 "/usr/share/docker/plugins"])
    cid = container["Id"]

    docker_client.start(container)

    print "Calico node is running with id: %s" % cid

    if not detach:
        _attach_and_stream(container)
Example #5
0
def node_start(node_image, log_dir, ip, ip6, as_num, detach, kubernetes):
    """
    Create the calico-node container and establish Calico networking on this
    host.

    :param ip:  The IPv4 address of the host.
    :param node_image:  The calico-node image to use.
    :param ip6:  The IPv6 address of the host (or None if not configured)
    :param as_num:  The BGP AS Number to use for this node.  If not specified
    the global default value will be used.
    :param detach: True to run in Docker's "detached" mode, False to run
    attached.
    :return:  None.
    """
    # Ensure log directory exists
    if not os.path.exists(log_dir):
        os.makedirs(log_dir)

    # Print warnings for any known system issues before continuing
    check_system(fix=False, quit_if_error=False)

    # Get IP address of host, if none was specified
    if not ip:
        ips = get_host_ips(exclude=["docker0"])
        try:
            ip = ips.pop()
        except IndexError:
            print "Couldn't autodetect a management IP address. Please provide" \
                  " an IP by rerunning the command with the --ip=<IP_ADDRESS> flag."
            sys.exit(1)
        else:
            print "No IP provided. Using detected IP: %s" % ip

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

    # Warn if this hostname conflicts with an existing host
    warn_if_hostname_conflict(ip)

    # Install kubernetes plugin
    if kubernetes:
        try:
            # Attempt to install to the default kubernetes directory
            install_kubernetes(KUBERNETES_PLUGIN_DIR)
        except OSError:
            # Use the backup directory
            install_kubernetes(KUBERNETES_PLUGIN_DIR_BACKUP)

    # 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 not ipv6_pools:
        client.add_ip_pool(6, DEFAULT_IPV6_POOL)

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

    try:
        docker_client.remove_container("calico-node", force=True)
    except docker.errors.APIError as err:
        if err.response.status_code != 404:
            raise

    etcd_authority = os.getenv(ETCD_AUTHORITY_ENV, ETCD_AUTHORITY_DEFAULT)
    etcd_authority_split = etcd_authority.split(':')
    if len(etcd_authority_split) != 2:
        print_paragraph("Invalid %s. Must take the form <address>:<port>. Value " \
              "provided is '%s'" % (ETCD_AUTHORITY_ENV, etcd_authority))
        sys.exit(1)

    etcd_authority_address = etcd_authority_split[0]
    etcd_authority_port = etcd_authority_split[1]

    # Always try to convert the address(hostname) to an IP. This is a noop if
    # the address is already an IP address.
    etcd_authority = '%s:%s' % (socket.gethostbyname(etcd_authority_address),
                                etcd_authority_port)

    environment = [
        "HOSTNAME=%s" % hostname,
        "IP=%s" % ip,
        "IP6=%s" % (ip6 or ""),
        "ETCD_AUTHORITY=%s" % etcd_authority,  # etcd host:port
        "FELIX_ETCDADDR=%s" % etcd_authority,  # etcd host:port
    ]

    binds = {
        "/proc": {
            "bind": "/proc_host",
            "ro": False
        },
        log_dir: {
            "bind": "/var/log/calico",
            "ro": False
        },
        "/run/docker/plugins": {
            "bind": "/usr/share/docker/plugins",
            "ro": False
        }
    }

    host_config = docker.utils.create_host_config(
        privileged=True,
        restart_policy={"Name": "Always"},
        network_mode="host",
        binds=binds)

    _find_or_pull_node_image(node_image, docker_client)
    container = docker_client.create_container(
        node_image,
        name="calico-node",
        detach=True,
        environment=environment,
        host_config=host_config,
        volumes=["/proc_host", "/var/log/calico", "/usr/share/docker/plugins"])
    cid = container["Id"]

    docker_client.start(container)

    print "Calico node is running with id: %s" % cid

    if not detach:
        _attach_and_stream(container)