Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 5 additions & 13 deletions app/handlers/handlers_services.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import base64
from collections.abc import Callable
from enum import StrEnum
from typing import cast
Expand All @@ -7,9 +6,8 @@
import kubernetes
from kopf import Body, Status

from app.crds import ResourceProxy, ResourceType
from app.crds import ResourceType
from app.utils import to_bool
from app.utils_k8s import k8s_read_namespaced_secret


def k8s_get_twingate_resource(
Expand Down Expand Up @@ -94,11 +92,6 @@ def service_to_twingate_resource(service_body: Body, namespace: str) -> dict:
f"{TLS_OBJECT_ANNOTATION} annotation is not provided."
)

if not (secret := k8s_read_namespaced_secret(namespace, secret_name)):
raise kopf.PermanentError(
f"Kubernetes Secret object: {secret_name} is missing."
)

result["spec"] |= {
"address": "kubernetes.default.svc.cluster.local",
"proxy": {
Expand All @@ -107,11 +100,10 @@ def service_to_twingate_resource(service_body: Body, namespace: str) -> dict:
if spec["type"] == ServiceType.LOAD_BALANCER
else f"{service_name}.{namespace}.svc.cluster.local"
),
"certificateAuthorityCert": base64.b64encode(
ResourceProxy.read_certificate_authority_cert_from_secret(
secret
).encode()
).decode(),
"certificateAuthorityCertSecretRef": {
"name": secret_name,
"namespace": namespace,
},
},
}

Expand Down
57 changes: 13 additions & 44 deletions app/handlers/tests/test_handlers_services.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,7 @@
import yaml
from kopf._core.intents.causes import Reason

from app.api.tests.factories import BASE64_OF_VALID_CA_CERT
from app.crds import ResourceProxy, ResourceType
from app.crds import ResourceType
from app.handlers.handlers_services import (
ALLOWED_EXTRA_ANNOTATIONS,
TLS_OBJECT_ANNOTATION,
Expand Down Expand Up @@ -172,26 +171,13 @@ def test_with_extra_annotation(
assert result == expected

def test_kubernetes_resource_type_annotation(
self,
example_cluster_ip_gateway_service_body,
k8s_core_client_mock,
k8s_secret_mock,
self, example_cluster_ip_gateway_service_body
):
tls_object_name = "gateway-tls"
namespace = "custom-namespace"
k8s_core_client_mock.read_namespaced_secret.return_value = k8s_secret_mock

with patch(
"app.handlers.handlers_services.ResourceProxy.read_certificate_authority_cert_from_secret",
wraps=ResourceProxy.read_certificate_authority_cert_from_secret,
) as read_ca_cert_mock:
result = service_to_twingate_resource(
example_cluster_ip_gateway_service_body, namespace
)

read_ca_cert_mock.assert_called_once_with(k8s_secret_mock)
k8s_core_client_mock.read_namespaced_secret.assert_called_once_with(
namespace=namespace, name=tls_object_name
result = service_to_twingate_resource(
example_cluster_ip_gateway_service_body, namespace
)

assert result["spec"] == {
Expand All @@ -200,7 +186,10 @@ def test_kubernetes_resource_type_annotation(
"alias": "alias.int",
"proxy": {
"address": "kubernetes-gateway.custom-namespace.svc.cluster.local",
"certificateAuthorityCert": BASE64_OF_VALID_CA_CERT,
"certificateAuthorityCertSecretRef": {
"name": tls_object_name,
"namespace": namespace,
},
},
"protocols": {
"allowIcmp": False,
Expand Down Expand Up @@ -231,19 +220,6 @@ def test_kubernetes_resource_type_annotation_without_tls_secret_annotation(
example_cluster_ip_gateway_service_body, "default"
)

def test_kubernetes_resource_type_annotation_without_k8s_secret_object(
self, example_cluster_ip_gateway_service_body, k8s_core_client_mock
):
k8s_core_client_mock.read_namespaced_secret.return_value = None

with pytest.raises(
kopf.PermanentError,
match=r"Kubernetes Secret object: gateway-tls is missing.",
):
service_to_twingate_resource(
example_cluster_ip_gateway_service_body, "default"
)

@pytest.mark.parametrize(
("status", "expected"),
[
Expand All @@ -255,16 +231,10 @@ def test_kubernetes_resource_type_annotation_without_k8s_secret_object(
],
)
def test_kubernetes_resource_with_load_balancer_service_type(
self,
example_load_balancer_gateway_service_body,
k8s_core_client_mock,
k8s_secret_mock,
status,
expected,
self, example_load_balancer_gateway_service_body, status, expected
):
tls_object_name = "gateway-tls"
namespace = "default"
k8s_core_client_mock.read_namespaced_secret.return_value = k8s_secret_mock

with patch(
"kopf._cogs.structs.bodies.Body.status",
Expand All @@ -275,17 +245,16 @@ def test_kubernetes_resource_with_load_balancer_service_type(
example_load_balancer_gateway_service_body, namespace
)

k8s_core_client_mock.read_namespaced_secret.assert_called_once_with(
namespace=namespace, name=tls_object_name
)

assert result["spec"] == {
"name": "kubernetes-gateway-resource",
"address": "kubernetes.default.svc.cluster.local",
"alias": "alias.int",
"proxy": {
"address": expected,
"certificateAuthorityCert": BASE64_OF_VALID_CA_CERT,
"certificateAuthorityCertSecretRef": {
"name": tls_object_name,
"namespace": namespace,
},
},
"protocols": {
"allowIcmp": False,
Expand Down
2 changes: 1 addition & 1 deletion tests_integration/test_connector_flows.py
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ def test_connector_flows_image_change(run_kopf, random_name_generator):
assert secret["data"] == {"TWINGATE_ACCESS_TOKEN": ANY, "TWINGATE_REFRESH_TOKEN": ANY} # fmt: skip

# Change image tag
# kubectl patch tc/test-connector-image-local -p '{"spec": {"image": {"tag": "1.78.0"}}}' --type=merge
# kubectl patch tc/test-connector-image-local -p '{"spec": {"image": {"tag": "1.63.0"}}}' --type=merge
kubectl_patch(f"tc/{connector_name}", {"spec": {"image": {"tag": "1.78.0"}}})
time.sleep(5)
wait_for_deployment()
Expand Down