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