diff --git a/go.mod b/go.mod index 6b3f91d05cae..5ea011a52721 100644 --- a/go.mod +++ b/go.mod @@ -30,7 +30,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.2 - sigs.k8s.io/karpenter v0.37.4-0.20240917214243-cb36671f459f + sigs.k8s.io/karpenter v0.37.4-0.20240925000401-46bab1b6a31f sigs.k8s.io/yaml v1.4.0 ) diff --git a/go.sum b/go.sum index 9db49fdf4b55..09b1b8b7bd5e 100644 --- a/go.sum +++ b/go.sum @@ -761,8 +761,8 @@ sigs.k8s.io/controller-runtime v0.18.2 h1:RqVW6Kpeaji67CY5nPEfRz6ZfFMk0lWQlNrLql sigs.k8s.io/controller-runtime v0.18.2/go.mod h1:tuAt1+wbVsXIT8lPtk5RURxqAnq7xkpv2Mhttslg7Hw= 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 v0.37.4-0.20240917214243-cb36671f459f h1:ul1EBIuHhZ/59h7npqhFwgzXKTCBZNFU5OETC0ZJkag= -sigs.k8s.io/karpenter v0.37.4-0.20240917214243-cb36671f459f/go.mod h1:XvblVAMUcv1Ja8eYC6dg4Wmx3Kwxhp58//YlPhVZQTk= +sigs.k8s.io/karpenter v0.37.4-0.20240925000401-46bab1b6a31f h1:91COL6TbmEmYPQTv7C4OdjnuuZAwPAWD7tTfAIBFd70= +sigs.k8s.io/karpenter v0.37.4-0.20240925000401-46bab1b6a31f/go.mod h1:XvblVAMUcv1Ja8eYC6dg4Wmx3Kwxhp58//YlPhVZQTk= 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/test/suites/integration/migration_test.go b/test/suites/integration/migration_test.go new file mode 100644 index 000000000000..743487dcc790 --- /dev/null +++ b/test/suites/integration/migration_test.go @@ -0,0 +1,82 @@ +/* +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 ( + "github.com/samber/lo" + + v1 "github.com/aws/karpenter-provider-aws/pkg/apis/v1" + "github.com/aws/karpenter-provider-aws/pkg/apis/v1beta1" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + + "sigs.k8s.io/controller-runtime/pkg/client" + karpv1 "sigs.k8s.io/karpenter/pkg/apis/v1" + karpv1beta1 "sigs.k8s.io/karpenter/pkg/apis/v1beta1" + coretest "sigs.k8s.io/karpenter/pkg/test" +) + +var _ = Describe("Migration", func() { + BeforeEach(func() { + nodeClass = env.DefaultEC2NodeClass() + nodePool = env.DefaultNodePool(nodeClass) + }) + It("should not have migration key present for v1beta1 resources", func() { + pod := coretest.Pod() + env.ExpectCreated(pod, nodeClass, nodePool) + env.EventuallyExpectHealthy(pod) + nodeClaim := env.EventuallyExpectNodeClaimCount("==", 1)[0] + Eventually(func(g Gomega) { + stored := nodeClass.DeepCopy() + nodeClass.Annotations = lo.Assign(nodeClass.Annotations, map[string]string{ + karpv1.StoredVersionMigratedKey: "true", + }) + g.Expect(env.Client.Patch(env.Context, nodeClass, client.StrategicMergeFrom(stored, client.MergeFromWithOptimisticLock{}))).To(Succeed()) + ec2nc := &v1beta1.EC2NodeClass{} + g.Expect(env.Client.Get(env.Context, client.ObjectKeyFromObject(nodeClass), ec2nc)).To(Succeed()) + v1ec2nc := &v1.EC2NodeClass{} + g.Expect(env.Client.Get(env.Context, client.ObjectKeyFromObject(nodeClass), v1ec2nc)).To(Succeed()) + g.Expect(v1ec2nc.GetAnnotations()).To(HaveKey(karpv1.StoredVersionMigratedKey)) + g.Expect(ec2nc.GetAnnotations()).To(Not(HaveKey(karpv1.StoredVersionMigratedKey))) + }) + Eventually(func(g Gomega) { + stored := nodePool.DeepCopy() + nodePool.Annotations = lo.Assign(nodePool.Annotations, map[string]string{ + karpv1.StoredVersionMigratedKey: "true", + }) + g.Expect(env.Client.Patch(env.Context, nodePool, client.StrategicMergeFrom(stored, client.MergeFromWithOptimisticLock{}))).To(Succeed()) + np := &karpv1beta1.NodePool{} + g.Expect(env.Client.Get(env.Context, client.ObjectKeyFromObject(nodePool), np)).To(Succeed()) + v1np := &karpv1.NodePool{} + g.Expect(env.Client.Get(env.Context, client.ObjectKeyFromObject(nodePool), v1np)).To(Succeed()) + g.Expect(v1np.GetAnnotations()).To(HaveKey(karpv1.StoredVersionMigratedKey)) + g.Expect(np.GetAnnotations()).To(Not(HaveKey(karpv1.StoredVersionMigratedKey))) + }) + Eventually(func(g Gomega) { + stored := nodeClaim.DeepCopy() + nodeClaim.Annotations = lo.Assign(nodeClaim.Annotations, map[string]string{ + karpv1.StoredVersionMigratedKey: "true", + }) + g.Expect(env.Client.Patch(env.Context, nodeClaim, client.StrategicMergeFrom(stored, client.MergeFromWithOptimisticLock{}))).To(Succeed()) + nc := &karpv1beta1.NodeClaim{} + g.Expect(env.Client.Get(env.Context, client.ObjectKeyFromObject(nodeClaim), nc)).To(Succeed()) + v1nc := &karpv1.NodeClaim{} + g.Expect(env.Client.Get(env.Context, client.ObjectKeyFromObject(nodeClaim), v1nc)).To(Succeed()) + g.Expect(v1nc.GetAnnotations()).To(HaveKey(karpv1.StoredVersionMigratedKey)) + g.Expect(nc.GetAnnotations()).To(Not(HaveKey(karpv1.StoredVersionMigratedKey))) + }) + }) +})