diff --git a/controllers/core/resourceset_controller.go b/controllers/core/resourceset_controller.go index 32d65e0..acfd425 100644 --- a/controllers/core/resourceset_controller.go +++ b/controllers/core/resourceset_controller.go @@ -211,7 +211,7 @@ func (r *ResourceSetReconciler) updateStatus(ctx reconcile.Context, resourceSet rs.Status.ObservedGeneration = rs.GetGeneration() rs.Status.ResourceVersion = rs.GetResourceVersion() - if util.AsSha256(resourceSet.Status) != util.AsSha256(rs.Status) { + if eq, err := util.Sha256Equal(resourceSet.Status, rs.Status); err != nil || !eq { ctx.Log.V(1).Info("updating ResourceSet status") if err := r.Status().Update(ctx.Context, &rs); err != nil { ctx.Log.Error(err, "failed to update ResourceSet status") diff --git a/controllers/core/tenant_controller.go b/controllers/core/tenant_controller.go index 4d8dae3..5c957de 100644 --- a/controllers/core/tenant_controller.go +++ b/controllers/core/tenant_controller.go @@ -28,8 +28,13 @@ import ( "k8s.io/apimachinery/pkg/types" "k8s.io/client-go/tools/record" ctrl "sigs.k8s.io/controller-runtime" + "sigs.k8s.io/controller-runtime/pkg/builder" "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/handler" "sigs.k8s.io/controller-runtime/pkg/log" + "sigs.k8s.io/controller-runtime/pkg/predicate" + kreconcile "sigs.k8s.io/controller-runtime/pkg/reconcile" // Required for Watching + "sigs.k8s.io/controller-runtime/pkg/source" corev1alpha1 "github.com/kristofferahl/aeto/apis/core/v1alpha1" "github.com/kristofferahl/aeto/internal/pkg/config" @@ -446,5 +451,33 @@ func (r *TenantReconciler) updateStatus(ctx reconcile.Context, tenant corev1alph func (r *TenantReconciler) SetupWithManager(mgr ctrl.Manager) error { return ctrl.NewControllerManagedBy(mgr). For(&corev1alpha1.Tenant{}). + Watches( + &source.Kind{Type: &corev1alpha1.ResourceSet{}}, + handler.EnqueueRequestsFromMapFunc(r.findTenantForResourceSet), + builder.WithPredicates(predicate.ResourceVersionChangedPredicate{}), + ). Complete(r) } + +func (r *TenantReconciler) findTenantForResourceSet(resourceSet client.Object) []kreconcile.Request { + tenantList := &corev1alpha1.TenantList{} + // TODO: Implement paging + // TODO: Allow operator to define namespaces to watch for tenants + options := &client.ListOptions{} // Fetch from all namespaces + err := r.List(context.TODO(), tenantList, options) + if err != nil { + return []kreconcile.Request{} + } + + requests := make([]kreconcile.Request, 0) + for _, item := range tenantList.Items { + requests = append(requests, kreconcile.Request{ + NamespacedName: types.NamespacedName{ + Name: item.GetName(), + Namespace: item.GetNamespace(), + }, + }) + + } + return requests +} diff --git a/internal/pkg/util/sha256.go b/internal/pkg/util/sha256.go index dbe8111..65615b8 100644 --- a/internal/pkg/util/sha256.go +++ b/internal/pkg/util/sha256.go @@ -2,11 +2,27 @@ package util import ( "crypto/sha256" + "encoding/json" "fmt" ) -func AsSha256(o interface{}) string { - h := sha256.New() - h.Write([]byte(fmt.Sprintf("%v", o))) - return fmt.Sprintf("%x", h.Sum(nil)) +func AsSha256(o interface{}) (string, error) { + b, err := json.Marshal(o) + if err != nil { + return "", err + } + sum := sha256.Sum256(b) + return fmt.Sprintf("%x", sum), nil +} + +func Sha256Equal(a, b interface{}) (bool, error) { + aSum, err := AsSha256(a) + if err != nil { + return false, err + } + bSum, err := AsSha256(b) + if err != nil { + return false, err + } + return aSum == bSum, nil }