@@ -19,6 +19,7 @@ import (
1919 corev1 "k8s.io/api/core/v1"
2020 apierrors "k8s.io/apimachinery/pkg/api/errors"
2121 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
22+ "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
2223 "k8s.io/apimachinery/pkg/runtime"
2324 "k8s.io/apimachinery/pkg/types"
2425 "k8s.io/client-go/util/retry"
@@ -80,6 +81,7 @@ func (r *ClientRegistrationReconciler) uncachedReader() client.Reader {
8081
8182// +kubebuilder:rbac:groups=apps,resources=deployments,verbs=get;list;watch;update;patch
8283// +kubebuilder:rbac:groups=apps,resources=statefulsets,verbs=get;list;watch;update;patch
84+ // +kubebuilder:rbac:groups=agents.x-k8s.io,resources=sandboxes,verbs=get;list;watch;update;patch
8385// +kubebuilder:rbac:groups=core,resources=secrets,verbs=get;list;watch;create;update;patch
8486// +kubebuilder:rbac:groups=core,resources=configmaps,verbs=get;list;watch
8587
@@ -97,7 +99,8 @@ func (r *ClientRegistrationReconciler) Reconcile(ctx context.Context, req ctrl.R
9799 }
98100
99101 dep := & appsv1.Deployment {}
100- if err := r .Get (ctx , req .NamespacedName , dep ); err == nil {
102+ err = r .Get (ctx , req .NamespacedName , dep )
103+ if err == nil {
101104 return r .reconcileOne (ctx , dep , injectTools , dep .Name , & dep .Spec .Template ,
102105 func (ctx context.Context ) error {
103106 return retry .RetryOnConflict (retry .DefaultRetry , func () error {
@@ -111,29 +114,66 @@ func (r *ClientRegistrationReconciler) Reconcile(ctx context.Context, req ctrl.R
111114 return r .Update (ctx , d )
112115 })
113116 })
114- }
115- if ! apierrors .IsNotFound (err ) {
117+ } else if ! apierrors .IsNotFound (err ) {
116118 return ctrl.Result {}, err
117119 }
118120
119121 sts := & appsv1.StatefulSet {}
120- if err := r .Get (ctx , req .NamespacedName , sts ); err != nil {
122+ err = r .Get (ctx , req .NamespacedName , sts )
123+ if err == nil {
124+ return r .reconcileOne (ctx , sts , injectTools , sts .Name , & sts .Spec .Template ,
125+ func (ctx context.Context ) error {
126+ return retry .RetryOnConflict (retry .DefaultRetry , func () error {
127+ s := & appsv1.StatefulSet {}
128+ if err := r .Get (ctx , req .NamespacedName , s ); err != nil {
129+ return err
130+ }
131+ if ! injectKeycloakClientCredentialsAnnotation (& s .Spec .Template , keycloakClientCredentialsSecretName (s .Namespace , s .Name )) {
132+ return nil
133+ }
134+ return r .Update (ctx , s )
135+ })
136+ })
137+ } else if ! apierrors .IsNotFound (err ) {
138+ return ctrl.Result {}, err
139+ }
140+
141+ sbx := & unstructured.Unstructured {}
142+ sbx .SetGroupVersionKind (sandboxGVK )
143+ if err = r .Get (ctx , req .NamespacedName , sbx ); err != nil {
121144 if apierrors .IsNotFound (err ) {
122145 return ctrl.Result {}, nil
123146 }
124147 return ctrl.Result {}, err
125148 }
126- return r .reconcileOne (ctx , sts , injectTools , sts .Name , & sts .Spec .Template ,
149+ podLabels , _ , _ := unstructured .NestedStringMap (sbx .Object , "spec" , "podTemplate" , "metadata" , "labels" )
150+ podAnnotations , _ , _ := unstructured .NestedStringMap (sbx .Object , "spec" , "podTemplate" , "metadata" , "annotations" )
151+ saName , _ , _ := unstructured .NestedString (sbx .Object , "spec" , "podTemplate" , "spec" , "serviceAccountName" )
152+ syntheticTemplate := & corev1.PodTemplateSpec {
153+ ObjectMeta : metav1.ObjectMeta {Labels : podLabels , Annotations : podAnnotations },
154+ Spec : corev1.PodSpec {ServiceAccountName : saName },
155+ }
156+ return r .reconcileOne (ctx , sbx , injectTools , sbx .GetName (), syntheticTemplate ,
127157 func (ctx context.Context ) error {
128158 return retry .RetryOnConflict (retry .DefaultRetry , func () error {
129- s := & appsv1.StatefulSet {}
130- if err := r .Get (ctx , req .NamespacedName , s ); err != nil {
159+ fresh := & unstructured.Unstructured {}
160+ fresh .SetGroupVersionKind (sandboxGVK )
161+ if err := r .Get (ctx , req .NamespacedName , fresh ); err != nil {
131162 return err
132163 }
133- if ! injectKeycloakClientCredentialsAnnotation (& s .Spec .Template , keycloakClientCredentialsSecretName (s .Namespace , s .Name )) {
164+ secretName := keycloakClientCredentialsSecretName (fresh .GetNamespace (), fresh .GetName ())
165+ annotations , _ , _ := unstructured .NestedStringMap (fresh .Object , "spec" , "podTemplate" , "metadata" , "annotations" )
166+ if annotations != nil && annotations [AnnotationKeycloakClientSecretName ] == secretName {
134167 return nil
135168 }
136- return r .Update (ctx , s )
169+ if annotations == nil {
170+ annotations = map [string ]string {}
171+ }
172+ annotations [AnnotationKeycloakClientSecretName ] = secretName
173+ if err := unstructured .SetNestedStringMap (fresh .Object , annotations , "spec" , "podTemplate" , "metadata" , "annotations" ); err != nil {
174+ return fmt .Errorf ("setting podTemplate annotations: %w" , err )
175+ }
176+ return r .Update (ctx , fresh )
137177 })
138178 })
139179}
@@ -437,6 +477,12 @@ func clientRegistrationWorkloadPredicate(obj client.Object) bool {
437477 return workloadWantsOperatorClientReg (o .Spec .Template .Labels , true )
438478 case * appsv1.StatefulSet :
439479 return workloadWantsOperatorClientReg (o .Spec .Template .Labels , true )
480+ case * unstructured.Unstructured :
481+ if o .GroupVersionKind () != sandboxGVK {
482+ return false
483+ }
484+ labels , _ , _ := unstructured .NestedStringMap (o .Object , "spec" , "podTemplate" , "metadata" , "labels" )
485+ return workloadWantsOperatorClientReg (labels , true )
440486 default :
441487 return false
442488 }
@@ -446,13 +492,24 @@ func clientRegistrationWorkloadPredicate(obj client.Object) bool {
446492// feature gates; the predicate uses injectTools=true so tool workloads are not dropped before gates load.
447493func (r * ClientRegistrationReconciler ) SetupWithManager (mgr ctrl.Manager ) error {
448494 pred := predicate .NewPredicateFuncs (clientRegistrationWorkloadPredicate )
449- return ctrl .NewControllerManagedBy (mgr ).
495+ b := ctrl .NewControllerManagedBy (mgr ).
450496 Named ("clientregistration" ).
451497 For (& appsv1.Deployment {}, builder .WithPredicates (pred )).
452498 Watches (
453499 & appsv1.StatefulSet {},
454500 & handler.EnqueueRequestForObject {},
455501 builder .WithPredicates (pred ),
456- ).
457- Complete (r )
502+ )
503+
504+ if SandboxCRDExists (mgr .GetConfig ()) {
505+ sandboxObj := & unstructured.Unstructured {}
506+ sandboxObj .SetGroupVersionKind (sandboxGVK )
507+ b = b .Watches (
508+ sandboxObj ,
509+ & handler.EnqueueRequestForObject {},
510+ builder .WithPredicates (pred ),
511+ )
512+ }
513+
514+ return b .Complete (r )
458515}
0 commit comments