示例#1
0
 def test_ns_veth_exists_true(self, m_NamedNamespace):
     """
     Test ns_veth_exists returns True if no error occurs.
     """
     m_namespace = Mock(spec=NamedNamespace)
     m_NamedNamespace().__enter__.return_value = m_namespace
     self.assertTrue(ns_veth_exists(Mock(spec=Namespace), "veth1"))
     m_namespace.check_output.assert_called_once_with(["ip", "link", "show", "veth1"])
示例#2
0
 def test_ns_veth_exists_false(self, m_NamedNamespace):
     """
     Test ns_veth_exists returns False if an error occurs.
     """
     m_namespace = Mock(spec=NamedNamespace)
     m_NamedNamespace().__enter__.return_value = m_namespace
     m_namespace.check_output.side_effect = CalledProcessError(1, "test")
     self.assertFalse(ns_veth_exists(Mock(spec=Namespace), "veth1"))
     m_namespace.check_output.assert_called_once_with(["ip", "link", "show", "veth1"])
示例#3
0
 def test_ns_veth_exists_true(self, m_NamedNamespace):
     """
     Test ns_veth_exists returns True if no error occurs.
     """
     m_namespace = Mock(spec=NamedNamespace)
     m_NamedNamespace().__enter__.return_value = m_namespace
     self.assertTrue(ns_veth_exists(Mock(spec=Namespace), "veth1"))
     m_namespace.check_output.assert_called_once_with(
         ["ip", "link", "show", "veth1"])
示例#4
0
 def test_ns_veth_exists_false(self, m_NamedNamespace):
     """
     Test ns_veth_exists returns False if an error occurs.
     """
     m_namespace = Mock(spec=NamedNamespace)
     m_NamedNamespace().__enter__.return_value = m_namespace
     m_namespace.check_output.side_effect = CalledProcessError(1, "test")
     self.assertFalse(ns_veth_exists(Mock(spec=Namespace), "veth1"))
     m_namespace.check_output.assert_called_once_with(
         ["ip", "link", "show", "veth1"])
示例#5
0
def container_ip_add(container_id, ip, interface):
    """
    Add an IP address to an existing Calico networked container.

    :param container_id: The namespace path or container_id of the container.
    :param ip: The IP to add
    :param interface: The name of the interface in the container.

    :return: None
    """

    # The netns manipulations must be done as root.
    enforce_root()

    if container_id.startswith("/") and os.path.exists(container_id):
        # The ID is a path. Don't do any docker lookups
        workload_id = escape_etcd(container_id)
        namespace = netns.Namespace(container_id)
        orchestrator_id = NAMESPACE_ORCHESTRATOR_ID
    else:
        info = get_container_info_or_exit(container_id)
        workload_id = info["Id"]
        namespace = netns.PidNamespace(info["State"]["Pid"])
        orchestrator_id = DOCKER_ORCHESTRATOR_ID

        # Check the container is actually running.
        if not info["State"]["Running"]:
            print "%s is not currently running." % container_id
            sys.exit(1)

    # Check that the container is already networked
    try:
        endpoint = client.get_endpoint(hostname=hostname,
                                       orchestrator_id=orchestrator_id,
                                       workload_id=workload_id)
    except KeyError:
        print "Failed to add IP address to container.\n"
        print_container_not_in_calico_msg(container_id)
        sys.exit(1)

    # From here, this method starts having side effects. If something
    # fails then at least try to leave the system in a clean state.
    address, pool = get_ip_and_pool(ip)

    try:
        if address.version == 4:
            endpoint.ipv4_nets.add(IPNetwork(address))
        else:
            endpoint.ipv6_nets.add(IPNetwork(address))
        client.update_endpoint(endpoint)
    except (KeyError, ValueError):
        client.release_ips({address})
        print "Error updating datastore. Aborting."
        sys.exit(1)

    if not netns.ns_veth_exists(namespace, interface):
        print "Interface provided does not exist in container. Aborting."
        sys.exit(1)

    try:
        netns.add_ip_to_ns_veth(namespace, address, interface)
    except CalledProcessError:
        print "Error updating networking in container. Aborting."
        if address.version == 4:
            endpoint.ipv4_nets.remove(IPNetwork(address))
        else:
            endpoint.ipv6_nets.remove(IPNetwork(address))
        client.update_endpoint(endpoint)
        client.release_ips({address})
        sys.exit(1)

    print "IP %s added to %s" % (str(address), container_id)
示例#6
0
def container_ip_add(container_id, ip, interface):
    """
    Add an IP address to an existing Calico networked container.

    :param container_id: The namespace path or container_id of the container.
    :param ip: The IP to add
    :param interface: The name of the interface in the container.

    :return: None
    """

    # The netns manipulations must be done as root.
    enforce_root()

    if container_id.startswith("/") and os.path.exists(container_id):
        # The ID is a path. Don't do any docker lookups
        workload_id = escape_etcd(container_id)
        namespace = netns.Namespace(container_id)
        orchestrator_id = NAMESPACE_ORCHESTRATOR_ID
    else:
        info = get_container_info_or_exit(container_id)
        workload_id = info["Id"]
        namespace = netns.PidNamespace(info["State"]["Pid"])
        orchestrator_id = DOCKER_ORCHESTRATOR_ID

        # Check the container is actually running.
        if not info["State"]["Running"]:
            print "%s is not currently running." % container_id
            sys.exit(1)

    # Check that the container is already networked
    try:
        endpoint = client.get_endpoint(hostname=hostname,
                                       orchestrator_id=orchestrator_id,
                                       workload_id=workload_id)
    except KeyError:
        print "Failed to add IP address to container.\n"
        print_container_not_in_calico_msg(container_id)
        sys.exit(1)

    # From here, this method starts having side effects. If something
    # fails then at least try to leave the system in a clean state.
    address, pool = get_ip_and_pool(ip)

    try:
        if address.version == 4:
            endpoint.ipv4_nets.add(IPNetwork(address))
        else:
            endpoint.ipv6_nets.add(IPNetwork(address))
        client.update_endpoint(endpoint)
    except (KeyError, ValueError):
        client.release_ips({address})
        print "Error updating datastore. Aborting."
        sys.exit(1)

    if not netns.ns_veth_exists(namespace, interface):
        print "Interface provided does not exist in container. Aborting."
        sys.exit(1)

    try:
        netns.add_ip_to_ns_veth(namespace, address, interface)
    except CalledProcessError:
        print "Error updating networking in container. Aborting."
        if address.version == 4:
            endpoint.ipv4_nets.remove(IPNetwork(address))
        else:
            endpoint.ipv6_nets.remove(IPNetwork(address))
        client.update_endpoint(endpoint)
        client.release_ips({address})
        sys.exit(1)

    print "IP %s added to %s" % (str(address), container_id)