Skip to content

Commit 7a7ae40

Browse files
authored
Merge pull request #338 from kagenti/fix/sandbox-client-registration
fix: watch Sandbox resources in ClientRegistration controller
2 parents 469cf71 + 1e9b1ba commit 7a7ae40

1 file changed

Lines changed: 69 additions & 12 deletions

File tree

kagenti-operator/internal/controller/clientregistration_controller.go

Lines changed: 69 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -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.
447493
func (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

Comments
 (0)