blob: 28d66c530df30f2020332cd93e508c601b38019c [file] [log] [blame]
# Copyright 2020 Canonical Ltd.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from unittest import TestCase, mock
from n2vc.kubectl import Kubectl, CORE_CLIENT
from n2vc.utils import Dict
from kubernetes.client.rest import ApiException
class FakeK8sResourceMetadata:
def __init__(
self,
name: str = None,
namespace: str = None,
annotations: dict = {},
labels: dict = {},
):
self._annotations = annotations
self._name = name or "name"
self._namespace = namespace or "namespace"
self._labels = labels or {"juju-app": "squid"}
@property
def name(self):
return self._name
@property
def namespace(self):
return self._namespace
@property
def labels(self):
return self._labels
@property
def annotations(self):
return self._annotations
class FakeK8sStorageClass:
def __init__(self, metadata=None):
self._metadata = metadata or FakeK8sResourceMetadata()
@property
def metadata(self):
return self._metadata
class FakeK8sStorageClassesList:
def __init__(self, items=[]):
self._items = items
@property
def items(self):
return self._items
fake_list_services = Dict(
{
"items": [
Dict(
{
"metadata": Dict(
{
"name": "squid",
"namespace": "test",
"labels": {"juju-app": "squid"},
}
),
"spec": Dict(
{
"cluster_ip": "10.152.183.79",
"type": "LoadBalancer",
"ports": [
Dict(
{
"name": None,
"node_port": None,
"port": 30666,
"protocol": "TCP",
"target_port": 30666,
}
)
],
}
),
"status": Dict(
{
"load_balancer": Dict(
{
"ingress": [
Dict({"hostname": None, "ip": "192.168.0.201"})
]
}
)
}
),
}
)
]
}
)
class KubectlTestCase(TestCase):
def setUp(
self,
):
pass
class FakeCoreV1Api:
def list_service_for_all_namespaces(self, **kwargs):
return fake_list_services
class GetServices(TestCase):
@mock.patch("n2vc.kubectl.config.load_kube_config")
@mock.patch("n2vc.kubectl.client.CoreV1Api")
def setUp(self, mock_core, mock_config):
mock_core.return_value = mock.MagicMock()
mock_config.return_value = mock.MagicMock()
self.kubectl = Kubectl()
@mock.patch("n2vc.kubectl.client.CoreV1Api")
def test_get_service(self, mock_corev1api):
mock_corev1api.return_value = FakeCoreV1Api()
services = self.kubectl.get_services(
field_selector="metadata.namespace", label_selector="juju-operator=squid"
)
keys = ["name", "cluster_ip", "type", "ports", "external_ip"]
self.assertTrue(k in service for service in services for k in keys)
def test_get_service_exception(self):
self.kubectl.clients[
CORE_CLIENT
].list_service_for_all_namespaces.side_effect = ApiException()
with self.assertRaises(ApiException):
self.kubectl.get_services()
@mock.patch("kubernetes.config.kube_config.Configuration")
@mock.patch("n2vc.kubectl.config.load_kube_config")
class GetConfiguration(KubectlTestCase):
def setUp(self):
super(GetConfiguration, self).setUp()
def test_get_configuration(self, mock_load_kube_config, mock_configuration):
kubectl = Kubectl()
kubectl.configuration
mock_configuration.assert_called_once()
@mock.patch("kubernetes.client.StorageV1Api.list_storage_class")
@mock.patch("kubernetes.config.load_kube_config")
class GetDefaultStorageClass(KubectlTestCase):
def setUp(self):
super(GetDefaultStorageClass, self).setUp()
# Default Storage Class
self.default_sc_name = "default-sc"
default_sc_metadata = FakeK8sResourceMetadata(
name=self.default_sc_name,
annotations={"storageclass.kubernetes.io/is-default-class": "true"},
)
self.default_sc = FakeK8sStorageClass(metadata=default_sc_metadata)
# Default Storage Class with old annotation
self.default_sc_old_name = "default-sc-old"
default_sc_old_metadata = FakeK8sResourceMetadata(
name=self.default_sc_old_name,
annotations={"storageclass.beta.kubernetes.io/is-default-class": "true"},
)
self.default_sc_old = FakeK8sStorageClass(metadata=default_sc_old_metadata)
# Storage class - not default
self.sc_name = "default-sc-old"
self.sc = FakeK8sStorageClass(
metadata=FakeK8sResourceMetadata(name=self.sc_name)
)
def test_get_default_storage_class_exists_default(
self, mock_load_kube_config, mock_list_storage_class
):
kubectl = Kubectl()
items = [self.default_sc]
mock_list_storage_class.return_value = FakeK8sStorageClassesList(items=items)
sc_name = kubectl.get_default_storage_class()
self.assertEqual(sc_name, self.default_sc_name)
mock_list_storage_class.assert_called_once()
def test_get_default_storage_class_exists_default_old(
self, mock_load_kube_config, mock_list_storage_class
):
kubectl = Kubectl()
items = [self.default_sc_old]
mock_list_storage_class.return_value = FakeK8sStorageClassesList(items=items)
sc_name = kubectl.get_default_storage_class()
self.assertEqual(sc_name, self.default_sc_old_name)
mock_list_storage_class.assert_called_once()
def test_get_default_storage_class_none(
self, mock_load_kube_config, mock_list_storage_class
):
kubectl = Kubectl()
mock_list_storage_class.return_value = FakeK8sStorageClassesList(items=[])
sc_name = kubectl.get_default_storage_class()
self.assertEqual(sc_name, None)
mock_list_storage_class.assert_called_once()
def test_get_default_storage_class_exists_not_default(
self, mock_load_kube_config, mock_list_storage_class
):
kubectl = Kubectl()
items = [self.sc]
mock_list_storage_class.return_value = FakeK8sStorageClassesList(items=items)
sc_name = kubectl.get_default_storage_class()
self.assertEqual(sc_name, self.sc_name)
mock_list_storage_class.assert_called_once()
def test_get_default_storage_class_choose(
self, mock_load_kube_config, mock_list_storage_class
):
kubectl = Kubectl()
items = [self.sc, self.default_sc]
mock_list_storage_class.return_value = FakeK8sStorageClassesList(items=items)
sc_name = kubectl.get_default_storage_class()
self.assertEqual(sc_name, self.default_sc_name)
mock_list_storage_class.assert_called_once()