Esempio n. 1
0
    def setUp(self):
        self.pod_name = "podname"
        self.namespace = "namespace"
        self.profile_name = "namespace_podname"
        self.auth_token = "authtoken12345"
        self.api_root = "https://10.100.0.1:443/api/v1/"
        self.network_config = {"policy": {}}
        self.driver = KubernetesAnnotationDriver(self.pod_name, self.namespace,
                                                 self.auth_token,
                                                 self.api_root, None, None,
                                                 None, None)
        assert_equal(self.driver.profile_name, self.profile_name)

        # Mock the DatastoreClient
        self.client = MagicMock(spec=DatastoreClient)
        self.driver._client = self.client
    def setUp(self):
        self.pod_name = "podname"
        self.namespace = "namespace"
        self.profile_name = "namespace_podname"
        self.auth_token = "authtoken12345"
        self.api_root = "https://10.100.0.1:443/api/v1/"
        self.network_config = {
                "policy": {}
        }
        self.driver = KubernetesAnnotationDriver(self.pod_name, self.namespace,
                self.auth_token, self.api_root, None, None, None, None)
        assert_equal(self.driver.profile_name, self.profile_name)

        # Mock the DatastoreClient
        self.client = MagicMock(spec=DatastoreClient)
        self.driver._client = self.client
