Skip to content

Commit

Permalink
Ignore status fields during drift detection (#2546)
Browse files Browse the repository at this point in the history
  • Loading branch information
aruiz14 authored Jun 21, 2024
1 parent 712dbc8 commit c2fde2f
Show file tree
Hide file tree
Showing 5 changed files with 82 additions and 0 deletions.
1 change: 1 addition & 0 deletions e2e/assets/drift/correction-enabled/gitrepo.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,4 @@ spec:
enabled: true
paths:
- drift
- drift-ignore-status
11 changes: 11 additions & 0 deletions e2e/drift/drift_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,17 @@ var _ = Describe("Drift", Ordered, func() {
`{"name":"http","port":1234,"protocol":"TCP","targetPort":"http-web-svc"}]}}`))
})
})

Context("Resource manifests containing status fields", func() {
// Status must be ignored for drift correction, despite being part of the manifests
It("Is marked as ready", func() {
bundleName := "drift-correction-test-drift-ignore-status"
Eventually(func() bool {
b := getBundle(bundleName, k)
return b.Status.Summary.Ready == 1
}).Should(BeTrue())
})
})
})

When("Drift correction is enabled with force", func() {
Expand Down
2 changes: 2 additions & 0 deletions internal/cmd/agent/deployer/normalizers/norm.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ func (n Norm) Normalize(un *unstructured.Unstructured) error {
func New(lives objectset.ObjectByGVK, additions ...diff.Normalizer) Norm {
n := Norm{
normalizers: []diff.Normalizer{
// Status fields are normally subresources which can't be influenced by resource updates
&StatusNormalizer{},
&MutatingWebhookNormalizer{
Live: lives,
},
Expand Down
13 changes: 13 additions & 0 deletions internal/cmd/agent/deployer/normalizers/status.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package normalizers

import (
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
)

// StatusNormalizer removes a top-level "status" fields from the object, if present
type StatusNormalizer struct{}

func (_ StatusNormalizer) Normalize(un *unstructured.Unstructured) error {
unstructured.RemoveNestedField(un.Object, "status")
return nil
}
55 changes: 55 additions & 0 deletions internal/cmd/agent/deployer/normalizers/status_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package normalizers

import (
"errors"
"testing"

corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/runtime"
)

func TestStatusNormalizer_Normalize(t *testing.T) {
tests := []struct {
name string
obj runtime.Object
check func(object runtime.Object) error
}{
{
name: "object with status",
obj: &corev1.Pod{
Status: corev1.PodStatus{
PodIP: "1.2.3.4",
},
},
check: func(obj runtime.Object) error {
if obj.(*corev1.Pod).Status.PodIP != "" {
return errors.New("status was not removed")
}
return nil
},
},
{
name: "object without status",
obj: &corev1.ConfigMap{},
check: func(_ runtime.Object) error { return nil },
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
un, err := runtime.DefaultUnstructuredConverter.ToUnstructured(tt.obj)
if err != nil {
t.Fatal(err)
}
if err := (StatusNormalizer{}).Normalize(&unstructured.Unstructured{Object: un}); err != nil {
t.Fatal(err)
}
if err := runtime.DefaultUnstructuredConverter.FromUnstructured(un, tt.obj); err != nil {
t.Fatal(err)
}
if err := tt.check(tt.obj); err != nil {
t.Error(err)
}
})
}
}

0 comments on commit c2fde2f

Please sign in to comment.