Skip to content

Commit

Permalink
Update Controller to Include Hash
Browse files Browse the repository at this point in the history
  • Loading branch information
engedaam committed Jul 27, 2023
1 parent 899e5e1 commit ea972f5
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 3 deletions.
2 changes: 1 addition & 1 deletion charts/karpenter/templates/clusterrole.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -42,5 +42,5 @@ rules:
resourceNames: ["defaulting.webhook.karpenter.k8s.aws"]
# Write
- apiGroups: ["karpenter.k8s.aws"]
resources: ["awsnodetemplates/status"]
resources: ["awsnodetemplates", "awsnodetemplates/status"]
verbs: ["patch", "update"]
12 changes: 10 additions & 2 deletions pkg/controllers/nodetemplate/controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import (

"go.uber.org/multierr"
"golang.org/x/time/rate"
"k8s.io/apimachinery/pkg/api/equality"
"k8s.io/client-go/util/workqueue"
controllerruntime "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/client"
Expand Down Expand Up @@ -61,14 +62,21 @@ func NewController(kubeClient client.Client, subnetProvider *subnet.Provider, se
func (c *Controller) Reconcile(ctx context.Context, nodeTemplate *v1alpha1.AWSNodeTemplate) (reconcile.Result, error) {
stored := nodeTemplate.DeepCopy()

nodeTemplate.Annotations = lo.Assign(nodeTemplate.ObjectMeta.Annotations, map[string]string{v1alpha1.AnnotationNodeTemplateHash: nodeTemplate.Hash()})
err := multierr.Combine(
c.resolveSubnets(ctx, nodeTemplate),
c.resolveSecurityGroups(ctx, nodeTemplate),
c.resolveAMIs(ctx, nodeTemplate),
)

if patchErr := c.kubeClient.Status().Patch(ctx, nodeTemplate, client.MergeFrom(stored)); patchErr != nil {
err = multierr.Append(err, client.IgnoreNotFound(patchErr))
if !equality.Semantic.DeepEqual(stored, nodeTemplate) {
statusCopy := nodeTemplate.DeepCopy()
if patchErr := c.kubeClient.Patch(ctx, nodeTemplate, client.MergeFrom(stored)); patchErr != nil {
err = multierr.Append(err, client.IgnoreNotFound(patchErr))
}
if patchErr := c.kubeClient.Status().Patch(ctx, statusCopy, client.MergeFrom(stored)); patchErr != nil {
err = multierr.Append(err, client.IgnoreNotFound(patchErr))
}
}

return reconcile.Result{RequeueAfter: 5 * time.Minute}, err
Expand Down
49 changes: 49 additions & 0 deletions pkg/controllers/nodetemplate/suite_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -720,6 +720,55 @@ var _ = Describe("AWSNodeTemplateController", func() {
))
})
})
Context("AWSNodeTemplate Static Drift Hash", func() {
DescribeTable("should update the static drift hash when nodeTemplate static field is updated", func(awsnodetemplatespec v1alpha1.AWSNodeTemplateSpec) {
updatedAWSNodeTemplate := test.AWSNodeTemplate(*nodeTemplate.Spec.DeepCopy(), awsnodetemplatespec)
updatedAWSNodeTemplate.ObjectMeta = nodeTemplate.ObjectMeta
updatedAWSNodeTemplate.Annotations = map[string]string{v1alpha1.AnnotationNodeTemplateHash: updatedAWSNodeTemplate.Hash()}

ExpectApplied(ctx, env.Client, nodeTemplate)
ExpectReconcileSucceeded(ctx, controller, client.ObjectKeyFromObject(nodeTemplate))
nodeTemplate = ExpectExists(ctx, env.Client, nodeTemplate)

expectedHash := nodeTemplate.Hash()
Expect(nodeTemplate.ObjectMeta.Annotations[v1alpha1.AnnotationNodeTemplateHash]).To(Equal(expectedHash))

ExpectApplied(ctx, env.Client, updatedAWSNodeTemplate)
ExpectReconcileSucceeded(ctx, controller, client.ObjectKeyFromObject(nodeTemplate))
nodeTemplate = ExpectExists(ctx, env.Client, nodeTemplate)

expectedHashTwo := nodeTemplate.Hash()
Expect(expectedHash).ToNot(Equal(expectedHashTwo))
Expect(nodeTemplate.ObjectMeta.Annotations[v1alpha1.AnnotationNodeTemplateHash]).To(Equal(expectedHashTwo))
},
Entry("InstanceProfile Drift", v1alpha1.AWSNodeTemplateSpec{AWS: v1alpha1.AWS{InstanceProfile: aws.String("profile-2")}}),
Entry("UserData Drift", v1alpha1.AWSNodeTemplateSpec{UserData: aws.String("userdata-test-2")}),
Entry("Tags Drift", v1alpha1.AWSNodeTemplateSpec{AWS: v1alpha1.AWS{Tags: map[string]string{"keyTag-test-3": "valueTag-test-3"}}}),
Entry("MetadataOptions Drift", v1alpha1.AWSNodeTemplateSpec{AWS: v1alpha1.AWS{LaunchTemplate: v1alpha1.LaunchTemplate{MetadataOptions: &v1alpha1.MetadataOptions{HTTPEndpoint: aws.String("test-metadata-2")}}}}),
Entry("BlockDeviceMappings Drift", v1alpha1.AWSNodeTemplateSpec{AWS: v1alpha1.AWS{LaunchTemplate: v1alpha1.LaunchTemplate{BlockDeviceMappings: []*v1alpha1.BlockDeviceMapping{{DeviceName: aws.String("map-device-test-3")}}}}}),
Entry("Context Drift", v1alpha1.AWSNodeTemplateSpec{AWS: v1alpha1.AWS{Context: aws.String("context-2")}}),
Entry("DetailedMonitoring Drift", v1alpha1.AWSNodeTemplateSpec{DetailedMonitoring: aws.Bool(true)}),
Entry("AMIFamily Drift", v1alpha1.AWSNodeTemplateSpec{AWS: v1alpha1.AWS{AMIFamily: aws.String(v1alpha1.AMIFamilyBottlerocket)}}),
)
It("should not update the static drift hash when nodeTemplate dynamic field is updated", func() {
ExpectApplied(ctx, env.Client, nodeTemplate)
ExpectReconcileSucceeded(ctx, controller, client.ObjectKeyFromObject(nodeTemplate))
nodeTemplate = ExpectExists(ctx, env.Client, nodeTemplate)

expectedHash := nodeTemplate.Hash()
Expect(nodeTemplate.ObjectMeta.Annotations[v1alpha1.AnnotationNodeTemplateHash]).To(Equal(expectedHash))

nodeTemplate.Spec.SubnetSelector = map[string]string{"aws-ids": "subnet-test1"}
nodeTemplate.Spec.SecurityGroupSelector = map[string]string{"aws-ids": "sg-test1"}
nodeTemplate.Spec.AMISelector = map[string]string{"ami-test-key": "ami-test-value"}

ExpectApplied(ctx, env.Client, nodeTemplate)
ExpectReconcileSucceeded(ctx, controller, client.ObjectKeyFromObject(nodeTemplate))
nodeTemplate = ExpectExists(ctx, env.Client, nodeTemplate)

Expect(nodeTemplate.ObjectMeta.Annotations[v1alpha1.AnnotationNodeTemplateHash]).To(Equal(expectedHash))
})
})
})

func sortRequirements(amis []v1alpha1.AMI) {
Expand Down

0 comments on commit ea972f5

Please sign in to comment.