From d9d13ad65116b0834d791e3323ccd291cd78ff55 Mon Sep 17 00:00:00 2001 From: Maximilian Blatt Date: Mon, 4 Jul 2022 11:34:46 +0200 Subject: [PATCH] feat(eks): Use generic tag initializer for addon Signed-off-by: Maximilian Blatt (external expert on behalf of DB Netz AG) --- apis/eks/v1alpha1/zz_generated.tagged.go | 34 +++++++++++++++++ apis/generate.go | 3 ++ pkg/controller/common/doc.go | 18 +++++++++ pkg/controller/common/tagger.go | 48 ++++++++++++++++++++++++ pkg/controller/eks/addon/setup.go | 31 ++++----------- 5 files changed, 111 insertions(+), 23 deletions(-) create mode 100644 apis/eks/v1alpha1/zz_generated.tagged.go create mode 100644 pkg/controller/common/doc.go create mode 100644 pkg/controller/common/tagger.go diff --git a/apis/eks/v1alpha1/zz_generated.tagged.go b/apis/eks/v1alpha1/zz_generated.tagged.go new file mode 100644 index 0000000000..fcc71b21f5 --- /dev/null +++ b/apis/eks/v1alpha1/zz_generated.tagged.go @@ -0,0 +1,34 @@ +/* +Copyright 2021 The Crossplane Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by provider-aws codegen. DO NOT EDIT. + +package v1alpha1 + +// AddTag adds a tag to this Addon. If it already exists, it will be overwritten. +// It returns true if the tag has been added/changed. Otherwise false. +func (mg *Addon) AddTag(key string, value string) bool { + if mg.Spec.ForProvider.Tags == nil { + mg.Spec.ForProvider.Tags = map[string]*string{key: &value} + return true + } + oldValue, exists := mg.Spec.ForProvider.Tags[key] + if !exists || oldValue == nil || *oldValue != value { + mg.Spec.ForProvider.Tags[key] = &value + return true + } + return false +} diff --git a/apis/generate.go b/apis/generate.go index 630b0340cd..258809c029 100644 --- a/apis/generate.go +++ b/apis/generate.go @@ -29,6 +29,9 @@ limitations under the License. // Generate crossplane-runtime methodsets (resource.Claim, etc) //go:generate go run -tags generate github.com/crossplane/crossplane-tools/cmd/angryjet generate-methodsets --header-file=../hack/boilerplate.go.txt ./... +// Generate tag methods for each managed resource +//go:generate go run -tags generate github.com/crossplane-contrib/provider-aws/cmd/codegen generate-methodsets --header-file=../hack/boilerplate.go.txt ./... + // TODO(muvaf): Remove the last mockgen usage in Addon resource and move to // current convention with tests. //go:generate go run github.com/golang/mock/mockgen --build_flags=--mod=mod -package eksiface -copyright_file ../hack/boilerplate.go.txt -destination ../pkg/clients/eks/fake/eksiface/fake.go github.com/aws/aws-sdk-go/service/eks/eksiface EKSAPI diff --git a/pkg/controller/common/doc.go b/pkg/controller/common/doc.go new file mode 100644 index 0000000000..acdea588a3 --- /dev/null +++ b/pkg/controller/common/doc.go @@ -0,0 +1,18 @@ +/* +Copyright 2021 The Crossplane Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// common contains shared controller logic. +package common diff --git a/pkg/controller/common/tagger.go b/pkg/controller/common/tagger.go new file mode 100644 index 0000000000..eaf5e3fe75 --- /dev/null +++ b/pkg/controller/common/tagger.go @@ -0,0 +1,48 @@ +package common + +import ( + "context" + + "github.com/crossplane/crossplane-runtime/pkg/resource" + "github.com/pkg/errors" + "sigs.k8s.io/controller-runtime/pkg/client" + + "github.com/crossplane-contrib/provider-aws/apis" +) + +const ( + errNotTagged = "Resource does not implement the Tagged interface" + errUpdateTags = "Failed to update tags for Tagged resource" +) + +// Tagger is a controller initializer that adds all default tags to a managed +// resource if it implementes the Tagged interface. +type Tagger struct { + kube client.Client +} + +// NewTagger creates a new Tagger instance. +func NewTagger(kube client.Client, _ apis.Tagged) *Tagger { + return &Tagger{ + kube: kube, + } +} + +// Initialize adds the default tags to the given managed resource if it +// implements the Tagged interface. +func (t *Tagger) Initialize(ctx context.Context, mg resource.Managed) error { + tagged, ok := mg.(apis.Tagged) + if !ok { + return errors.New(errNotTagged) + } + shouldUpdate := false + for k, v := range resource.GetExternalTags(mg) { + if added := tagged.AddTag(k, v); added { + shouldUpdate = true + } + } + if shouldUpdate { + return errors.Wrap(t.kube.Update(ctx, mg), errUpdateTags) + } + return nil +} diff --git a/pkg/controller/eks/addon/setup.go b/pkg/controller/eks/addon/setup.go index a0a13ee725..3c3c125255 100644 --- a/pkg/controller/eks/addon/setup.go +++ b/pkg/controller/eks/addon/setup.go @@ -36,14 +36,14 @@ import ( eksv1alpha1 "github.com/crossplane-contrib/provider-aws/apis/eks/v1alpha1" "github.com/crossplane-contrib/provider-aws/apis/v1alpha1" awsclients "github.com/crossplane-contrib/provider-aws/pkg/clients" + "github.com/crossplane-contrib/provider-aws/pkg/controller/common" "github.com/crossplane-contrib/provider-aws/pkg/features" ) const ( - errNotEKSCluster = "managed resource is not an EKS cluster custom resource" - errKubeUpdateFailed = "cannot update EKS cluster custom resource" - errTagResource = "cannot tag resource" - errUntagResource = "cannot untag resource" + errNotEKSCluster = "managed resource is not an EKS cluster custom resource" + errTagResource = "cannot tag resource" + errUntagResource = "cannot untag resource" ) // SetupAddon adds a controller that reconciles Clusters. @@ -65,7 +65,10 @@ func SetupAddon(mgr ctrl.Manager, o controller.Options) error { Complete(managed.NewReconciler(mgr, resource.ManagedKind(eksv1alpha1.AddonGroupVersionKind), managed.WithExternalConnecter(&connector{kube: mgr.GetClient(), opts: opts}), - managed.WithInitializers(managed.NewDefaultProviderConfig(mgr.GetClient()), &tagger{kube: mgr.GetClient()}), + managed.WithInitializers( + managed.NewDefaultProviderConfig(mgr.GetClient()), + common.NewTagger(mgr.GetClient(), &eksv1alpha1.Addon{}), + ), managed.WithReferenceResolver(managed.NewAPISimpleReferenceResolver(mgr.GetClient())), managed.WithPollInterval(o.PollInterval), managed.WithLogger(o.Logger.WithValues("controller", name)), @@ -199,21 +202,3 @@ func preDelete(_ context.Context, cr *eksv1alpha1.Addon, obj *awseks.DeleteAddon obj.ClusterName = cr.Spec.ForProvider.ClusterName return false, nil } - -type tagger struct { - kube client.Client -} - -func (t *tagger) Initialize(ctx context.Context, mg resource.Managed) error { - cr, ok := mg.(*eksv1alpha1.Addon) - if !ok { - return errors.New(errNotEKSCluster) - } - if cr.Spec.ForProvider.Tags == nil { - cr.Spec.ForProvider.Tags = map[string]*string{} - } - for k, v := range resource.GetExternalTags(mg) { - cr.Spec.ForProvider.Tags[k] = awsclients.String(v) - } - return errors.Wrap(t.kube.Update(ctx, cr), errKubeUpdateFailed) -}