@@ -34,6 +34,7 @@ import (
34
34
rayv1 "github.com/ray-project/kuberay/ray-operator/apis/ray/v1"
35
35
36
36
corev1 "k8s.io/api/core/v1"
37
+ networkingv1 "k8s.io/api/networking/v1"
37
38
rbacv1 "k8s.io/api/rbac/v1"
38
39
"k8s.io/apimachinery/pkg/api/errors"
39
40
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
@@ -48,6 +49,8 @@ import (
48
49
ctrl "sigs.k8s.io/controller-runtime"
49
50
"sigs.k8s.io/controller-runtime/pkg/client"
50
51
"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
52
+ "sigs.k8s.io/controller-runtime/pkg/handler"
53
+ "sigs.k8s.io/controller-runtime/pkg/reconcile"
51
54
52
55
routev1 "github.com/openshift/api/route/v1"
53
56
routev1ac "github.com/openshift/client-go/route/applyconfigurations/route/v1"
@@ -78,6 +81,8 @@ const (
78
81
79
82
CAPrivateKeyKey = "ca.key"
80
83
CACertKey = "ca.crt"
84
+
85
+ RayClusterNameLabel = "ray.openshift.ai/cluster-name"
81
86
)
82
87
83
88
var (
@@ -88,16 +93,16 @@ var (
88
93
// +kubebuilder:rbac:groups=ray.io,resources=rayclusters,verbs=get;list;watch;create;update;patch;delete
89
94
// +kubebuilder:rbac:groups=ray.io,resources=rayclusters/status,verbs=get;update;patch
90
95
// +kubebuilder:rbac:groups=ray.io,resources=rayclusters/finalizers,verbs=update
91
- // +kubebuilder:rbac:groups=route.openshift.io,resources=routes;routes/custom-host,verbs=get;create;update;patch;delete
92
- // +kubebuilder:rbac:groups=networking.k8s.io,resources=ingresses,verbs=get;create;update;patch;delete
93
- // +kubebuilder:rbac:groups=core,resources=secrets,verbs=get;create;patch;delete;get
94
- // +kubebuilder:rbac:groups=core,resources=services,verbs=get;create;update;patch;delete
95
- // +kubebuilder:rbac:groups=core,resources=serviceaccounts,verbs=get;create;update;patch;delete
96
- // +kubebuilder:rbac:groups=rbac.authorization.k8s.io,resources=clusterrolebindings,verbs=get;create;update;patch;delete
96
+ // +kubebuilder:rbac:groups=route.openshift.io,resources=routes;routes/custom-host,verbs=get;list; create;update;patch;delete;watch
97
+ // +kubebuilder:rbac:groups=networking.k8s.io,resources=ingresses,verbs=get;list; create;update;patch;delete;watch
98
+ // +kubebuilder:rbac:groups=core,resources=secrets,verbs=get;list; create;patch;delete;get;watch
99
+ // +kubebuilder:rbac:groups=core,resources=services,verbs=get;list; create;update;patch;delete;watch
100
+ // +kubebuilder:rbac:groups=core,resources=serviceaccounts,verbs=get;list; create;update;patch;delete;watch
101
+ // +kubebuilder:rbac:groups=rbac.authorization.k8s.io,resources=clusterrolebindings,verbs=get;list; create;update;patch;delete;watch
97
102
// +kubebuilder:rbac:groups=authentication.k8s.io,resources=tokenreviews,verbs=create;
98
103
// +kubebuilder:rbac:groups=authorization.k8s.io,resources=subjectaccessreviews,verbs=create;
99
104
// +kubebuilder:rbac:groups=dscinitialization.opendatahub.io,resources=dscinitializations,verbs=get;list;watch
100
- // +kubebuilder:rbac:groups=networking.k8s.io,resources=networkpolicies,verbs=get;create;update;patch;delete
105
+ // +kubebuilder:rbac:groups=networking.k8s.io,resources=networkpolicies,verbs=get;list; create;update;patch;delete;watch
101
106
102
107
// Reconcile is part of the main kubernetes reconciliation loop which aims to
103
108
// move the current state of the cluster closer to the desired state.
@@ -301,7 +306,7 @@ func crbNameFromCluster(cluster *rayv1.RayCluster) string {
301
306
func desiredOAuthClusterRoleBinding (cluster * rayv1.RayCluster ) * rbacv1ac.ClusterRoleBindingApplyConfiguration {
302
307
return rbacv1ac .ClusterRoleBinding (
303
308
crbNameFromCluster (cluster )).
304
- WithLabels (map [string ]string {"ray.io /cluster-name " : cluster .Name }).
309
+ WithLabels (map [string ]string {RayClusterNameLabel : cluster . Name , "ray.openshift.ai /cluster-namespace " : cluster .Namespace }).
305
310
WithSubjects (
306
311
rbacv1ac .Subject ().
307
312
WithKind ("ServiceAccount" ).
@@ -322,14 +327,14 @@ func oauthServiceAccountNameFromCluster(cluster *rayv1.RayCluster) string {
322
327
323
328
func desiredServiceAccount (cluster * rayv1.RayCluster ) * corev1ac.ServiceAccountApplyConfiguration {
324
329
return corev1ac .ServiceAccount (oauthServiceAccountNameFromCluster (cluster ), cluster .Namespace ).
325
- WithLabels (map [string ]string {"ray.io/cluster-name" : cluster .Name }).
330
+ WithLabels (map [string ]string {RayClusterNameLabel : cluster .Name }).
326
331
WithAnnotations (map [string ]string {
327
332
"serviceaccounts.openshift.io/oauth-redirectreference.first" : "" +
328
333
`{"kind":"OAuthRedirectReference","apiVersion":"v1",` +
329
334
`"reference":{"kind":"Route","name":"` + dashboardNameFromCluster (cluster ) + `"}}` ,
330
335
}).
331
336
WithOwnerReferences (
332
- metav1ac .OwnerReference ().WithUID (cluster .UID ).WithName (cluster .Name ).WithKind (cluster .Kind ).WithAPIVersion (cluster .APIVersion ),
337
+ metav1ac .OwnerReference ().WithUID (cluster .UID ).WithName (cluster .Name ).WithKind (cluster .Kind ).WithAPIVersion (cluster .APIVersion ). WithController ( true ) ,
333
338
)
334
339
}
335
340
@@ -343,7 +348,7 @@ func rayClientNameFromCluster(cluster *rayv1.RayCluster) string {
343
348
344
349
func desiredClusterRoute (cluster * rayv1.RayCluster ) * routev1ac.RouteApplyConfiguration {
345
350
return routev1ac .Route (dashboardNameFromCluster (cluster ), cluster .Namespace ).
346
- WithLabels (map [string ]string {"ray.io/cluster-name" : cluster .Name }).
351
+ WithLabels (map [string ]string {RayClusterNameLabel : cluster .Name }).
347
352
WithSpec (routev1ac .RouteSpec ().
348
353
WithTo (routev1ac .RouteTargetReference ().WithKind ("Service" ).WithName (oauthServiceNameFromCluster (cluster ))).
349
354
WithPort (routev1ac .RoutePort ().WithTargetPort (intstr .FromString ((oAuthServicePortName )))).
@@ -353,7 +358,7 @@ func desiredClusterRoute(cluster *rayv1.RayCluster) *routev1ac.RouteApplyConfigu
353
358
),
354
359
).
355
360
WithOwnerReferences (
356
- metav1ac .OwnerReference ().WithUID (cluster .UID ).WithName (cluster .Name ).WithKind (cluster .Kind ).WithAPIVersion (cluster .APIVersion ),
361
+ metav1ac .OwnerReference ().WithUID (cluster .UID ).WithName (cluster .Name ).WithKind (cluster .Kind ).WithAPIVersion (cluster .APIVersion ). WithController ( true ) ,
357
362
)
358
363
}
359
364
@@ -367,7 +372,7 @@ func oauthServiceTLSSecretName(cluster *rayv1.RayCluster) string {
367
372
368
373
func desiredOAuthService (cluster * rayv1.RayCluster ) * corev1ac.ServiceApplyConfiguration {
369
374
return corev1ac .Service (oauthServiceNameFromCluster (cluster ), cluster .Namespace ).
370
- WithLabels (map [string ]string {"ray.io/cluster-name" : cluster .Name }).
375
+ WithLabels (map [string ]string {RayClusterNameLabel : cluster .Name }).
371
376
WithAnnotations (map [string ]string {"service.beta.openshift.io/serving-cert-secret-name" : oauthServiceTLSSecretName (cluster )}).
372
377
WithSpec (
373
378
corev1ac .ServiceSpec ().
@@ -381,7 +386,7 @@ func desiredOAuthService(cluster *rayv1.RayCluster) *corev1ac.ServiceApplyConfig
381
386
WithSelector (map [string ]string {"ray.io/cluster" : cluster .Name , "ray.io/node-type" : "head" }),
382
387
).
383
388
WithOwnerReferences (
384
- metav1ac .OwnerReference ().WithUID (cluster .UID ).WithName (cluster .Name ).WithKind (cluster .Kind ).WithAPIVersion (cluster .APIVersion ),
389
+ metav1ac .OwnerReference ().WithUID (cluster .UID ).WithName (cluster .Name ).WithKind (cluster .Kind ).WithAPIVersion (cluster .APIVersion ). WithController ( true ) ,
385
390
)
386
391
}
387
392
@@ -397,10 +402,10 @@ func desiredOAuthSecret(cluster *rayv1.RayCluster, cookieSalt string) *corev1ac.
397
402
cookieSecret := base64 .StdEncoding .EncodeToString (hasher .Sum (nil ))
398
403
399
404
return corev1ac .Secret (oauthSecretNameFromCluster (cluster ), cluster .Namespace ).
400
- WithLabels (map [string ]string {"ray.io/cluster-name" : cluster .Name }).
405
+ WithLabels (map [string ]string {RayClusterNameLabel : cluster .Name }).
401
406
WithStringData (map [string ]string {"cookie_secret" : cookieSecret }).
402
407
WithOwnerReferences (
403
- metav1ac .OwnerReference ().WithUID (cluster .UID ).WithName (cluster .Name ).WithKind (cluster .Kind ).WithAPIVersion (cluster .APIVersion ),
408
+ metav1ac .OwnerReference ().WithUID (cluster .UID ).WithName (cluster .Name ).WithKind (cluster .Kind ).WithAPIVersion (cluster .APIVersion ). WithController ( true ) ,
404
409
)
405
410
}
406
411
@@ -410,7 +415,7 @@ func caSecretNameFromCluster(cluster *rayv1.RayCluster) string {
410
415
411
416
func desiredCASecret (cluster * rayv1.RayCluster , key , cert []byte ) * corev1ac.SecretApplyConfiguration {
412
417
return corev1ac .Secret (caSecretNameFromCluster (cluster ), cluster .Namespace ).
413
- WithLabels (map [string ]string {"ray.io/cluster-name" : cluster .Name }).
418
+ WithLabels (map [string ]string {RayClusterNameLabel : cluster .Name }).
414
419
WithData (map [string ][]byte {
415
420
CAPrivateKeyKey : key ,
416
421
CACertKey : cert ,
@@ -419,7 +424,8 @@ func desiredCASecret(cluster *rayv1.RayCluster, key, cert []byte) *corev1ac.Secr
419
424
WithUID (cluster .UID ).
420
425
WithName (cluster .Name ).
421
426
WithKind (cluster .Kind ).
422
- WithAPIVersion (cluster .APIVersion ))
427
+ WithAPIVersion (cluster .APIVersion ).
428
+ WithController (true ))
423
429
}
424
430
425
431
func generateCACertificate () ([]byte , []byte , error ) {
@@ -466,7 +472,7 @@ func generateCACertificate() ([]byte, []byte, error) {
466
472
}
467
473
func desiredWorkersNetworkPolicy (cluster * rayv1.RayCluster ) * networkingv1ac.NetworkPolicyApplyConfiguration {
468
474
return networkingv1ac .NetworkPolicy (cluster .Name + "-workers" , cluster .Namespace ).
469
- WithLabels (map [string ]string {"ray.io/cluster-name" : cluster .Name }).
475
+ WithLabels (map [string ]string {RayClusterNameLabel : cluster .Name }).
470
476
WithSpec (networkingv1ac .NetworkPolicySpec ().
471
477
WithPodSelector (metav1ac .LabelSelector ().WithMatchLabels (map [string ]string {"ray.io/cluster" : cluster .Name , "ray.io/node-type" : "worker" })).
472
478
WithIngress (
@@ -477,7 +483,7 @@ func desiredWorkersNetworkPolicy(cluster *rayv1.RayCluster) *networkingv1ac.Netw
477
483
),
478
484
).
479
485
WithOwnerReferences (
480
- metav1ac .OwnerReference ().WithUID (cluster .UID ).WithName (cluster .Name ).WithKind (cluster .Kind ).WithAPIVersion (cluster .APIVersion ),
486
+ metav1ac .OwnerReference ().WithUID (cluster .UID ).WithName (cluster .Name ).WithKind (cluster .Kind ).WithAPIVersion (cluster .APIVersion ). WithController ( true ) ,
481
487
)
482
488
}
483
489
func desiredHeadNetworkPolicy (cluster * rayv1.RayCluster , cfg * config.KubeRayConfiguration , kubeRayNamespaces []string ) * networkingv1ac.NetworkPolicyApplyConfiguration {
@@ -488,7 +494,7 @@ func desiredHeadNetworkPolicy(cluster *rayv1.RayCluster, cfg *config.KubeRayConf
488
494
allSecuredPorts = append (allSecuredPorts , networkingv1ac .NetworkPolicyPort ().WithProtocol (corev1 .ProtocolTCP ).WithPort (intstr .FromInt (10001 )))
489
495
}
490
496
return networkingv1ac .NetworkPolicy (cluster .Name + "-head" , cluster .Namespace ).
491
- WithLabels (map [string ]string {"ray.io/cluster-name" : cluster .Name }).
497
+ WithLabels (map [string ]string {RayClusterNameLabel : cluster .Name }).
492
498
WithSpec (networkingv1ac .NetworkPolicySpec ().
493
499
WithPodSelector (metav1ac .LabelSelector ().WithMatchLabels (map [string ]string {"ray.io/cluster" : cluster .Name , "ray.io/node-type" : "head" })).
494
500
WithIngress (
@@ -534,7 +540,7 @@ func desiredHeadNetworkPolicy(cluster *rayv1.RayCluster, cfg *config.KubeRayConf
534
540
),
535
541
).
536
542
WithOwnerReferences (
537
- metav1ac .OwnerReference ().WithUID (cluster .UID ).WithName (cluster .Name ).WithKind (cluster .Kind ).WithAPIVersion (cluster .APIVersion ),
543
+ metav1ac .OwnerReference ().WithUID (cluster .UID ).WithName (cluster .Name ).WithKind (cluster .Kind ).WithAPIVersion (cluster .APIVersion ). WithController ( true ) ,
538
544
)
539
545
}
540
546
@@ -548,8 +554,35 @@ func (r *RayClusterReconciler) SetupWithManager(mgr ctrl.Manager) error {
548
554
return err
549
555
}
550
556
r .CookieSalt = string (b )
551
- return ctrl .NewControllerManagedBy (mgr ).
557
+ // despite ownership, we need to check for labels because we can't use
558
+ controller := ctrl .NewControllerManagedBy (mgr ).
552
559
Named (controllerName ).
553
560
For (& rayv1.RayCluster {}).
554
- Complete (r )
561
+ Owns (& corev1.ServiceAccount {}).
562
+ Owns (& corev1.Service {}).
563
+ Owns (& corev1.Secret {}).
564
+ Owns (& networkingv1.Ingress {}).
565
+ Owns (& networkingv1.NetworkPolicy {}).
566
+ Watches (& rbacv1.ClusterRoleBinding {}, handler .EnqueueRequestsFromMapFunc (
567
+ func (c context.Context , o client.Object ) []reconcile.Request {
568
+ name , ok := o .GetLabels ()[RayClusterNameLabel ]
569
+ if ! ok {
570
+ return []reconcile.Request {}
571
+ }
572
+ namespace , ok := o .GetLabels ()["ray.openshift.ai/cluster-namespace" ]
573
+ if ! ok {
574
+ return []reconcile.Request {}
575
+ }
576
+ return []reconcile.Request {{
577
+ NamespacedName : client.ObjectKey {
578
+ Name : name ,
579
+ Namespace : namespace ,
580
+ }}}
581
+ }),
582
+ )
583
+ if r .IsOpenShift {
584
+ controller .Owns (& routev1.Route {})
585
+ }
586
+
587
+ return controller .Complete (r )
555
588
}
0 commit comments