11"""System Apicast that comes deployed with 3scale"""
22
33from typing import TYPE_CHECKING
4+ from urllib .parse import urlparse
45
56import backoff
6- from openshift_client import OpenShiftPythonException
7+ from openshift_client import Missing , OpenShiftPythonException
8+ from threescale_api .resources import Service
79
810from testsuite .capabilities import Capability
911from testsuite .gateways .apicast import AbstractApicast
1012from testsuite .openshift .env import Properties
13+ from testsuite .openshift .objects import Routes
1114from testsuite .utils import randomize
1215
1316if TYPE_CHECKING :
14- from typing import Optional
17+ from typing import List , Optional
1518
1619 # pylint: disable=cyclic-import
1720 from testsuite .openshift .client import OpenShiftClient
@@ -34,6 +37,54 @@ class SystemApicast(AbstractApicast):
3437 def __init__ (self , staging : bool , openshift : "Optional[OpenShiftClient]" = None ):
3538 self .staging = staging
3639 self .openshift : "Optional[OpenShiftClient]" = openshift
40+ self ._routes : "List[str]" = []
41+
42+ @property
43+ def _zync_disabled (self ) -> bool :
44+ """Returns True if zync is disabled in the APIManager spec"""
45+ if self .openshift is None :
46+ return False
47+ enabled = self .openshift .api_manager .get_path ("spec/zync/enabled" )
48+ return enabled is not Missing and not enabled
49+
50+ @staticmethod
51+ def _route_name (service : Service , production : bool = False ) -> str :
52+ env = "prod" if production else "stage"
53+ return f"testsuite-{ env } -{ service .entity_id } "
54+
55+ def _create_route (self , name : str , endpoint_url : str , ocp_service : str ):
56+ """Creates an OCP route for the given endpoint URL pointing to the given OCP service"""
57+ assert self .openshift is not None
58+ hostname = urlparse (endpoint_url ).hostname
59+ if name in self .openshift .routes :
60+ del self .openshift .routes [name ]
61+ self .openshift .routes .create (
62+ name , Routes .Types .EDGE , service = ocp_service , hostname = hostname , ** {"insecure-policy" : "Allow" }
63+ )
64+ self ._routes .append (name )
65+
66+ def on_service_create (self , service : Service ):
67+ """Creates staging OCP route when zync is disabled"""
68+ if not self ._zync_disabled :
69+ return
70+ proxy = service .proxy .fetch ()
71+ self ._create_route (self ._route_name (service ), proxy ["sandbox_endpoint" ], "apicast-staging" )
72+
73+ def on_proxy_promote (self , service : Service ):
74+ """Creates production OCP route when zync is disabled"""
75+ if not self ._zync_disabled :
76+ return
77+ proxy = service .proxy .fetch ()
78+ self ._create_route (self ._route_name (service , production = True ), proxy ["endpoint" ], "apicast-production" )
79+
80+ def on_service_delete (self , service : Service ):
81+ """Cleans up OCP routes created for this service"""
82+ if self .openshift is None :
83+ return
84+ for name in [self ._route_name (service ), self ._route_name (service , production = True )]:
85+ if name in self ._routes and name in self .openshift .routes :
86+ del self .openshift .routes [name ]
87+ self ._routes .remove (name )
3788
3889 @property
3990 def deployment (self ):
0 commit comments