21
21
import sys
22
22
import argparse
23
23
import uuid
24
+ < << << << HEAD
24
25
from kubernetes import client , config
25
26
from .kube_api_helpers import _kube_api_error_handling
26
27
from ..cluster .auth import api_config_handler
28
+ == == == =
29
+ from os import urandom
30
+ from base64 import b64encode
31
+ from urllib3 .util import parse_url
32
+ > >> >> >> bb0a0a7 (add functions for creating ray with oauth proxy in front of the dashboard )
27
33
34
+ import openshift as oc
35
+ from kubernetes import client , config
36
+
37
+ k8_client = config .new_client_from_config ()
28
38
29
39
def read_template (template ):
30
40
with open (template , "r" ) as stream :
@@ -46,12 +56,14 @@ def gen_names(name):
46
56
47
57
def update_dashboard_route (route_item , cluster_name , namespace ):
48
58
metadata = route_item .get ("generictemplate" , {}).get ("metadata" )
49
- metadata ["name" ] = f"ray-dashboard- { cluster_name } "
59
+ metadata ["name" ] = gen_dashboard_route_name ( cluster_name )
50
60
metadata ["namespace" ] = namespace
51
61
metadata ["labels" ]["odh-ray-cluster-service" ] = f"{ cluster_name } -head-svc"
52
62
spec = route_item .get ("generictemplate" , {}).get ("spec" )
53
63
spec ["to" ]["name" ] = f"{ cluster_name } -head-svc"
54
64
65
+ def gen_dashboard_route_name (cluster_name ):
66
+ return f"ray-dashboard-{ cluster_name } "
55
67
56
68
# ToDo: refactor the update_x_route() functions
57
69
def update_rayclient_route (route_item , cluster_name , namespace ):
@@ -347,6 +359,64 @@ def write_user_appwrapper(user_yaml, output_file_name):
347
359
print (f"Written to: { output_file_name } " )
348
360
349
361
362
+ def enable_openshift_oauth (user_yaml , cluster_name , namespace ):
363
+ tls_mount_location = "/etc/tls/private"
364
+ oauth_port = 443
365
+ oauth_sa_name = f"{ cluster_name } -oauth-proxy"
366
+ tls_secret_name = f"{ cluster_name } -proxy-tls-secret"
367
+ tls_volume_name = "proxy-tls-secret"
368
+ port_name = "oauth-proxy"
369
+ _ ,_ ,host ,_ ,_ ,_ ,_ = parse_url (k8_client .configuration .host )
370
+ host = host .replace ("api." , f"{ gen_dashboard_route_name (cluster_name )} -{ namespace } .apps." )
371
+ oauth_sidecar = _create_oauth_sidecar_object (
372
+ namespace , tls_mount_location , oauth_port , oauth_sa_name , tls_volume_name , port_name
373
+ )
374
+ tls_secret_volume = client .V1Volume (
375
+ name = tls_volume_name ,secret = client .V1SecretVolumeSource (secret_name = tls_secret_name )
376
+ )
377
+ # allows for setting value of Cluster object when initializing object from an existing AppWrapper on cluster
378
+ user_yaml ["metadata" ]["annotations" ] = user_yaml ["metadata" ].get ("annotations" , {})
379
+ user_yaml ["metadata" ]["annotations" ]["codeflare-sdk-use-oauth" ] = "true" # if the user gets an
380
+ ray_headgroup_pod = user_yaml ["spec" ]["resources" ]["GenericItems" ][0 ]["generictemplate" ]["spec" ]["headGroupSpec" ]["template" ]["spec" ]
381
+ user_yaml ["spec" ]["resources" ]["GenericItems" ].pop (1 )
382
+ ray_headgroup_pod ["serviceAccount" ] = oauth_sa_name
383
+ ray_headgroup_pod ["volumes" ] = ray_headgroup_pod .get ("volumes" , [])
384
+ ray_headgroup_pod ["volumes" ].append (k8_client .sanitize_for_serialization (tls_secret_volume ))
385
+ ray_headgroup_pod ["containers" ].append (k8_client .sanitize_for_serialization (oauth_sidecar ))
386
+ # add volume to headnode
387
+ # add sidecar container to ray object
388
+
389
+ def _create_oauth_sidecar_object (
390
+ namespace : str ,
391
+ tls_mount_location : str ,
392
+ oauth_port : int ,
393
+ oauth_sa_name : str ,
394
+ tls_volume_name : str ,
395
+ port_name : str
396
+ ) -> client .V1Container :
397
+ return client .V1Container (
398
+ args = [
399
+ f"--https-address=:{ oauth_port } " ,
400
+ "--provider=openshift" ,
401
+ f"--openshift-service-account={ oauth_sa_name } " ,
402
+ "--upstream=http://localhost:8265" ,
403
+ f"--tls-cert={ tls_mount_location } /tls.crt" ,
404
+ f"--tls-key={ tls_mount_location } /tls.key" ,
405
+ "--cookie-secret=SECRET" ,
406
+ # f"--cookie-secret={b64encode(urandom(64)).decode('utf-8')}", # create random string for encrypting cookie
407
+ f'--openshift-delegate-urls={{"/":{{"resource":"pods","namespace":"{ namespace } ","verb":"get"}}}}'
408
+ ],
409
+ image = "registry.redhat.io/openshift4/ose-oauth-proxy@sha256:1ea6a01bf3e63cdcf125c6064cbd4a4a270deaf0f157b3eabb78f60556840366" ,
410
+ name = "oauth-proxy" ,
411
+ ports = [client .V1ContainerPort (container_port = oauth_port ,name = port_name )],
412
+ resources = client .V1ResourceRequirements (limits = None ,requests = None ),
413
+ volume_mounts = [
414
+ client .V1VolumeMount (
415
+ mount_path = tls_mount_location ,name = tls_volume_name ,read_only = True
416
+ )
417
+ ],
418
+ )
419
+
350
420
def generate_appwrapper (
351
421
name : str ,
352
422
namespace : str ,
@@ -365,6 +435,7 @@ def generate_appwrapper(
365
435
image_pull_secrets : list ,
366
436
dispatch_priority : str ,
367
437
priority_val : int ,
438
+ openshift_oauth : bool ,
368
439
):
369
440
user_yaml = read_template (template )
370
441
appwrapper_name , cluster_name = gen_names (name )
@@ -396,6 +467,10 @@ def generate_appwrapper(
396
467
enable_local_interactive (resources , cluster_name , namespace )
397
468
else :
398
469
disable_raycluster_tls (resources ["resources" ])
470
+
471
+ if openshift_oauth :
472
+ enable_openshift_oauth (user_yaml , cluster_name , namespace )
473
+
399
474
outfile = appwrapper_name + ".yaml"
400
475
write_user_appwrapper (user_yaml , outfile )
401
476
return outfile
0 commit comments