diff --git a/operator/gefyra/bridge/carrier/__init__.py b/operator/gefyra/bridge/carrier/__init__.py index 29dd4e4d..b032ee2f 100644 --- a/operator/gefyra/bridge/carrier/__init__.py +++ b/operator/gefyra/bridge/carrier/__init__.py @@ -1,6 +1,7 @@ import json from typing import Any, Dict, List, Optional -from gefyra.utils import BridgeException, exec_command_pod +from gefyra.bridge.exceptions import BridgeInstallException +from gefyra.utils import exec_command_pod import kubernetes as k8s from gefyra.bridge.abstract import AbstractGefyraBridgeProvider @@ -33,12 +34,7 @@ def __init__( def install(self, parameters: Optional[Dict[Any, Any]] = None): parameters = parameters or {} - try: - self._patch_pod_with_carrier( - handle_probes=parameters.get("handleProbes", True) - ) - except BridgeException as be: - raise BridgeException from be + self._patch_pod_with_carrier(handle_probes=parameters.get("handleProbes", True)) def _ensure_probes(self, container: k8s.client.V1Container) -> bool: probes = self._get_all_probes(container) @@ -144,11 +140,9 @@ def _patch_pod_with_carrier( self._get_all_probes(container), ) ): - self.logger.error( - "Not all of the probes to be handled are currently" - " supported by Gefyra" + raise BridgeInstallException( + message="Not all of the probes to be handled are currently supported by Gefyra" ) - raise BridgeException() if ( container.image == f"{self.configuration.CARRIER_IMAGE}:{self.configuration.CARRIER_IMAGE_TAG}" @@ -162,8 +156,8 @@ def _patch_pod_with_carrier( container.image = f"{self.configuration.CARRIER_IMAGE}:{self.configuration.CARRIER_IMAGE_TAG}" break else: - raise RuntimeError( - f"Could not found container {self.container} in Pod {self.pod}" + raise BridgeInstallException( + message=f"Could not found container {self.container} in Pod {self.pod}" ) self.logger.info( f"Now patching Pod {self.pod}; container {self.container} with Carrier" diff --git a/operator/gefyra/bridge/exceptions.py b/operator/gefyra/bridge/exceptions.py new file mode 100644 index 00000000..677fb92b --- /dev/null +++ b/operator/gefyra/bridge/exceptions.py @@ -0,0 +1,5 @@ +from gefyra.exceptions import BridgeException + + +class BridgeInstallException(BridgeException): + pass diff --git a/operator/gefyra/bridgestate.py b/operator/gefyra/bridgestate.py index 7f9f53b1..9c214fc4 100644 --- a/operator/gefyra/bridgestate.py +++ b/operator/gefyra/bridgestate.py @@ -10,7 +10,8 @@ from gefyra.base import GefyraStateObject, StateControllerMixin from gefyra.configuration import OperatorConfiguration -from gefyra.utils import BridgeException +from gefyra.bridge.exceptions import BridgeInstallException +from gefyra.exceptions import BridgeException class GefyraBridgeObject(GefyraStateObject): @@ -38,7 +39,7 @@ class GefyraBridge(StateMachine, StateControllerMixin): install = ( requested.to(installing, on="_install_provider") - | installing.to(error) + | error.to(installing) | installing.to.itself(on="_wait_for_provider") ) set_installed = ( @@ -124,8 +125,9 @@ def _install_provider(self): """ try: self.bridge_provider.install() - except BridgeException: - self.send("impair") + except BridgeInstallException as be: + self.logger.debug(f"Encountered: {be}") + self.send("impair", exception=be) def _wait_for_provider(self): if not self.bridge_provider.ready(): @@ -193,3 +195,11 @@ def on_remove(self): def on_restore(self): self.bridge_provider.uninstall() self.send("terminate") + + def on_impair(self, exception: BridgeException | None): + self.logger.error(f"Failed from {self.current_state}") + self.post_event( + reason=f"Failed from {self.current_state}", + message=exception.message, + _type="Warning", + ) diff --git a/operator/gefyra/exceptions.py b/operator/gefyra/exceptions.py new file mode 100644 index 00000000..1af400c1 --- /dev/null +++ b/operator/gefyra/exceptions.py @@ -0,0 +1,5 @@ +class BridgeException(Exception): + message: str + + def __init__(self, message: str): + self.message = message diff --git a/operator/gefyra/utils.py b/operator/gefyra/utils.py index afb8d17d..04cc204c 100644 --- a/operator/gefyra/utils.py +++ b/operator/gefyra/utils.py @@ -13,10 +13,6 @@ logger = logging.getLogger("gefyra.utils") -class BridgeException(Exception): - pass - - def get_label_selector(labels: dict[str, str]) -> str: return ",".join(["{0}={1}".format(*label) for label in list(labels.items())]) diff --git a/operator/tests/e2e/test_create_bridge.py b/operator/tests/e2e/test_create_bridge.py index 853bccf9..acaf8886 100644 --- a/operator/tests/e2e/test_create_bridge.py +++ b/operator/tests/e2e/test_create_bridge.py @@ -1,7 +1,5 @@ import json import logging -import subprocess -import pytest from pytest_kubernetes.providers import AClusterManager from .utils import GefyraDockerClient @@ -148,7 +146,7 @@ def test_c_fail_create_not_supported_bridges( k3d.wait("ns/demo-failing", "jsonpath='{.status.phase}'=Active") k3d.apply("tests/fixtures/demo_pods_not_supported.yaml") k3d.wait( - "pod/backend", + "pod/frontend", "condition=ready", namespace="demo-failing", timeout=60, @@ -164,11 +162,9 @@ def test_c_fail_create_not_supported_bridges( ) # applying the bridge shouldn't have worked - with pytest.raises(subprocess.TimeoutExpired): - k3d.wait( - "pod/frontend", - "jsonpath=.status.containerStatuses[0].image=docker.io/library/" - + carrier_image, - namespace="demo-failing", - timeout=60, - ) + k3d.wait( + "pod/frontend", + "condition=ready", + namespace="demo-failing", + timeout=60, + ) diff --git a/operator/tests/fixtures/demo_pods_not_supported.yaml b/operator/tests/fixtures/demo_pods_not_supported.yaml index 57a92a69..faeece0c 100644 --- a/operator/tests/fixtures/demo_pods_not_supported.yaml +++ b/operator/tests/fixtures/demo_pods_not_supported.yaml @@ -1,23 +1,7 @@ apiVersion: v1 -kind: Pod +kind: Namespace metadata: - name: backend - namespace: demo-failing - labels: - app: backend -spec: - securityContext: - runAsUser: 1000 - runAsGroup: 1000 - fsGroup: 1000 - containers: - - name: backend - image: quay.io/gefyra/gefyra-demo-backend - imagePullPolicy: IfNotPresent - ports: - - name: web - containerPort: 5002 - protocol: TCP + name: demo-failing --- apiVersion: v1 kind: Pod @@ -41,41 +25,14 @@ spec: livenessProbe: exec: command: - - cat - - /tmp/healthy + - ls + - /tmp initialDelaySeconds: 30 periodSeconds: 10 readinessProbe: exec: command: - - cat - - /tmp/ready + - ls + - /tmp initialDelaySeconds: 5 - periodSeconds: 5 ---- -apiVersion: v1 -kind: Service -metadata: - name: backend - namespace: demo-failing -spec: - selector: - app: backend - ports: - - protocol: TCP - port: 5002 - targetPort: 5002 ---- -apiVersion: v1 -kind: Service -metadata: - name: frontend - namespace: demo-failing -spec: - selector: - app: frontend - ports: - - protocol: "TCP" - port: 80 - targetPort: 5003 - type: LoadBalancer \ No newline at end of file + periodSeconds: 5 \ No newline at end of file