@@ -60,7 +60,9 @@ <h1 class="title">Module <code>codeflare_sdk.cluster.cluster</code></h1>
6060
6161from .auth import config_check, api_config_handler
6262from ..utils import pretty_print
63- from ..utils.generate_yaml import generate_appwrapper
63+ from ..utils.generate_yaml import (
64+ generate_appwrapper,
65+ )
6466from ..utils.kube_api_helpers import _kube_api_error_handling
6567from ..utils.openshift_oauth import (
6668 create_openshift_oauth_objects,
@@ -207,6 +209,8 @@ <h1 class="title">Module <code>codeflare_sdk.cluster.cluster</code></h1>
207209 local_interactive = self.config.local_interactive
208210 image_pull_secrets = self.config.image_pull_secrets
209211 dispatch_priority = self.config.dispatch_priority
212+ ingress_domain = self.config.ingress_domain
213+ ingress_options = self.config.ingress_options
210214 return generate_appwrapper(
211215 name=name,
212216 namespace=namespace,
@@ -230,6 +234,8 @@ <h1 class="title">Module <code>codeflare_sdk.cluster.cluster</code></h1>
230234 dispatch_priority=dispatch_priority,
231235 priority_val=priority_val,
232236 openshift_oauth=self.config.openshift_oauth,
237+ ingress_domain=ingress_domain,
238+ ingress_options=ingress_options,
233239 )
234240
235241 # creates a new cluster with the provided or default spec
@@ -368,7 +374,7 @@ <h1 class="title">Module <code>codeflare_sdk.cluster.cluster</code></h1>
368374 timeout=5,
369375 verify=self._client_verify_tls,
370376 )
371- except requests.exceptions.SSLError:
377+ except requests.exceptions.SSLError: # pragma no cover
372378 # SSL exception occurs when oauth ingress has been created but cluster is not up
373379 return False
374380 if response.status_code == 200:
@@ -431,27 +437,24 @@ <h1 class="title">Module <code>codeflare_sdk.cluster.cluster</code></h1>
431437 """
432438 try:
433439 config_check()
434- api_instance = client.CustomObjectsApi(api_config_handler())
435- routes = api_instance.list_namespaced_custom_object(
436- group="route.openshift.io",
437- version="v1",
438- namespace=self.config.namespace,
439- plural="routes",
440- )
441- except Exception as e: # pragma: no cover
440+ api_instance = client.NetworkingV1Api(api_config_handler())
441+ ingresses = api_instance.list_namespaced_ingress(self.config.namespace)
442+ except Exception as e: # pragma no cover
442443 return _kube_api_error_handling(e)
443444
444- for route in routes["items"]:
445- if route["metadata"][
446- "name"
447- ] == f"ray-dashboard-{self.config.name}" or route["metadata"][
448- "name"
449- ].startswith(
450- f"{self.config.name}-ingress"
445+ for ingress in ingresses.items:
446+ annotations = ingress.metadata.annotations
447+ protocol = "http"
448+ if (
449+ ingress.metadata.name == f"ray-dashboard-{self.config.name}"
450+ or ingress.metadata.name.startswith(f"{self.config.name}-ingress")
451451 ):
452- protocol = "https" if route["spec"].get("tls") else "http"
453- return f"{protocol}://{route['spec']['host']}"
454- return "Dashboard route not available yet, have you run cluster.up()?"
452+ if annotations == None:
453+ protocol = "http"
454+ elif "route.openshift.io/termination" in annotations:
455+ protocol = "https"
456+ return f"{protocol}://{ingress.spec.rules[0].host}"
457+ return "Dashboard ingress not available yet, have you run cluster.up()?"
455458
456459 def list_jobs(self) -> List:
457460 """
@@ -530,8 +533,8 @@ <h1 class="title">Module <code>codeflare_sdk.cluster.cluster</code></h1>
530533
531534 def local_client_url(self):
532535 if self.config.local_interactive == True:
533- ingress_domain = _get_ingress_domain()
534- return f"ray://rayclient-{self.config.name}-{self.config.namespace}. {ingress_domain}"
536+ ingress_domain = _get_ingress_domain(self )
537+ return f"ray://{ingress_domain}"
535538 else:
536539 return "None"
537540
@@ -687,16 +690,23 @@ <h1 class="title">Module <code>codeflare_sdk.cluster.cluster</code></h1>
687690 return False
688691
689692
690- def _get_ingress_domain():
693+ # Cant test this until get_current_namespace is fixed
694+ def _get_ingress_domain(self): # pragma: no cover
691695 try:
692696 config_check()
693- api_client = client.CustomObjectsApi(api_config_handler())
694- ingress = api_client.get_cluster_custom_object(
695- "config.openshift.io", "v1", "ingresses", "cluster"
696- )
697+ api_client = client.NetworkingV1Api(api_config_handler())
698+ if self.config.namespace != None:
699+ namespace = self.config.namespace
700+ else:
701+ namespace = get_current_namespace()
702+ ingresses = api_client.list_namespaced_ingress(namespace)
697703 except Exception as e: # pragma: no cover
698704 return _kube_api_error_handling(e)
699- return ingress["spec"]["domain"]
705+ domain = None
706+ for ingress in ingresses.items:
707+ if ingress.spec.rules[0].http.paths[0].backend.service.port.number == 10001:
708+ domain = ingress.spec.rules[0].host
709+ return domain
700710
701711
702712def _app_wrapper_status(name, namespace="default") -> Optional[AppWrapper]:
@@ -788,27 +798,25 @@ <h1 class="title">Module <code>codeflare_sdk.cluster.cluster</code></h1>
788798 status = RayClusterStatus(rc["status"]["state"].lower())
789799 else:
790800 status = RayClusterStatus.UNKNOWN
791-
792- config_check()
793- api_instance = client.CustomObjectsApi(api_config_handler())
794- # UPDATE THIS
795- routes = api_instance.list_namespaced_custom_object(
796- group="route.openshift.io",
797- version="v1",
798- namespace=rc["metadata"]["namespace"],
799- plural="routes",
800- )
801- ray_route = None
802- for route in routes["items"]:
803- if route["metadata"][
804- "name"
805- ] == f"ray-dashboard-{rc['metadata']['name']}" or route["metadata"][
806- "name"
807- ].startswith(
808- f"{rc['metadata']['name']}-ingress"
801+ try:
802+ config_check()
803+ api_instance = client.NetworkingV1Api(api_config_handler())
804+ ingresses = api_instance.list_namespaced_ingress(rc["metadata"]["namespace"])
805+ except Exception as e: # pragma no cover
806+ return _kube_api_error_handling(e)
807+ ray_ingress = None
808+ for ingress in ingresses.items:
809+ annotations = ingress.metadata.annotations
810+ protocol = "http"
811+ if (
812+ ingress.metadata.name == f"ray-dashboard-{rc['metadata']['name']}"
813+ or ingress.metadata.name.startswith(f"{rc['metadata']['name']}-ingress")
809814 ):
810- protocol = "https" if route["spec"].get("tls") else "http"
811- ray_route = f"{protocol}://{route['spec']['host']}"
815+ if annotations == None:
816+ protocol = "http"
817+ elif "route.openshift.io/termination" in annotations:
818+ protocol = "https"
819+ ray_ingress = f"{protocol}://{ingress.spec.rules[0].host}"
812820
813821 return RayCluster(
814822 name=rc["metadata"]["name"],
@@ -826,7 +834,6 @@ <h1 class="title">Module <code>codeflare_sdk.cluster.cluster</code></h1>
826834 ]["resources"]["limits"]["cpu"],
827835 worker_gpu=0, # hard to detect currently how many gpus, can override it with what the user asked for
828836 namespace=rc["metadata"]["namespace"],
829- dashboard=ray_route,
830837 head_cpus=rc["spec"]["headGroupSpec"]["template"]["spec"]["containers"][0][
831838 "resources"
832839 ]["limits"]["cpu"],
@@ -836,6 +843,7 @@ <h1 class="title">Module <code>codeflare_sdk.cluster.cluster</code></h1>
836843 head_gpu=rc["spec"]["headGroupSpec"]["template"]["spec"]["containers"][0][
837844 "resources"
838845 ]["limits"]["nvidia.com/gpu"],
846+ dashboard=ray_ingress,
839847 )
840848
841849
@@ -1136,6 +1144,8 @@ <h2 class="section-title" id="header-classes">Classes</h2>
11361144 local_interactive = self.config.local_interactive
11371145 image_pull_secrets = self.config.image_pull_secrets
11381146 dispatch_priority = self.config.dispatch_priority
1147+ ingress_domain = self.config.ingress_domain
1148+ ingress_options = self.config.ingress_options
11391149 return generate_appwrapper(
11401150 name=name,
11411151 namespace=namespace,
@@ -1159,6 +1169,8 @@ <h2 class="section-title" id="header-classes">Classes</h2>
11591169 dispatch_priority=dispatch_priority,
11601170 priority_val=priority_val,
11611171 openshift_oauth=self.config.openshift_oauth,
1172+ ingress_domain=ingress_domain,
1173+ ingress_options=ingress_options,
11621174 )
11631175
11641176 # creates a new cluster with the provided or default spec
@@ -1297,7 +1309,7 @@ <h2 class="section-title" id="header-classes">Classes</h2>
12971309 timeout=5,
12981310 verify=self._client_verify_tls,
12991311 )
1300- except requests.exceptions.SSLError:
1312+ except requests.exceptions.SSLError: # pragma no cover
13011313 # SSL exception occurs when oauth ingress has been created but cluster is not up
13021314 return False
13031315 if response.status_code == 200:
@@ -1360,27 +1372,24 @@ <h2 class="section-title" id="header-classes">Classes</h2>
13601372 """
13611373 try:
13621374 config_check()
1363- api_instance = client.CustomObjectsApi(api_config_handler())
1364- routes = api_instance.list_namespaced_custom_object(
1365- group="route.openshift.io",
1366- version="v1",
1367- namespace=self.config.namespace,
1368- plural="routes",
1369- )
1370- except Exception as e: # pragma: no cover
1375+ api_instance = client.NetworkingV1Api(api_config_handler())
1376+ ingresses = api_instance.list_namespaced_ingress(self.config.namespace)
1377+ except Exception as e: # pragma no cover
13711378 return _kube_api_error_handling(e)
13721379
1373- for route in routes["items"]:
1374- if route["metadata"][
1375- "name"
1376- ] == f"ray-dashboard-{self.config.name}" or route["metadata"][
1377- "name"
1378- ].startswith(
1379- f"{self.config.name}-ingress"
1380+ for ingress in ingresses.items:
1381+ annotations = ingress.metadata.annotations
1382+ protocol = "http"
1383+ if (
1384+ ingress.metadata.name == f"ray-dashboard-{self.config.name}"
1385+ or ingress.metadata.name.startswith(f"{self.config.name}-ingress")
13801386 ):
1381- protocol = "https" if route["spec"].get("tls") else "http"
1382- return f"{protocol}://{route['spec']['host']}"
1383- return "Dashboard route not available yet, have you run cluster.up()?"
1387+ if annotations == None:
1388+ protocol = "http"
1389+ elif "route.openshift.io/termination" in annotations:
1390+ protocol = "https"
1391+ return f"{protocol}://{ingress.spec.rules[0].host}"
1392+ return "Dashboard ingress not available yet, have you run cluster.up()?"
13841393
13851394 def list_jobs(self) -> List:
13861395 """
@@ -1459,8 +1468,8 @@ <h2 class="section-title" id="header-classes">Classes</h2>
14591468
14601469 def local_client_url(self):
14611470 if self.config.local_interactive == True:
1462- ingress_domain = _get_ingress_domain()
1463- return f"ray://rayclient-{self.config.name}-{self.config.namespace}. {ingress_domain}"
1471+ ingress_domain = _get_ingress_domain(self )
1472+ return f"ray://{ingress_domain}"
14641473 else:
14651474 return "None"
14661475
@@ -1580,27 +1589,24 @@ <h3>Methods</h3>
15801589 """
15811590 try:
15821591 config_check()
1583- api_instance = client.CustomObjectsApi(api_config_handler())
1584- routes = api_instance.list_namespaced_custom_object(
1585- group="route.openshift.io",
1586- version="v1",
1587- namespace=self.config.namespace,
1588- plural="routes",
1589- )
1590- except Exception as e: # pragma: no cover
1592+ api_instance = client.NetworkingV1Api(api_config_handler())
1593+ ingresses = api_instance.list_namespaced_ingress(self.config.namespace)
1594+ except Exception as e: # pragma no cover
15911595 return _kube_api_error_handling(e)
15921596
1593- for route in routes["items"]:
1594- if route["metadata"][
1595- "name"
1596- ] == f"ray-dashboard-{self.config.name}" or route["metadata"][
1597- "name"
1598- ].startswith(
1599- f"{self.config.name}-ingress"
1597+ for ingress in ingresses.items:
1598+ annotations = ingress.metadata.annotations
1599+ protocol = "http"
1600+ if (
1601+ ingress.metadata.name == f"ray-dashboard-{self.config.name}"
1602+ or ingress.metadata.name.startswith(f"{self.config.name}-ingress")
16001603 ):
1601- protocol = "https" if route["spec"].get("tls") else "http"
1602- return f"{protocol}://{route['spec']['host']}"
1603- return "Dashboard route not available yet, have you run cluster.up()?"</ code > </ pre >
1604+ if annotations == None:
1605+ protocol = "http"
1606+ elif "route.openshift.io/termination" in annotations:
1607+ protocol = "https"
1608+ return f"{protocol}://{ingress.spec.rules[0].host}"
1609+ return "Dashboard ingress not available yet, have you run cluster.up()?"</ code > </ pre >
16041610</ details >
16051611</ dd >
16061612< dt id ="codeflare_sdk.cluster.cluster.Cluster.cluster_uri "> < code class ="name flex ">
@@ -1678,6 +1684,8 @@ <h3>Methods</h3>
16781684 local_interactive = self.config.local_interactive
16791685 image_pull_secrets = self.config.image_pull_secrets
16801686 dispatch_priority = self.config.dispatch_priority
1687+ ingress_domain = self.config.ingress_domain
1688+ ingress_options = self.config.ingress_options
16811689 return generate_appwrapper(
16821690 name=name,
16831691 namespace=namespace,
@@ -1701,6 +1709,8 @@ <h3>Methods</h3>
17011709 dispatch_priority=dispatch_priority,
17021710 priority_val=priority_val,
17031711 openshift_oauth=self.config.openshift_oauth,
1712+ ingress_domain=ingress_domain,
1713+ ingress_options=ingress_options,
17041714 )</ code > </ pre >
17051715</ details >
17061716</ dd >
@@ -1858,7 +1868,7 @@ <h3>Methods</h3>
18581868 timeout=5,
18591869 verify=self._client_verify_tls,
18601870 )
1861- except requests.exceptions.SSLError:
1871+ except requests.exceptions.SSLError: # pragma no cover
18621872 # SSL exception occurs when oauth ingress has been created but cluster is not up
18631873 return False
18641874 if response.status_code == 200:
@@ -1926,8 +1936,8 @@ <h3>Methods</h3>
19261936</ summary >
19271937< pre > < code class ="python "> def local_client_url(self):
19281938 if self.config.local_interactive == True:
1929- ingress_domain = _get_ingress_domain()
1930- return f"ray://rayclient-{self.config.name}-{self.config.namespace}. {ingress_domain}"
1939+ ingress_domain = _get_ingress_domain(self )
1940+ return f"ray://{ingress_domain}"
19311941 else:
19321942 return "None"</ code > </ pre >
19331943</ details >
0 commit comments