diff --git a/go.mod b/go.mod index 7e870bfd6994..66c6b3201113 100644 --- a/go.mod +++ b/go.mod @@ -29,7 +29,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 v0.33.9-0.20240917220643-0782640a7f2c + sigs.k8s.io/karpenter v0.33.9-0.20240925004400-4fc4749486b6 ) require ( diff --git a/go.sum b/go.sum index 79511b0972d7..e7a4f6b91dbf 100644 --- a/go.sum +++ b/go.sum @@ -760,8 +760,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 v0.33.9-0.20240917220643-0782640a7f2c h1:1gJfLXBINOGbp2+KojukAzpSuns4LWSs97OLeVzLloY= -sigs.k8s.io/karpenter v0.33.9-0.20240917220643-0782640a7f2c/go.mod h1:CpSddDzJyNGROic0uqiYM/+p7c/8iO7zshDf+rd1gJY= +sigs.k8s.io/karpenter v0.33.9-0.20240925004400-4fc4749486b6 h1:z8nhdEITGPHNURV5CAvDmh98bFIatmrKJnnwrYcYSLw= +sigs.k8s.io/karpenter v0.33.9-0.20240925004400-4fc4749486b6/go.mod h1:CpSddDzJyNGROic0uqiYM/+p7c/8iO7zshDf+rd1gJY= 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 ed974c2a2169..b36f5d840ca3 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 c7f956f01cd3..d85aec1f8fe3 100644 --- a/pkg/apis/v1/ec2nodeclass_conversion_test.go +++ b/pkg/apis/v1/ec2nodeclass_conversion_test.go @@ -21,6 +21,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" @@ -49,6 +50,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..ce1afa7e93b0 --- /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/pkg/apis/v1" + "github.com/aws/karpenter/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.EventuallyExpectCreatedNodeClaimCount("==", 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))) + }) + }) +})