Esempio n. 3
0
class KubernetesAnnotationDriverTest(unittest.TestCase):
    """
    Test class for KubernetesAnnotationDriver class.
    """
    def setUp(self):
        self.pod_name = "podname"
        self.namespace = "namespace"
        self.profile_name = "namespace_podname"
        self.auth_token = "authtoken12345"
        self.api_root = "https://10.100.0.1:443/api/v1/"
        self.network_config = {"policy": {}}
        self.driver = KubernetesAnnotationDriver(self.pod_name, self.namespace,
                                                 self.auth_token,
                                                 self.api_root, None, None,
                                                 None, None)
        assert_equal(self.driver.profile_name, self.profile_name)

        # Mock the DatastoreClient
        self.client = MagicMock(spec=DatastoreClient)
        self.driver._client = self.client

    @patch("calico_cni.policy_drivers.KubernetesAnnotationDriver._get_api_pod",
           autospec=True)
    def test_generate_rules_mainline(self, m_get_pod):
        # Generate rules
        rules = self.driver.generate_rules()

        # Assert correct. Should return rules which isolate the pod by namespace.
        expected = Rules(id=self.profile_name,
                         inbound_rules=[
                             Rule(action="allow",
                                  src_tag="namespace_namespace")
                         ],
                         outbound_rules=[Rule(action="allow")])
        assert_equal(rules, expected)

    @patch("calico_cni.policy_drivers.KubernetesAnnotationDriver._get_api_pod",
           autospec=True)
    def test_generate_rules_kube_system(self, m_get_pod):
        # Use kube-system namespace.
        self.driver.namespace = "kube-system"

        # Generate rules
        rules = self.driver.generate_rules()

        # Assert correct. Should allow all.
        expected = Rules(id=self.profile_name,
                         inbound_rules=[Rule(action="allow")],
                         outbound_rules=[Rule(action="allow")])
        assert_equal(rules, expected)

    def test_remove_profile(self):
        self.driver.remove_profile()
        self.driver._client.remove_profile.assert_called_once_with(
            self.driver.profile_name)

    def test_remove_missing_profile(self):
        self.driver._client.remove_profile.side_effect = KeyError

        # Nothing should be raised.
        self.driver.remove_profile()

    @patch("calico_cni.policy_drivers.KubernetesAnnotationDriver._get_api_pod",
           autospec=True)
    def test_generate_rules_annotations(self, m_get_pod):
        # Mock get_metadata to return annotations.
        annotations = {"projectcalico.org/policy": "allow tcp"}
        self.driver._get_metadata = MagicMock(spec=self.driver._get_metadata)
        self.driver._get_metadata.return_value = annotations

        # Generate rules
        rules = self.driver.generate_rules()

        # Assert correct. Should allow all.
        expected = Rules(id=self.profile_name,
                         inbound_rules=[Rule(action="allow", protocol="tcp")],
                         outbound_rules=[Rule(action="allow")])
        assert_equal(rules, expected)

    @patch("calico_cni.policy_drivers.KubernetesAnnotationDriver._get_api_pod",
           autospec=True)
    def test_generate_rules_parse_error(self, m_get_pod):
        # Mock get_metadata to return annotations.
        annotations = {"projectcalico.org/policy": "allow tcp"}
        self.driver._get_metadata = MagicMock(spec=self.driver._get_metadata)
        self.driver._get_metadata.return_value = annotations

        # Mock to raise error
        self.driver.policy_parser = MagicMock(spec=self.driver.policy_parser)
        self.driver.policy_parser.parse_line.side_effect = ValueError

        # Generate rules
        assert_raises(ApplyProfileError, self.driver.generate_rules)

    def test_generate_tags(self):
        # Mock get_metadata to return labels.
        labels = {"key": "value"}
        self.driver._get_metadata = MagicMock(spec=self.driver._get_metadata)
        self.driver._get_metadata.return_value = labels

        # Call
        tags = self.driver.generate_tags()

        # Assert
        assert_equal(tags, set(["namespace_namespace", "namespace_key_value"]))

    @patch('calico_cni.policy_drivers.requests.Session', autospec=True)
    @patch('json.loads', autospec=True)
    def test_get_api_pod(self, m_json_load, m_session):
        # Set up driver.
        self.driver.pod_name = 'pod-1'
        self.driver.namespace = 'a'
        pod1 = '{"metadata": {"namespace": "a", "name": "pod-1"}}'

        api_root = "http://*****:*****@patch("calico_cni.policy_drivers.HTTPClient", autospec=True)
    @patch("calico_cni.policy_drivers.Query", autospec=True)
    @patch("calico_cni.policy_drivers.KubeConfig", autospec=True)
    def test_get_api_pod_kubeconfig(self, m_kcfg, m_query, m_http):
        # Set up driver.
        self.driver.pod_name = 'pod-1'
        self.driver.namespace = 'a'

        pod = Mock()
        pod.obj = '{"metadata": {"namespace": "a", "name": "pod-1"}}'
        m_query(1, 2, 3).get_by_name.return_value = pod

        api_root = "http://*****:*****@patch("calico_cni.policy_drivers.HTTPClient", autospec=True)
    @patch("calico_cni.policy_drivers.Query", autospec=True)
    @patch("calico_cni.policy_drivers.KubeConfig", autospec=True)
    def test_get_api_pod_kubeconfig_error(self, m_kcfg, m_query, m_http):
        # Set up driver.
        self.driver.pod_name = 'pod-1'
        self.driver.namespace = 'a'

        pod = Mock()
        pod.obj = '{"metadata": {"namespace": "a", "name": "pod-1"}}'
        m_query(1, 2, 3).get_by_name.side_effect = KeyError

        api_root = "http://*****:*****@patch('calico_cni.policy_drivers.requests.Session', autospec=True)
    @patch('json.loads', autospec=True)
    def test_get_api_pod_with_client_certs(self, m_json_load, m_session):
        # Set up driver.
        self.driver.pod_name = 'pod-1'
        self.driver.namespace = 'a'
        pod1 = '{"metadata": {"namespace": "a", "name": "pod-1"}}'

        api_root = "http://*****:*****@patch('calico_cni.policy_drivers.requests.Session', autospec=True)
    @patch('json.loads', autospec=True)
    def test_get_pod_config_error(self, m_json_load, m_session):
        """Test _get_api_path with API Access Error
        """
        # Set up mock objects
        self.driver.auth_token = 'TOKEN'

        m_session_obj = Mock()
        m_session_obj.headers = Mock()
        m_session_obj.get.side_effect = BaseException

        m_session.return_value = m_session_obj
        m_session_obj.__enter__ = Mock(return_value=m_session_obj)
        m_session_obj.__exit__ = Mock(return_value=False)

        # Call method under test
        assert_raises(ApplyProfileError, self.driver._get_api_pod)

    @patch('calico_cni.policy_drivers.requests.Session', autospec=True)
    @patch('json.loads', autospec=True)
    def test_get_pod_config_response_code(self, m_json_load, m_session):
        """Test _get_api_path with incorrect status_code
        """
        # Set up class member
        self.driver.pod_name = 'pod-1'
        self.driver.namespace = 'a'
        pod1 = '{"metadata": {"namespace": "a", "name": "pod-1"}}'

        # Set up mock objects
        self.driver.auth_token = 'TOKEN'

        get_obj = Mock()
        get_obj.status_code = 404

        m_session_obj = Mock()
        m_session_obj.headers = Mock()
        m_session_obj.get.return_value = get_obj

        m_session.return_value = m_session_obj
        m_session_obj.__enter__ = Mock(return_value=m_session_obj)
        m_session_obj.__exit__ = Mock(return_value=False)

        # Call method under test
        assert_raises(ApplyProfileError, self.driver._get_api_pod)

    @patch('calico_cni.policy_drivers.requests.Session', autospec=True)
    @patch('json.loads', autospec=True)
    def test_get_api_pod_parse_error(self, m_json_load, m_session):
        # Set up driver.
        self.driver.pod_name = 'pod-1'
        self.driver.namespace = 'a'
        pod1 = '{"metadata": {"namespace": "a", "name": "pod-1"}}'

        api_root = "http://kubernetesapi:8080/api/v1/"
        self.driver.api_root = api_root

        # Set up mock objects
        self.driver.auth_token = 'TOKEN'

        m_json_load.side_effect = TypeError

        get_obj = Mock()
        get_obj.status_code = 200
        get_obj.text = pod1

        m_session_obj = Mock()
        m_session_obj.headers = Mock()
        m_session_obj.get.return_value = get_obj

        m_session.return_value = m_session_obj
        m_session_obj.__enter__ = Mock(return_value=m_session_obj)
        m_session_obj.__exit__ = Mock(return_value=False)

        # Call method under test
        assert_raises(ApplyProfileError, self.driver._get_api_pod)

    def test_get_metadata_missing(self):
        # Mock out self.pod in the driver.
        self.driver.pod = {}

        # Attempt to get metadata
        annotations = self.driver._get_metadata("annotations")

        # Should be None
        assert_equal(annotations, None)
