From aaac5efc37004418cd008f897ad3a68b97f2d32c Mon Sep 17 00:00:00 2001 From: Reed Schalo Date: Tue, 24 Sep 2024 23:41:12 -0700 Subject: [PATCH] chore: add e2es and drop annotation on conversion --- .../karpenter/templates/clusterrole-core.yaml | 4 ++ go.mod | 2 +- go.sum | 4 +- pkg/apis/v1/ec2nodeclass_conversion.go | 3 +- pkg/apis/v1/ec2nodeclass_conversion_test.go | 14 +++++ pkg/controllers/controllers.go | 2 + test/suites/integration/migration_test.go | 57 +++++++++++++++++++ 7 files changed, 82 insertions(+), 4 deletions(-) create mode 100644 test/suites/integration/migration_test.go diff --git a/charts/karpenter/templates/clusterrole-core.yaml b/charts/karpenter/templates/clusterrole-core.yaml index d46de7d7036a..5fe85325ce85 100644 --- a/charts/karpenter/templates/clusterrole-core.yaml +++ b/charts/karpenter/templates/clusterrole-core.yaml @@ -68,6 +68,10 @@ rules: - apiGroups: [""] resources: ["pods"] verbs: ["delete"] + - apiGroups: ["apiextensions.k8s.io"] + resources: ["customresourcedefinitions/status"] + resourceNames: ["ec2nodeclass.karpenter.k8s.aws", "nodepools.karpenter.sh", "nodeclaims.karpenter.sh"] + verbs: ["patch"] {{- if .Values.webhook.enabled }} - apiGroups: ["apiextensions.k8s.io"] resources: ["customresourcedefinitions"] diff --git a/go.mod b/go.mod index 112c40d1d845..48003f7fd391 100644 --- a/go.mod +++ b/go.mod @@ -32,7 +32,7 @@ require ( k8s.io/utils v0.0.0-20240102154912-e7106e64919e knative.dev/pkg v0.0.0-20231010144348-ca8c009405dd sigs.k8s.io/controller-runtime v0.18.4 - sigs.k8s.io/karpenter v1.0.2-0.20240923155000-ca71181901ff + sigs.k8s.io/karpenter v1.0.2-0.20240925000600-11b890128ea3 sigs.k8s.io/yaml v1.4.0 ) diff --git a/go.sum b/go.sum index 216ef6dff53f..f02895d5ae33 100644 --- a/go.sum +++ b/go.sum @@ -761,8 +761,8 @@ sigs.k8s.io/controller-runtime v0.18.4 h1:87+guW1zhvuPLh1PHybKdYFLU0YJp4FhJRmiHv sigs.k8s.io/controller-runtime v0.18.4/go.mod h1:TVoGrfdpbA9VRFaRnKgk9P5/atA0pMwq+f+msb9M8Sg= sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd h1:EDPBXCAspyGV4jQlpZSudPeMmr1bNJefnuqLsRAsHZo= sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0= -sigs.k8s.io/karpenter v1.0.2-0.20240923155000-ca71181901ff h1:IJmq70mAKmjmR24i1bZyTlIYHOAo9Mf3ldn6NdoeFjI= -sigs.k8s.io/karpenter v1.0.2-0.20240923155000-ca71181901ff/go.mod h1:3NLmsnHHw8p4VutpjTOPUZyhE3qH6yGTs8O94Lsu8uw= +sigs.k8s.io/karpenter v1.0.2-0.20240925000600-11b890128ea3 h1:1ss4TsmuZbHs9mlaVoWCK4E/4Qw+ZTJOtQeaGx9Xwb0= +sigs.k8s.io/karpenter v1.0.2-0.20240925000600-11b890128ea3/go.mod h1:3NLmsnHHw8p4VutpjTOPUZyhE3qH6yGTs8O94Lsu8uw= sigs.k8s.io/structured-merge-diff/v4 v4.4.1 h1:150L+0vs/8DA78h1u02ooW1/fFq/Lwr+sGiqlzvrtq4= sigs.k8s.io/structured-merge-diff/v4 v4.4.1/go.mod h1:N8hJocpFajUSSeSJ9bOZ77VzejKZaXsTtZo4/u7Io08= sigs.k8s.io/yaml v1.4.0 h1:Mk1wCc2gy/F0THH0TAp1QYyJNzRm2KCLy3o5ASXVI5E= diff --git a/pkg/apis/v1/ec2nodeclass_conversion.go b/pkg/apis/v1/ec2nodeclass_conversion.go index 86ccdf5e6a20..38cf590c8b4f 100644 --- a/pkg/apis/v1/ec2nodeclass_conversion.go +++ b/pkg/apis/v1/ec2nodeclass_conversion.go @@ -22,6 +22,7 @@ import ( "github.com/samber/lo" "k8s.io/apimachinery/pkg/api/resource" "knative.dev/pkg/apis" + karpv1 "sigs.k8s.io/karpenter/pkg/apis/v1" "github.com/aws/aws-sdk-go/service/ec2" @@ -31,7 +32,7 @@ import ( func (in *EC2NodeClass) ConvertTo(ctx context.Context, to apis.Convertible) error { v1beta1enc := to.(*v1beta1.EC2NodeClass) v1beta1enc.ObjectMeta = in.ObjectMeta - v1beta1enc.Annotations = lo.OmitByKeys(v1beta1enc.Annotations, []string{AnnotationUbuntuCompatibilityKey}) + v1beta1enc.Annotations = lo.OmitByKeys(v1beta1enc.Annotations, []string{AnnotationUbuntuCompatibilityKey, karpv1.StoredVersionMigratedKey}) if value, ok := in.Annotations[AnnotationUbuntuCompatibilityKey]; ok { compatSpecifiers := strings.Split(value, ",") diff --git a/pkg/apis/v1/ec2nodeclass_conversion_test.go b/pkg/apis/v1/ec2nodeclass_conversion_test.go index a598e72f030b..9a2479b3c70d 100644 --- a/pkg/apis/v1/ec2nodeclass_conversion_test.go +++ b/pkg/apis/v1/ec2nodeclass_conversion_test.go @@ -22,6 +22,7 @@ import ( . "github.com/onsi/gomega" "github.com/samber/lo" "k8s.io/apimachinery/pkg/api/resource" + karpv1 "sigs.k8s.io/karpenter/pkg/apis/v1" "sigs.k8s.io/karpenter/pkg/test" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -50,6 +51,19 @@ var _ = Describe("Convert v1 to v1beta1 EC2NodeClass API", func() { Expect(v1ec2nodeclass.ConvertTo(ctx, v1beta1ec2nodeclass)).To(Succeed()) Expect(v1beta1ec2nodeclass.ObjectMeta).To(BeEquivalentTo(v1ec2nodeclass.ObjectMeta)) }) + It("should drop v1 specific annotations on conversion", func() { + v1ec2nodeclass.ObjectMeta = test.ObjectMeta( + metav1.ObjectMeta{ + Annotations: map[string]string{ + karpv1.StoredVersionMigratedKey: "true", + }, + }, + ) + v1nc := v1ec2nodeclass.DeepCopy() + Expect(v1ec2nodeclass.ConvertTo(ctx, v1beta1ec2nodeclass)).To(Succeed()) + Expect(v1nc.Annotations).To(HaveKey(karpv1.StoredVersionMigratedKey)) + Expect(v1beta1ec2nodeclass.Annotations).NotTo(HaveKey(karpv1.StoredVersionMigratedKey)) + }) Context("EC2NodeClass Spec", func() { It("should convert v1 ec2nodeclass subnet selector terms", func() { v1ec2nodeclass.Spec.SubnetSelectorTerms = []SubnetSelectorTerm{ diff --git a/pkg/controllers/controllers.go b/pkg/controllers/controllers.go index c45f00938299..1f6411bea07a 100644 --- a/pkg/controllers/controllers.go +++ b/pkg/controllers/controllers.go @@ -21,6 +21,7 @@ import ( "github.com/awslabs/operatorpkg/status" "sigs.k8s.io/controller-runtime/pkg/manager" "sigs.k8s.io/karpenter/pkg/cloudprovider" + migration "sigs.k8s.io/karpenter/pkg/controllers/migration/resource" v1 "github.com/aws/karpenter-provider-aws/pkg/apis/v1" nodeclasshash "github.com/aws/karpenter-provider-aws/pkg/controllers/nodeclass/hash" @@ -67,6 +68,7 @@ func NewControllers(ctx context.Context, mgr manager.Manager, sess *session.Sess controllerspricing.NewController(pricingProvider), controllersinstancetype.NewController(instanceTypeProvider), status.NewController[*v1.EC2NodeClass](kubeClient, mgr.GetEventRecorderFor("karpenter")), + migration.NewController[*v1.EC2NodeClass](kubeClient), } if options.FromContext(ctx).InterruptionQueue != "" { sqsapi := servicesqs.New(sess) diff --git a/test/suites/integration/migration_test.go b/test/suites/integration/migration_test.go new file mode 100644 index 000000000000..a53097f5e6eb --- /dev/null +++ b/test/suites/integration/migration_test.go @@ -0,0 +1,57 @@ +/* +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. +*/ + +package integration_test + +import ( + "time" + + "github.com/aws/karpenter-provider-aws/pkg/apis" + v1 "github.com/aws/karpenter-provider-aws/pkg/apis/v1" + "github.com/aws/karpenter-provider-aws/pkg/test" + "github.com/awslabs/operatorpkg/object" + "github.com/samber/lo" + apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + + "sigs.k8s.io/controller-runtime/pkg/client" + karpv1 "sigs.k8s.io/karpenter/pkg/apis/v1" +) + +var _ = FDescribe("EC2NodeClass Migration Controller", func() { + var nodeClass *v1.EC2NodeClass + var nodePool *karpv1.NodePool + BeforeEach(func() { + nodeClass = test.EC2NodeClass() + nodePool = &karpv1.NodePool{} + }) + It("should have migration key on for v1 resources", func() { + env.ExpectCreated(nodeClass, nodePool) + Expect(nodeClass.Annotations).To(HaveKey(karpv1.StoredVersionMigratedKey)) + Expect(nodePool.Annotations).To(HaveKey(karpv1.StoredVersionMigratedKey)) + }) + It("should update CRD status", func() { + v1beta1NodeClass := test.BetaEC2NodeClass() + env.ExpectCreated(v1beta1NodeClass) + nodeClassCrd, _ := lo.Find(apis.CRDs, func(crd *apiextensionsv1.CustomResourceDefinition) bool { + return crd.Name == object.GVK(nodeClass).Kind + }) + crd := &apiextensionsv1.CustomResourceDefinition{} + Eventually(func(g Gomega) { + g.Expect(env.Client.Get(env.Context, client.ObjectKeyFromObject(nodeClassCrd), crd)).To(Succeed()) + }).WithTimeout(time.Second * 10).Should(Succeed()) + }) +})