From 72380e2abad39011835bc6098575569cfaf84e4c Mon Sep 17 00:00:00 2001 From: Dario Tranchitella Date: Wed, 5 Aug 2020 11:54:46 +0200 Subject: [PATCH] Syncing Namespace annotations for Storage and Ingress classes (#30) --- api/v1alpha1/tenant_annotations.go | 9 +++++- controllers/tenant_controller.go | 48 ++++++++++++++++++++++++++++++ go.mod | 1 + go.sum | 4 +++ 4 files changed, 61 insertions(+), 1 deletion(-) diff --git a/api/v1alpha1/tenant_annotations.go b/api/v1alpha1/tenant_annotations.go index 100d4ebc..31e76956 100644 --- a/api/v1alpha1/tenant_annotations.go +++ b/api/v1alpha1/tenant_annotations.go @@ -16,7 +16,14 @@ limitations under the License. package v1alpha1 -import corev1 "k8s.io/api/core/v1" +import ( + corev1 "k8s.io/api/core/v1" +) + +const ( + AvailableIngressClassesAnnotation = "capsule.clastix.io/ingress-classes" + AvailableStorageClassesAnnotation = "capsule.clastix.io/storage-classes" +) func UsedQuotaFor(resource corev1.ResourceName) string { return "quota.capsule.clastix.io/used-" + resource.String() diff --git a/controllers/tenant_controller.go b/controllers/tenant_controller.go index 9e60c1c4..cf6a2465 100644 --- a/controllers/tenant_controller.go +++ b/controllers/tenant_controller.go @@ -24,6 +24,7 @@ import ( "sync" "github.com/go-logr/logr" + "github.com/hashicorp/go-multierror" corev1 "k8s.io/api/core/v1" networkingv1 "k8s.io/api/networking/v1" rbacv1 "k8s.io/api/rbac/v1" @@ -53,6 +54,7 @@ type TenantReconciler struct { func (r *TenantReconciler) SetupWithManager(mgr ctrl.Manager) error { return ctrl.NewControllerManagedBy(mgr). For(&capsulev1alpha1.Tenant{}). + Owns(&corev1.Namespace{}). Owns(&networkingv1.NetworkPolicy{}). Owns(&corev1.LimitRange{}). Owns(&corev1.ResourceQuota{}). @@ -75,6 +77,12 @@ func (r TenantReconciler) Reconcile(request ctrl.Request) (ctrl.Result, error) { return reconcile.Result{}, err } + r.Log.Info("Starting processing of Namespaces", "items", instance.Status.Namespaces.Len()) + if err := r.syncNamespaces(instance); err != nil { + r.Log.Error(err, "Cannot sync Namespace items") + return reconcile.Result{}, err + } + r.Log.Info("Starting processing of Network Policies", "items", len(instance.Spec.NetworkPolicies)) if err := r.syncNetworkPolicies(instance); err != nil { r.Log.Error(err, "Cannot sync NetworkPolicy items") @@ -358,6 +366,46 @@ func (r *TenantReconciler) syncLimitRanges(tenant *capsulev1alpha1.Tenant) error return nil } +func (r *TenantReconciler) syncNamespace(namespace string, ingressClasses []string, storageClasses []string, wg *sync.WaitGroup, channel chan error) { + defer wg.Done() + + t := &corev1.Namespace{} + if err := r.Client.Get(context.TODO(), types.NamespacedName{Name: namespace}, t); err != nil { + channel <- err + } + + channel <- retry.RetryOnConflict(retry.DefaultBackoff, func() error { + if t.Annotations == nil { + t.Annotations = make(map[string]string) + } + t.Annotations[capsulev1alpha1.AvailableIngressClassesAnnotation] = strings.Join(ingressClasses, ",") + t.Annotations[capsulev1alpha1.AvailableStorageClassesAnnotation] = strings.Join(storageClasses, ",") + return r.Client.Update(context.TODO(), t, &client.UpdateOptions{}) + }) +} + +// Ensuring all annotations are applied to each Namespace handled by the Tenant. +func (r *TenantReconciler) syncNamespaces(tenant *capsulev1alpha1.Tenant) (err error) { + ch := make(chan error, tenant.Status.Namespaces.Len()) + + wg := &sync.WaitGroup{} + wg.Add(tenant.Status.Namespaces.Len()) + + for _, ns := range tenant.Status.Namespaces { + go r.syncNamespace(ns, tenant.Spec.IngressClasses, tenant.Spec.StorageClasses, wg, ch) + } + + wg.Wait() + close(ch) + + for e := range ch { + if e != nil { + err = multierror.Append(e, err) + } + } + return +} + // Ensuring all the NetworkPolicies are applied to each Namespace handled by the Tenant. func (r *TenantReconciler) syncNetworkPolicies(tenant *capsulev1alpha1.Tenant) error { // getting requested NetworkPolicy keys diff --git a/go.mod b/go.mod index 0104678c..b89eaf09 100644 --- a/go.mod +++ b/go.mod @@ -4,6 +4,7 @@ go 1.13 require ( github.com/go-logr/logr v0.1.0 + github.com/hashicorp/go-multierror v1.1.0 github.com/onsi/ginkgo v1.11.0 github.com/onsi/gomega v1.8.1 github.com/stretchr/testify v1.4.0 diff --git a/go.sum b/go.sum index 89e74abf..559c071c 100644 --- a/go.sum +++ b/go.sum @@ -159,6 +159,10 @@ github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:Fecb github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= +github.com/hashicorp/errwrap v1.0.0 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/UYA= +github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= +github.com/hashicorp/go-multierror v1.1.0 h1:B9UzwGQJehnUY1yNrnwREHc3fGbC2xefo8g4TbElacI= +github.com/hashicorp/go-multierror v1.1.0/go.mod h1:spPvp8C1qA32ftKqdAHm4hHTbPw+vmowP0z+KUhOZdA= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1 h1:0hERBMJE1eitiLkihrMvRVBYAkpHzc/J3QdDN+dAcgU= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=