class KubernetesAnnotationDriverTest(unittest.TestCase):
    """
    Test class for KubernetesAnnotationDriver class.
    """
    def setUp(self):
        self.pod_name = "podname"
        self.namespace = "namespace"
        self.profile_name = "namespace_podname"
        self.auth_token = "authtoken12345"
        self.api_root = "https://10.100.0.1:443/api/v1/"
        self.network_config = {
                "policy": {}
        }
        self.driver = KubernetesAnnotationDriver(self.pod_name, self.namespace,
                self.auth_token, self.api_root, None, None, None, None)
        assert_equal(self.driver.profile_name, self.profile_name)

        # Mock the DatastoreClient
        self.client = MagicMock(spec=DatastoreClient)
        self.driver._client = self.client

    @patch("calico_cni.policy_drivers.KubernetesAnnotationDriver._get_api_pod", autospec=True)
    def test_generate_rules_mainline(self, m_get_pod):
        # Generate rules
        rules = self.driver.generate_rules()

        # Assert correct. Should return rules which isolate the pod by namespace.
        expected = Rules(id=self.profile_name,
                         inbound_rules=[Rule(action="allow", src_tag="namespace_namespace")],
                         outbound_rules=[Rule(action="allow")])
        assert_equal(rules, expected)

    @patch("calico_cni.policy_drivers.KubernetesAnnotationDriver._get_api_pod", autospec=True)
    def test_generate_rules_kube_system(self, m_get_pod):
        # Use kube-system namespace.
        self.driver.namespace = "kube-system"

        # Generate rules
        rules = self.driver.generate_rules()

        # Assert correct. Should allow all.
        expected = Rules(id=self.profile_name,
                         inbound_rules=[Rule(action="allow")],
                         outbound_rules=[Rule(action="allow")])
        assert_equal(rules, expected)

    def test_remove_profile(self):
        self.driver.remove_profile()
        self.driver._client.remove_profile.assert_called_once_with(self.driver.profile_name)

    def test_remove_missing_profile(self):
        self.driver._client.remove_profile.side_effect = KeyError

        # Nothing should be raised.
        self.driver.remove_profile()

    @patch("calico_cni.policy_drivers.KubernetesAnnotationDriver._get_api_pod", autospec=True)
    def test_generate_rules_annotations(self, m_get_pod):
        # Mock get_metadata to return annotations.
        annotations = {"projectcalico.org/policy": "allow tcp"}
        self.driver._get_metadata = MagicMock(spec=self.driver._get_metadata)
        self.driver._get_metadata.return_value = annotations

        # Generate rules
        rules = self.driver.generate_rules()

        # Assert correct. Should allow all.
        expected = Rules(id=self.profile_name,
                         inbound_rules=[Rule(action="allow", protocol="tcp")],
                         outbound_rules=[Rule(action="allow")])
        assert_equal(rules, expected)

    @patch("calico_cni.policy_drivers.KubernetesAnnotationDriver._get_api_pod", autospec=True)
    def test_generate_rules_parse_error(self, m_get_pod):
        # Mock get_metadata to return annotations.
        annotations = {"projectcalico.org/policy": "allow tcp"}
        self.driver._get_metadata = MagicMock(spec=self.driver._get_metadata)
        self.driver._get_metadata.return_value = annotations

        # Mock to raise error
        self.driver.policy_parser = MagicMock(spec=self.driver.policy_parser)
        self.driver.policy_parser.parse_line.side_effect = ValueError

        # Generate rules
        assert_raises(ApplyProfileError, self.driver.generate_rules)

    def test_generate_tags(self):
        # Mock get_metadata to return labels.
        labels = {"key": "value"}
        self.driver._get_metadata = MagicMock(spec=self.driver._get_metadata)
        self.driver._get_metadata.return_value = labels

        # Call
        tags = self.driver.generate_tags()

        # Assert
        assert_equal(tags, set(["namespace_namespace", "namespace_key_value"]))


    @patch('calico_cni.policy_drivers.requests.Session', autospec=True)
    @patch('json.loads', autospec=True)
    def test_get_api_pod(self, m_json_load, m_session):
        # Set up driver.
        self.driver.pod_name = 'pod-1'
        self.driver.namespace = 'a'
        pod1 = '{"metadata": {"namespace": "a", "name": "pod-1"}}'

        api_root = "http://*****:*****@patch("calico_cni.policy_drivers.HTTPClient", autospec=True)
    @patch("calico_cni.policy_drivers.Query", autospec=True)
    @patch("calico_cni.policy_drivers.KubeConfig", autospec=True)
    def test_get_api_pod_kubeconfig(self, m_kcfg, m_query, m_http):
        # Set up driver.
        self.driver.pod_name = 'pod-1'
        self.driver.namespace = 'a'

        pod = Mock()
        pod.obj = '{"metadata": {"namespace": "a", "name": "pod-1"}}'
        m_query(1, 2, 3).get_by_name.return_value = pod

        api_root = "http://*****:*****@patch("calico_cni.policy_drivers.HTTPClient", autospec=True)
    @patch("calico_cni.policy_drivers.Query", autospec=True)
    @patch("calico_cni.policy_drivers.KubeConfig", autospec=True)
    def test_get_api_pod_kubeconfig_error(self, m_kcfg, m_query, m_http):
        # Set up driver.
        self.driver.pod_name = 'pod-1'
        self.driver.namespace = 'a'

        pod = Mock()
        pod.obj = '{"metadata": {"namespace": "a", "name": "pod-1"}}'
        m_query(1, 2, 3).get_by_name.side_effect = KeyError

        api_root = "http://*****:*****@patch('calico_cni.policy_drivers.requests.Session', autospec=True)
    @patch('json.loads', autospec=True)
    def test_get_api_pod_with_client_certs(self, m_json_load, m_session):
        # Set up driver.
        self.driver.pod_name = 'pod-1'
        self.driver.namespace = 'a'
        pod1 = '{"metadata": {"namespace": "a", "name": "pod-1"}}'

        api_root = "http://*****:*****@patch('calico_cni.policy_drivers.requests.Session', autospec=True)
    @patch('json.loads', autospec=True)
    def test_get_pod_config_error(self, m_json_load, m_session):
        """Test _get_api_path with API Access Error
        """
        # Set up mock objects
        self.driver.auth_token = 'TOKEN'

        m_session_obj = Mock()
        m_session_obj.headers = Mock()
        m_session_obj.get.side_effect = BaseException

        m_session.return_value = m_session_obj
        m_session_obj.__enter__ = Mock(return_value=m_session_obj)
        m_session_obj.__exit__ = Mock(return_value=False)

        # Call method under test
        assert_raises(ApplyProfileError, self.driver._get_api_pod)

    @patch('calico_cni.policy_drivers.requests.Session', autospec=True)
    @patch('json.loads', autospec=True)
    def test_get_pod_config_response_code(self, m_json_load, m_session):
        """Test _get_api_path with incorrect status_code
        """
        # Set up class member
        self.driver.pod_name = 'pod-1'
        self.driver.namespace = 'a'
        pod1 = '{"metadata": {"namespace": "a", "name": "pod-1"}}'

        # Set up mock objects
        self.driver.auth_token = 'TOKEN'

        get_obj = Mock()
        get_obj.status_code = 404

        m_session_obj = Mock()
        m_session_obj.headers = Mock()
        m_session_obj.get.return_value = get_obj

        m_session.return_value = m_session_obj
        m_session_obj.__enter__ = Mock(return_value=m_session_obj)
        m_session_obj.__exit__ = Mock(return_value=False)

        # Call method under test
        assert_raises(ApplyProfileError, self.driver._get_api_pod)

    @patch('calico_cni.policy_drivers.requests.Session', autospec=True)
    @patch('json.loads', autospec=True)
    def test_get_api_pod_parse_error(self, m_json_load, m_session):
        # Set up driver.
        self.driver.pod_name = 'pod-1'
        self.driver.namespace = 'a'
        pod1 = '{"metadata": {"namespace": "a", "name": "pod-1"}}'

        api_root = "http://kubernetesapi:8080/api/v1/"
        self.driver.api_root = api_root

        # Set up mock objects
        self.driver.auth_token = 'TOKEN'

        m_json_load.side_effect = TypeError

        get_obj = Mock()
        get_obj.status_code = 200
        get_obj.text = pod1

        m_session_obj = Mock()
        m_session_obj.headers = Mock()
        m_session_obj.get.return_value = get_obj

        m_session.return_value = m_session_obj
        m_session_obj.__enter__ = Mock(return_value=m_session_obj)
        m_session_obj.__exit__ = Mock(return_value=False)

        # Call method under test
        assert_raises(ApplyProfileError, self.driver._get_api_pod)

    def test_get_metadata_missing(self):
        # Mock out self.pod in the driver.
        self.driver.pod = {}

        # Attempt to get metadata
        annotations = self.driver._get_metadata("annotations")

        # Should be None
        assert_equal(annotations, None)