def test_container_add(self, m_netns, m_get_pool_or_exit, m_client, m_get_container_info_or_exit, m_enforce_root): """ Test container_add method of calicoctl container command """ # Set up mock objects m_get_container_info_or_exit.return_value = { "Id": 666, "State": {"Running": 1, "Pid": "Pid_info"}, "HostConfig": {"NetworkMode": "not host"}, } m_client.get_endpoint.side_effect = KeyError m_client.get_default_next_hops.return_value = "next_hops" # Call method under test test_return = container.container_add("container1", "1.1.1.1", "interface") # Assert m_enforce_root.assert_called_once_with() m_get_container_info_or_exit.assert_called_once_with("container1") m_client.get_endpoint.assert_called_once_with( hostname=utils.hostname, orchestrator_id=utils.ORCHESTRATOR_ID, workload_id=666 ) m_get_pool_or_exit.assert_called_once_with(IPAddress("1.1.1.1")) m_client.get_default_next_hops.assert_called_once_with(utils.hostname) # Check an enpoint object was returned self.assertTrue(isinstance(test_return, Endpoint)) self.assertTrue(m_netns.create_veth.called) self.assertTrue(m_netns.move_veth_into_ns.called) self.assertTrue(m_netns.add_ip_to_ns_veth.called) self.assertTrue(m_netns.add_ns_default_route.called) self.assertTrue(m_netns.get_ns_veth_mac.called) self.assertTrue(m_client.set_endpoint.called)
def _configure_interface(self): """Configure the Calico interface for a pod. This involves the following steps: 1) Determine the IP that docker assigned to the interface inside the container 2) Delete the docker-assigned veth pair that's attached to the docker bridge 3) Create a new calico veth pair, using the docker-assigned IP for the end in the container's namespace 4) Assign the node's IP to the host end of the veth pair (required for compatibility with kube-proxy REDIRECT iptables rules). """ container_ip = self._read_docker_ip() self._delete_docker_interface() print('Configuring Calico network interface') ep = container_add(self.docker_id, container_ip, 'eth0') interface_name = generate_cali_interface_name(IF_PREFIX, ep.endpoint_id) node_ip = self._get_node_ip() print('Adding IP %s to interface %s' % (node_ip, interface_name)) # This is slightly tricky. Since the kube-proxy sometimes # programs REDIRECT iptables rules, we MUST have an IP on the host end # of the caliXXX veth pairs. This is because the REDIRECT rule # rewrites the destination ip/port of traffic from a pod to a service # VIP. The destination port is rewriten to an arbitrary high-numbered # port, and the destination IP is rewritten to one of the IPs allocated # to the interface. This fails if the interface doesn't have an IP, # so we allocate an IP which is already allocated to the node. We set # the subnet to /32 so that the routing table is not affected; # no traffic for the node_ip's subnet will use the /32 route. check_call(['ip', 'addr', 'add', node_ip + '/32', 'dev', interface_name]) print('Finished configuring network interface') return ep
def test_container_add(self, m_netns, m_get_pool_or_exit, m_client, m_get_container_info_or_exit, m_enforce_root): """ Test container_add method of calicoctl container command """ # Set up mock objects m_get_container_info_or_exit.return_value = { 'Id': 666, 'State': { 'Running': 1, 'Pid': 'Pid_info' }, 'HostConfig': { 'NetworkMode': "not host" } } m_client.get_endpoint.side_effect = KeyError m_client.get_default_next_hops.return_value = 'next_hops' # Call method under test test_return = container.container_add('container1', '1.1.1.1', 'interface') # Assert m_enforce_root.assert_called_once_with() m_get_container_info_or_exit.assert_called_once_with('container1') m_client.get_endpoint.assert_called_once_with( hostname=utils.hostname, orchestrator_id=utils.ORCHESTRATOR_ID, workload_id=666) m_get_pool_or_exit.assert_called_once_with(IPAddress('1.1.1.1')) m_client.get_default_next_hops.assert_called_once_with(utils.hostname) # Check an enpoint object was returned self.assertTrue(isinstance(test_return, Endpoint)) self.assertTrue(m_netns.create_veth.called) self.assertTrue(m_netns.move_veth_into_ns.called) self.assertTrue(m_netns.add_ip_to_ns_veth.called) self.assertTrue(m_netns.add_ns_default_route.called) self.assertTrue(m_netns.get_ns_veth_mac.called) self.assertTrue(m_client.set_endpoint.called)
def test_container_add(self, m_netns, m_get_pool_or_exit, m_client, m_get_container_info_or_exit, m_enforce_root): """ Test container_add method of calicoctl container command """ # Set up mock objects m_get_container_info_or_exit.return_value = { 'Id': 666, 'State': {'Running': 1, 'Pid': 'Pid_info'}, 'HostConfig': {'NetworkMode': "not host"} } m_client.get_endpoint.side_effect = KeyError m_client.get_default_next_hops.return_value = 'next_hops' # Call method under test test_return = container.container_add('container1', '1.1.1.1', 'interface') # Assert m_enforce_root.assert_called_once_with() m_get_container_info_or_exit.assert_called_once_with('container1') m_client.get_endpoint.assert_called_once_with( hostname=utils.hostname, orchestrator_id=utils.DOCKER_ORCHESTRATOR_ID, workload_id=666 ) m_get_pool_or_exit.assert_called_once_with(IPAddress('1.1.1.1')) m_client.get_default_next_hops.assert_called_once_with(utils.hostname) # Check an enpoint object was returned self.assertTrue(isinstance(test_return, Endpoint)) self.assertTrue(m_netns.increment_metrics.called) self.assertTrue(m_netns.create_veth.called) self.assertTrue(m_netns.move_veth_into_ns.called) self.assertTrue(m_netns.add_ip_to_ns_veth.called) self.assertTrue(m_netns.add_ns_default_route.called) self.assertTrue(m_netns.get_ns_veth_mac.called) self.assertTrue(m_client.set_endpoint.called)
def _configure_interface(self): """Configure the Calico interface for a pod. This involves the following steps: 1) Determine the IP that docker assigned to the interface inside the container 2) Delete the docker-assigned veth pair that's attached to the docker bridge 3) Create a new calico veth pair, using the docker-assigned IP for the end in the container's namespace 4) Assign the node's IP to the host end of the veth pair (required for compatibility with kube-proxy REDIRECT iptables rules). """ container_ip = self._read_docker_ip() self._delete_docker_interface() print('Configuring Calico network interface') ep = container_add(self.docker_id, container_ip, 'eth0') interface_name = generate_cali_interface_name(IF_PREFIX, ep.endpoint_id) node_ip = self._get_node_ip() print('Adding IP %s to interface %s' % (node_ip, interface_name)) # This is slightly tricky. Since the kube-proxy sometimes # programs REDIRECT iptables rules, we MUST have an IP on the host end # of the caliXXX veth pairs. This is because the REDIRECT rule # rewrites the destination ip/port of traffic from a pod to a service # VIP. The destination port is rewriten to an arbitrary high-numbered # port, and the destination IP is rewritten to one of the IPs allocated # to the interface. This fails if the interface doesn't have an IP, # so we allocate an IP which is already allocated to the node. We set # the subnet to /32 so that the routing table is not affected; # no traffic for the node_ip's subnet will use the /32 route. check_call( ['ip', 'addr', 'add', node_ip + '/32', 'dev', interface_name]) print('Finished configuring network interface') return ep