21
21
import sys
22
22
import argparse
23
23
import uuid
24
+ from os import urandom
25
+ from base64 import b64encode
26
+ from urllib3 .util import parse_url
27
+
24
28
import openshift as oc
29
+ from kubernetes import client , config
25
30
31
+ k8_client = config .new_client_from_config ()
26
32
27
33
def read_template (template ):
28
34
with open (template , "r" ) as stream :
@@ -44,12 +50,14 @@ def gen_names(name):
44
50
45
51
def update_dashboard_route (route_item , cluster_name , namespace ):
46
52
metadata = route_item .get ("generictemplate" , {}).get ("metadata" )
47
- metadata ["name" ] = f"ray-dashboard- { cluster_name } "
53
+ metadata ["name" ] = gen_dashboard_route_name ( cluster_name )
48
54
metadata ["namespace" ] = namespace
49
55
metadata ["labels" ]["odh-ray-cluster-service" ] = f"{ cluster_name } -head-svc"
50
56
spec = route_item .get ("generictemplate" , {}).get ("spec" )
51
57
spec ["to" ]["name" ] = f"{ cluster_name } -head-svc"
52
58
59
+ def gen_dashboard_route_name (cluster_name ):
60
+ return f"ray-dashboard-{ cluster_name } "
53
61
54
62
# ToDo: refactor the update_x_route() functions
55
63
def update_rayclient_route (route_item , cluster_name , namespace ):
@@ -289,6 +297,64 @@ def write_user_appwrapper(user_yaml, output_file_name):
289
297
print (f"Written to: { output_file_name } " )
290
298
291
299
300
+ def enable_openshift_oauth (user_yaml , cluster_name , namespace ):
301
+ tls_mount_location = "/etc/tls/private"
302
+ oauth_port = 443
303
+ oauth_sa_name = f"{ cluster_name } -oauth-proxy"
304
+ tls_secret_name = f"{ cluster_name } -proxy-tls-secret"
305
+ tls_volume_name = "proxy-tls-secret"
306
+ port_name = "oauth-proxy"
307
+ _ ,_ ,host ,_ ,_ ,_ ,_ = parse_url (k8_client .configuration .host )
308
+ host = host .replace ("api." , f"{ gen_dashboard_route_name (cluster_name )} -{ namespace } .apps." )
309
+ oauth_sidecar = _create_oauth_sidecar_object (
310
+ namespace , tls_mount_location , oauth_port , oauth_sa_name , tls_volume_name , port_name
311
+ )
312
+ tls_secret_volume = client .V1Volume (
313
+ name = tls_volume_name ,secret = client .V1SecretVolumeSource (secret_name = tls_secret_name )
314
+ )
315
+ # allows for setting value of Cluster object when initializing object from an existing AppWrapper on cluster
316
+ user_yaml ["metadata" ]["annotations" ] = user_yaml ["metadata" ].get ("annotations" , {})
317
+ user_yaml ["metadata" ]["annotations" ]["codeflare-sdk-use-oauth" ] = "true" # if the user gets an
318
+ ray_headgroup_pod = user_yaml ["spec" ]["resources" ]["GenericItems" ][0 ]["generictemplate" ]["spec" ]["headGroupSpec" ]["template" ]["spec" ]
319
+ user_yaml ["spec" ]["resources" ]["GenericItems" ].pop (1 )
320
+ ray_headgroup_pod ["serviceAccount" ] = oauth_sa_name
321
+ ray_headgroup_pod ["volumes" ] = ray_headgroup_pod .get ("volumes" , [])
322
+ ray_headgroup_pod ["volumes" ].append (k8_client .sanitize_for_serialization (tls_secret_volume ))
323
+ ray_headgroup_pod ["containers" ].append (k8_client .sanitize_for_serialization (oauth_sidecar ))
324
+ # add volume to headnode
325
+ # add sidecar container to ray object
326
+
327
+ def _create_oauth_sidecar_object (
328
+ namespace : str ,
329
+ tls_mount_location : str ,
330
+ oauth_port : int ,
331
+ oauth_sa_name : str ,
332
+ tls_volume_name : str ,
333
+ port_name : str
334
+ ) -> client .V1Container :
335
+ return client .V1Container (
336
+ args = [
337
+ f"--https-address=:{ oauth_port } " ,
338
+ "--provider=openshift" ,
339
+ f"--openshift-service-account={ oauth_sa_name } " ,
340
+ "--upstream=http://localhost:8265" ,
341
+ f"--tls-cert={ tls_mount_location } /tls.crt" ,
342
+ f"--tls-key={ tls_mount_location } /tls.key" ,
343
+ "--cookie-secret=SECRET" ,
344
+ # f"--cookie-secret={b64encode(urandom(64)).decode('utf-8')}", # create random string for encrypting cookie
345
+ f'--openshift-delegate-urls={{"/":{{"resource":"pods","namespace":"{ namespace } ","verb":"get"}}}}'
346
+ ],
347
+ image = "registry.redhat.io/openshift4/ose-oauth-proxy@sha256:1ea6a01bf3e63cdcf125c6064cbd4a4a270deaf0f157b3eabb78f60556840366" ,
348
+ name = "oauth-proxy" ,
349
+ ports = [client .V1ContainerPort (container_port = oauth_port ,name = port_name )],
350
+ resources = client .V1ResourceRequirements (limits = None ,requests = None ),
351
+ volume_mounts = [
352
+ client .V1VolumeMount (
353
+ mount_path = tls_mount_location ,name = tls_volume_name ,read_only = True
354
+ )
355
+ ],
356
+ )
357
+
292
358
def generate_appwrapper (
293
359
name : str ,
294
360
namespace : str ,
@@ -305,6 +371,7 @@ def generate_appwrapper(
305
371
env ,
306
372
local_interactive : bool ,
307
373
image_pull_secrets : list ,
374
+ openshift_oauth : bool ,
308
375
):
309
376
user_yaml = read_template (template )
310
377
appwrapper_name , cluster_name = gen_names (name )
@@ -335,6 +402,10 @@ def generate_appwrapper(
335
402
enable_local_interactive (resources , cluster_name , namespace )
336
403
else :
337
404
disable_raycluster_tls (resources ["resources" ])
405
+
406
+ if openshift_oauth :
407
+ enable_openshift_oauth (user_yaml , cluster_name , namespace )
408
+
338
409
outfile = appwrapper_name + ".yaml"
339
410
write_user_appwrapper (user_yaml , outfile )
340
411
return outfile
0 commit comments