Skip to content

Commit

Permalink
Fix status not updating when the spec has an update
Browse files Browse the repository at this point in the history
  • Loading branch information
jonathan-innis committed Dec 20, 2022
1 parent 7a8783c commit 93dc59e
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 8 deletions.
14 changes: 6 additions & 8 deletions pkg/operator/controller/typed.go
Original file line number Diff line number Diff line change
Expand Up @@ -98,20 +98,18 @@ func (t *typedDecorator[T]) Builder(ctx context.Context, m manager.Manager) Buil
}

func (t *typedDecorator[T]) patch(ctx context.Context, obj, updated client.Object) error {
// If an updated value returns as nil from the Reconcile function, this means we shouldn't update the object
if reflect.ValueOf(updated).IsNil() {
return nil
}
statusCopy := updated.DeepCopyObject().(client.Object) // Snapshot the status, since create/update may override

// Patch Body if changed
if !bodyEqual(obj, updated) {
if err := t.kubeClient.Patch(ctx, updated, client.MergeFrom(obj)); err != nil {
return err
return client.IgnoreNotFound(err)
}
}
// Patch Status if changed
if !statusEqual(obj, updated) {
if err := t.kubeClient.Status().Patch(ctx, updated, client.MergeFrom(obj)); err != nil {
return err
if !statusEqual(obj, statusCopy) {
if err := t.kubeClient.Status().Patch(ctx, statusCopy, client.MergeFrom(obj)); err != nil {
return client.IgnoreNotFound(err) // Status subresource may not exist
}
}
return nil
Expand Down
27 changes: 27 additions & 0 deletions pkg/operator/controller/typed_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import (

"github.com/samber/lo"
v1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/resource"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
"sigs.k8s.io/controller-runtime/pkg/manager"
Expand Down Expand Up @@ -84,6 +85,32 @@ var _ = Describe("Typed", func() {
node = ExpectNodeExists(ctx, env.Client, node.Name)
Expect(node.Labels).To(HaveKeyWithValue("custom-key", "custom-value"))
})
It("should modify the provisioner and the provisioner status in the reconcile", func() {
provisioner := test.Provisioner()
ExpectApplied(ctx, env.Client, provisioner)
fakeController := &FakeTypedController[*v1alpha5.Provisioner]{
ReconcileAssertions: []TypedReconcileAssertion[*v1alpha5.Provisioner]{
func(ctx context.Context, p *v1alpha5.Provisioner) {
p.Labels = lo.Assign(p.Labels, map[string]string{
"custom-key": "custom-value",
})
p.Status.Resources = v1.ResourceList{
v1.ResourceCPU: resource.MustParse("1"),
v1.ResourceMemory: resource.MustParse("1Mi"),
v1.ResourceEphemeralStorage: resource.MustParse("1Gi"),
}
},
},
}
typedController := controller.Typed[*v1alpha5.Provisioner](env.Client, fakeController)
ExpectReconcileSucceeded(ctx, typedController, client.ObjectKeyFromObject(provisioner))
Expect(env.Client.Get(ctx, client.ObjectKeyFromObject(provisioner), provisioner)).To(Succeed())
Expect(provisioner.Labels).To(HaveKeyWithValue("custom-key", "custom-value"))
Expect(provisioner.Status.Resources).To(HaveLen(3))
Expect(provisioner.Status.Resources).To(HaveKeyWithValue(v1.ResourceCPU, resource.MustParse("1")))
Expect(provisioner.Status.Resources).To(HaveKeyWithValue(v1.ResourceMemory, resource.MustParse("1Mi")))
Expect(provisioner.Status.Resources).To(HaveKeyWithValue(v1.ResourceEphemeralStorage, resource.MustParse("1Gi")))
})
It("should call finalizer func when finalizing", func() {
node := test.Node(test.NodeOptions{
ObjectMeta: metav1.ObjectMeta{
Expand Down

0 comments on commit 93dc59e

Please sign in to comment.