mirror of
https://github.com/ansible-collections/kubernetes.core.git
synced 2026-03-26 21:33:02 +00:00
K8sService class (#307)
K8sService class SUMMARY This refactors the perform_action() logic from common.py into a separate K8sService class. TODO: Unit tests. ISSUE TYPE New Module Pull Request COMPONENT NAME service.py Reviewed-by: Abhijeet Kasurde <None> Reviewed-by: Mike Graves <mgraves@redhat.com> Reviewed-by: Alina Buzachis <None> Reviewed-by: None <None>
This commit is contained in:
committed by
Mike Graves
parent
f168a3f67f
commit
e2f54d3431
373
tests/unit/module_utils/test_service.py
Normal file
373
tests/unit/module_utils/test_service.py
Normal file
@@ -0,0 +1,373 @@
|
||||
from unittest.mock import Mock
|
||||
|
||||
import pytest
|
||||
from kubernetes.dynamic.resource import ResourceInstance, Resource
|
||||
|
||||
from ansible_collections.kubernetes.core.plugins.module_utils.k8s.service import (
|
||||
K8sService,
|
||||
)
|
||||
|
||||
from kubernetes.dynamic.exceptions import NotFoundError
|
||||
|
||||
pod_definition = {
|
||||
"apiVersion": "v1",
|
||||
"kind": "Pod",
|
||||
"metadata": {
|
||||
"name": "foo",
|
||||
"labels": {"environment": "production", "app": "nginx"},
|
||||
"namespace": "foo",
|
||||
},
|
||||
"spec": {
|
||||
"containers": [
|
||||
{
|
||||
"name": "nginx",
|
||||
"image": "nginx:1.14.2",
|
||||
"command": ["/bin/sh", "-c", "sleep 10"],
|
||||
}
|
||||
]
|
||||
},
|
||||
}
|
||||
|
||||
pod_definition_updated = {
|
||||
"apiVersion": "v1",
|
||||
"kind": "Pod",
|
||||
"metadata": {
|
||||
"name": "foo",
|
||||
"labels": {"environment": "testing", "app": "nginx"},
|
||||
"namespace": "bar",
|
||||
},
|
||||
"spec": {
|
||||
"containers": [
|
||||
{
|
||||
"name": "nginx",
|
||||
"image": "nginx:1.14.2",
|
||||
"command": ["/bin/sh", "-c", "sleep 10"],
|
||||
}
|
||||
]
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
@pytest.fixture(scope="module")
|
||||
def mock_pod_resource_instance():
|
||||
return ResourceInstance(None, pod_definition)
|
||||
|
||||
|
||||
@pytest.fixture(scope="module")
|
||||
def mock_pod_updated_resource_instance():
|
||||
return ResourceInstance(None, pod_definition_updated)
|
||||
|
||||
|
||||
def test_diff_objects_no_diff():
|
||||
svc = K8sService(Mock(), Mock())
|
||||
match, diff = svc.diff_objects(pod_definition, pod_definition)
|
||||
|
||||
assert match is True
|
||||
assert diff == {}
|
||||
|
||||
|
||||
def test_diff_objects_meta_diff():
|
||||
svc = K8sService(Mock(), Mock())
|
||||
match, diff = svc.diff_objects(pod_definition, pod_definition_updated)
|
||||
|
||||
assert match is False
|
||||
assert diff["before"] == {
|
||||
"metadata": {"labels": {"environment": "production"}, "namespace": "foo"}
|
||||
}
|
||||
assert diff["after"] == {
|
||||
"metadata": {"labels": {"environment": "testing"}, "namespace": "bar"}
|
||||
}
|
||||
|
||||
|
||||
def test_diff_objects_spec_diff():
|
||||
pod_definition_updated = {
|
||||
"apiVersion": "v1",
|
||||
"kind": "Pod",
|
||||
"metadata": {
|
||||
"name": "foo",
|
||||
"labels": {"environment": "production", "app": "nginx"},
|
||||
"namespace": "foo",
|
||||
},
|
||||
"spec": {
|
||||
"containers": [
|
||||
{
|
||||
"name": "busybox",
|
||||
"image": "busybox",
|
||||
"command": ["/bin/sh", "-c", "sleep 3600"],
|
||||
}
|
||||
]
|
||||
},
|
||||
}
|
||||
svc = K8sService(Mock(), Mock())
|
||||
match, diff = svc.diff_objects(pod_definition, pod_definition_updated)
|
||||
|
||||
assert match is False
|
||||
assert diff["before"]["spec"] == pod_definition["spec"]
|
||||
assert diff["after"]["spec"] == pod_definition_updated["spec"]
|
||||
|
||||
|
||||
def test_find_resource():
|
||||
mock_pod_resource = Resource(
|
||||
api_version="v1", kind="Pod", namespaced=False, preferred=True, prefix="api"
|
||||
)
|
||||
spec = {"resources.get.side_effect": [mock_pod_resource]}
|
||||
client = Mock(**spec)
|
||||
svc = K8sService(client, Mock())
|
||||
resource = svc.find_resource("Pod", "v1")
|
||||
|
||||
assert isinstance(resource, Resource)
|
||||
assert resource.to_dict().items() <= mock_pod_resource.to_dict().items()
|
||||
|
||||
|
||||
def test_service_delete_existing_resource(mock_pod_resource_instance):
|
||||
spec = {"delete.side_effect": [mock_pod_resource_instance]}
|
||||
client = Mock(**spec)
|
||||
module = Mock()
|
||||
module.params = {}
|
||||
module.check_mode = False
|
||||
svc = K8sService(client, module)
|
||||
results = svc.delete(Mock(), pod_definition, mock_pod_resource_instance)
|
||||
|
||||
assert isinstance(results, dict)
|
||||
assert results["changed"] is True
|
||||
assert results["result"] == pod_definition
|
||||
|
||||
|
||||
def test_service_delete_no_existing_resource():
|
||||
module = Mock()
|
||||
module.params = {}
|
||||
module.check_mode = False
|
||||
svc = K8sService(Mock(), module)
|
||||
results = svc.delete(Mock(), pod_definition)
|
||||
|
||||
assert isinstance(results, dict)
|
||||
assert results["changed"] is False
|
||||
assert results["result"] == {}
|
||||
|
||||
|
||||
def test_service_delete_existing_resource_check_mode(mock_pod_resource_instance):
|
||||
module = Mock()
|
||||
module.params = {"wait": False}
|
||||
module.check_mode = True
|
||||
svc = K8sService(Mock(), module)
|
||||
results = svc.delete(Mock(), pod_definition, mock_pod_resource_instance)
|
||||
|
||||
assert isinstance(results, dict)
|
||||
assert results["changed"] is True
|
||||
|
||||
|
||||
def test_service_create_resource(mock_pod_resource_instance):
|
||||
spec = {"create.side_effect": [mock_pod_resource_instance]}
|
||||
client = Mock(**spec)
|
||||
module = Mock()
|
||||
module.params = {}
|
||||
module.check_mode = False
|
||||
svc = K8sService(client, module)
|
||||
results = svc.create(Mock(), pod_definition)
|
||||
|
||||
assert isinstance(results, dict)
|
||||
assert results["changed"] is True
|
||||
assert results["result"] == pod_definition
|
||||
|
||||
|
||||
def test_service_create_resource_check_mode():
|
||||
client = Mock()
|
||||
client.dry_run = False
|
||||
module = Mock()
|
||||
module.params = {}
|
||||
module.check_mode = True
|
||||
svc = K8sService(client, module)
|
||||
results = svc.create(Mock(), pod_definition)
|
||||
|
||||
assert isinstance(results, dict)
|
||||
assert results["changed"] is True
|
||||
assert results["result"] == pod_definition
|
||||
|
||||
|
||||
def test_service_retrieve_existing_resource(mock_pod_resource_instance):
|
||||
spec = {"get.side_effect": [mock_pod_resource_instance]}
|
||||
client = Mock(**spec)
|
||||
module = Mock()
|
||||
module.params = {}
|
||||
svc = K8sService(client, module)
|
||||
results = svc.retrieve(Mock(), pod_definition)
|
||||
|
||||
assert isinstance(results, dict)
|
||||
assert results["changed"] is False
|
||||
assert results["result"] == pod_definition
|
||||
|
||||
|
||||
def test_service_retrieve_no_existing_resource():
|
||||
spec = {"get.side_effect": [NotFoundError(Mock())]}
|
||||
client = Mock(**spec)
|
||||
module = Mock()
|
||||
module.params = {}
|
||||
svc = K8sService(client, module)
|
||||
results = svc.retrieve(Mock(), pod_definition)
|
||||
|
||||
assert isinstance(results, dict)
|
||||
assert results["changed"] is False
|
||||
assert results["result"] == {}
|
||||
|
||||
|
||||
def test_create_project_request():
|
||||
project_definition = {
|
||||
"apiVersion": "v1",
|
||||
"kind": "ProjectRequest",
|
||||
"metadata": {"name": "test"},
|
||||
}
|
||||
spec = {"create.side_effect": [ResourceInstance(None, project_definition)]}
|
||||
client = Mock(**spec)
|
||||
module = Mock()
|
||||
module.check_mode = False
|
||||
module.params = {"state": "present"}
|
||||
svc = K8sService(client, module)
|
||||
results = svc.create_project_request(project_definition)
|
||||
|
||||
assert isinstance(results, dict)
|
||||
assert results["changed"] is True
|
||||
assert results["result"] == project_definition
|
||||
|
||||
|
||||
def test_service_apply_existing_resource(mock_pod_resource_instance):
|
||||
spec = {"apply.side_effect": [ResourceInstance(None, pod_definition_updated)]}
|
||||
client = Mock(**spec)
|
||||
module = Mock()
|
||||
module.params = {"apply": True}
|
||||
module.check_mode = False
|
||||
svc = K8sService(client, module)
|
||||
results = svc.apply(Mock(), pod_definition_updated, mock_pod_resource_instance)
|
||||
|
||||
assert isinstance(results, dict)
|
||||
assert results["changed"] is True
|
||||
assert results["diff"] is not {}
|
||||
assert results["result"] == pod_definition_updated
|
||||
|
||||
|
||||
def test_service_apply_existing_resource_no_diff(mock_pod_resource_instance):
|
||||
spec = {"apply.side_effect": [mock_pod_resource_instance]}
|
||||
client = Mock(**spec)
|
||||
module = Mock()
|
||||
module.params = {"apply": True}
|
||||
module.check_mode = False
|
||||
svc = K8sService(client, module)
|
||||
results = svc.apply(Mock(), pod_definition, mock_pod_resource_instance)
|
||||
|
||||
assert isinstance(results, dict)
|
||||
assert results["changed"] is False
|
||||
assert results["diff"] == {}
|
||||
assert results["result"] == pod_definition
|
||||
|
||||
|
||||
def test_service_apply_existing_resource_no_apply(mock_pod_resource_instance):
|
||||
spec = {"apply.side_effect": [mock_pod_resource_instance]}
|
||||
client = Mock(**spec)
|
||||
module = Mock()
|
||||
module.params = {"apply": False}
|
||||
module.check_mode = False
|
||||
svc = K8sService(client, module)
|
||||
results = svc.apply(Mock(), pod_definition, mock_pod_resource_instance)
|
||||
|
||||
assert isinstance(results, dict)
|
||||
assert results["changed"] is False
|
||||
assert results["result"] == {}
|
||||
|
||||
|
||||
def test_service_replace_existing_resource_no_diff(mock_pod_resource_instance):
|
||||
spec = {"replace.side_effect": [mock_pod_resource_instance]}
|
||||
client = Mock(**spec)
|
||||
module = Mock()
|
||||
module.params = {}
|
||||
module.check_mode = False
|
||||
svc = K8sService(client, module)
|
||||
results = svc.replace(Mock(), pod_definition, mock_pod_resource_instance)
|
||||
|
||||
assert isinstance(results, dict)
|
||||
assert results["changed"] is False
|
||||
assert results["diff"] == {}
|
||||
assert results["result"] == pod_definition
|
||||
|
||||
|
||||
def test_service_replace_existing_resource(
|
||||
mock_pod_resource_instance, mock_pod_updated_resource_instance
|
||||
):
|
||||
spec = {"replace.side_effect": [mock_pod_updated_resource_instance]}
|
||||
client = Mock(**spec)
|
||||
module = Mock()
|
||||
module.params = {}
|
||||
module.check_mode = False
|
||||
svc = K8sService(client, module)
|
||||
results = svc.replace(Mock(), pod_definition_updated, mock_pod_resource_instance)
|
||||
|
||||
assert isinstance(results, dict)
|
||||
assert results["changed"] is True
|
||||
assert results["result"] == pod_definition_updated
|
||||
assert results["diff"] != {}
|
||||
assert results["diff"]["before"] is not {}
|
||||
assert results["diff"]["after"] is not {}
|
||||
|
||||
|
||||
def test_service_update_existing_resource(
|
||||
mock_pod_resource_instance, mock_pod_updated_resource_instance
|
||||
):
|
||||
spec = {"replace.side_effect": [mock_pod_updated_resource_instance]}
|
||||
client = Mock(**spec)
|
||||
module = Mock()
|
||||
module.params = {}
|
||||
module.check_mode = False
|
||||
svc = K8sService(client, module)
|
||||
results = svc.replace(Mock(), pod_definition_updated, mock_pod_resource_instance)
|
||||
|
||||
assert isinstance(results, dict)
|
||||
assert results["changed"] is True
|
||||
assert results["result"] == pod_definition_updated
|
||||
assert results["diff"] != {}
|
||||
assert results["diff"]["before"] is not {}
|
||||
assert results["diff"]["after"] is not {}
|
||||
|
||||
|
||||
def test_service_update_existing_resource_no_diff(mock_pod_updated_resource_instance):
|
||||
spec = {"replace.side_effect": [mock_pod_updated_resource_instance]}
|
||||
client = Mock(**spec)
|
||||
module = Mock()
|
||||
module.params = {}
|
||||
module.check_mode = False
|
||||
svc = K8sService(client, module)
|
||||
results = svc.replace(
|
||||
Mock(), pod_definition_updated, mock_pod_updated_resource_instance
|
||||
)
|
||||
|
||||
assert isinstance(results, dict)
|
||||
assert results["changed"] is False
|
||||
assert results["result"] == pod_definition_updated
|
||||
assert results["diff"] == {}
|
||||
|
||||
|
||||
def test_service_find(mock_pod_resource_instance):
|
||||
spec = {"get.side_effect": [mock_pod_resource_instance]}
|
||||
client = Mock(**spec)
|
||||
module = Mock()
|
||||
module.params = {}
|
||||
module.check_mode = False
|
||||
svc = K8sService(client, module)
|
||||
results = svc.find("Pod", "v1", name="foo", namespace="foo")
|
||||
|
||||
assert isinstance(results, dict)
|
||||
assert results["api_found"] is True
|
||||
assert results["resources"] is not []
|
||||
assert len(results["resources"]) == 1
|
||||
assert results["resources"][0] == pod_definition
|
||||
|
||||
|
||||
def test_service_find_error():
|
||||
spec = {"get.side_effect": [NotFoundError(Mock())]}
|
||||
client = Mock(**spec)
|
||||
module = Mock()
|
||||
module.params = {}
|
||||
module.check_mode = False
|
||||
svc = K8sService(client, module)
|
||||
results = svc.find("Pod", "v1", name="foo", namespace="foo")
|
||||
|
||||
assert isinstance(results, dict)
|
||||
assert results["api_found"] is True
|
||||
assert results["resources"] == []
|
||||
@@ -83,7 +83,10 @@ def test_waiter_waits_for_missing_resource():
|
||||
client = Mock(**spec)
|
||||
resource = Mock()
|
||||
result, instance, elapsed = Waiter(client, resource, exists).wait(
|
||||
RESOURCES[0], 3, 1
|
||||
timeout=3,
|
||||
sleep=1,
|
||||
name=RESOURCES[0]["metadata"].get("name"),
|
||||
namespace=RESOURCES[0]["metadata"].get("namespace"),
|
||||
)
|
||||
assert result is False
|
||||
assert instance is None
|
||||
@@ -95,7 +98,12 @@ def test_waiter_waits_for_resource_to_exist(resource, expected):
|
||||
result = resource.to_dict()
|
||||
spec = {"get.side_effect": [NotFoundError(Mock()), resource, resource, resource]}
|
||||
client = Mock(**spec)
|
||||
success, instance, elapsed = Waiter(client, Mock(), exists).wait(result, 3, 1)
|
||||
success, instance, elapsed = Waiter(client, Mock(), exists).wait(
|
||||
timeout=3,
|
||||
sleep=1,
|
||||
name=result["metadata"].get("name"),
|
||||
namespace=result["metadata"].get("namespace"),
|
||||
)
|
||||
assert success is expected
|
||||
assert instance == result
|
||||
assert abs(elapsed - 2) <= 1
|
||||
|
||||
Reference in New Issue
Block a user