From 447cffd60ba25ecb884f8a632b385186a30bd130 Mon Sep 17 00:00:00 2001 From: Sam Dowell Date: Tue, 11 Feb 2025 15:12:35 -0800 Subject: [PATCH] feat: add observedGeneration to CommonStatus This updates the built in CommonStatus struct to provide observedGeneration behavior when using one of the provided status builders. Custom implementations of the BuildStatus interface could already set observedGeneration if desired, but this provides an opinionated default to the addon implementations. --- go.work.sum | 1 + pkg/patterns/addon/pkg/apis/v1alpha1/common_types.go | 2 ++ pkg/patterns/addon/pkg/status/aggregate.go | 1 + pkg/patterns/addon/pkg/status/kstatus.go | 1 + .../reconcile/direct/create/expected-http.yaml | 12 ++++++------ .../testdata/reconcile/ssa/create/expected-http.yaml | 12 ++++++------ 6 files changed, 17 insertions(+), 12 deletions(-) diff --git a/go.work.sum b/go.work.sum index 55d8a8e6..62337891 100644 --- a/go.work.sum +++ b/go.work.sum @@ -251,6 +251,7 @@ github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFB github.com/lithammer/dedent v1.1.0/go.mod h1:jrXYCQtgg0nJiN+StA2KgR7w6CiQNv9Fd/Z9BP0jIOc= github.com/lyft/protoc-gen-star/v2 v2.0.3/go.mod h1:amey7yeodaJhXSbf/TlLvWiqQfLOSpEk//mLlc+axEk= github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369 h1:I0XW9+e1XWDxdcEniV4rQAIOPUGDq67JSCiRCgGCZLI= +github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= github.com/matttproud/golang_protobuf_extensions v1.0.2 h1:hAHbPm5IJGijwng3PWk09JkG9WeqChjprR5s9bBZ+OM= github.com/matttproud/golang_protobuf_extensions v1.0.2/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo= diff --git a/pkg/patterns/addon/pkg/apis/v1alpha1/common_types.go b/pkg/patterns/addon/pkg/apis/v1alpha1/common_types.go index 0837d744..d6cd191d 100644 --- a/pkg/patterns/addon/pkg/apis/v1alpha1/common_types.go +++ b/pkg/patterns/addon/pkg/apis/v1alpha1/common_types.go @@ -47,6 +47,8 @@ type CommonStatus struct { Healthy bool `json:"healthy"` Errors []string `json:"errors,omitempty"` Phase string `json:"phase,omitempty"` + // +kubebuilder:default:=0 + ObservedGeneration int64 `json:"observedGeneration"` } // Patchable is a trait for addon CRDs that expose a raw set of Patches to be diff --git a/pkg/patterns/addon/pkg/status/aggregate.go b/pkg/patterns/addon/pkg/status/aggregate.go index cde8aa7a..b810ed9e 100644 --- a/pkg/patterns/addon/pkg/status/aggregate.go +++ b/pkg/patterns/addon/pkg/status/aggregate.go @@ -96,6 +96,7 @@ func (a *aggregator) BuildStatus(ctx context.Context, info *declarative.StatusIn status := currentStatus status.Healthy = statusHealthy status.Errors = statusErrors + status.ObservedGeneration = info.Subject.GetGeneration() if !reflect.DeepEqual(status, currentStatus) { err := utils.SetCommonStatus(info.Subject, status) diff --git a/pkg/patterns/addon/pkg/status/kstatus.go b/pkg/patterns/addon/pkg/status/kstatus.go index c0691705..45e3f4b1 100644 --- a/pkg/patterns/addon/pkg/status/kstatus.go +++ b/pkg/patterns/addon/pkg/status/kstatus.go @@ -161,6 +161,7 @@ func (k *kstatusAggregator) BuildStatus(ctx context.Context, info *declarative.S } } currentStatus.Healthy = currentStatus.Phase == string(status.CurrentStatus) + currentStatus.ObservedGeneration = info.Subject.GetGeneration() if err = utils.SetCommonStatus(info.Subject, currentStatus); err != nil { return err } diff --git a/pkg/test/testreconciler/simpletest/testdata/reconcile/direct/create/expected-http.yaml b/pkg/test/testreconciler/simpletest/testdata/reconcile/direct/create/expected-http.yaml index abcf7820..dc8f6aa6 100644 --- a/pkg/test/testreconciler/simpletest/testdata/reconcile/direct/create/expected-http.yaml +++ b/pkg/test/testreconciler/simpletest/testdata/reconcile/direct/create/expected-http.yaml @@ -233,16 +233,16 @@ PUT http://kube-apiserver/apis/addons.example.org/v1alpha1/namespaces/ns1/simple Accept: application/json, */* Content-Type: application/json -{"kind":"SimpleTest","apiVersion":"addons.example.org/v1alpha1","metadata":{"name":"simple1","namespace":"ns1","uid":"00000000-0000-0000-0000-000000000002","resourceVersion":"2","generation":1,"creationTimestamp":"2022-01-01T00:00:01Z"},"spec":{"channel":"stable"},"status":{"healthy":true}} +{"kind":"SimpleTest","apiVersion":"addons.example.org/v1alpha1","metadata":{"name":"simple1","namespace":"ns1","uid":"00000000-0000-0000-0000-000000000002","resourceVersion":"2","generation":1,"creationTimestamp":"2022-01-01T00:00:01Z"},"spec":{"channel":"stable"},"status":{"healthy":true,"observedGeneration":1}} 200 OK Cache-Control: no-cache, private -Content-Length: 291 +Content-Length: 314 Content-Type: application/json Date: (removed) -{"apiVersion":"addons.example.org/v1alpha1","kind":"SimpleTest","metadata":{"creationTimestamp":"2022-01-01T00:00:01Z","generation":1,"name":"simple1","namespace":"ns1","resourceVersion":"5","uid":"00000000-0000-0000-0000-000000000002"},"spec":{"channel":"stable"},"status":{"healthy":true}} +{"apiVersion":"addons.example.org/v1alpha1","kind":"SimpleTest","metadata":{"creationTimestamp":"2022-01-01T00:00:01Z","generation":1,"name":"simple1","namespace":"ns1","resourceVersion":"5","uid":"00000000-0000-0000-0000-000000000002"},"spec":{"channel":"stable"},"status":{"healthy":true,"observedGeneration":1}} --- @@ -320,13 +320,13 @@ PUT http://kube-apiserver/apis/addons.example.org/v1alpha1/namespaces/ns1/simple Accept: application/json, */* Content-Type: application/json -{"kind":"SimpleTest","apiVersion":"addons.example.org/v1alpha1","metadata":{"name":"simple1","namespace":"ns1","uid":"00000000-0000-0000-0000-000000000002","resourceVersion":"5","generation":1,"creationTimestamp":"2022-01-01T00:00:01Z"},"spec":{"channel":"stable"},"status":{"healthy":true}} +{"kind":"SimpleTest","apiVersion":"addons.example.org/v1alpha1","metadata":{"name":"simple1","namespace":"ns1","uid":"00000000-0000-0000-0000-000000000002","resourceVersion":"5","generation":1,"creationTimestamp":"2022-01-01T00:00:01Z"},"spec":{"channel":"stable"},"status":{"healthy":true,"observedGeneration":1}} 200 OK Cache-Control: no-cache, private -Content-Length: 291 +Content-Length: 314 Content-Type: application/json Date: (removed) -{"apiVersion":"addons.example.org/v1alpha1","kind":"SimpleTest","metadata":{"creationTimestamp":"2022-01-01T00:00:01Z","generation":1,"name":"simple1","namespace":"ns1","resourceVersion":"5","uid":"00000000-0000-0000-0000-000000000002"},"spec":{"channel":"stable"},"status":{"healthy":true}} +{"apiVersion":"addons.example.org/v1alpha1","kind":"SimpleTest","metadata":{"creationTimestamp":"2022-01-01T00:00:01Z","generation":1,"name":"simple1","namespace":"ns1","resourceVersion":"5","uid":"00000000-0000-0000-0000-000000000002"},"spec":{"channel":"stable"},"status":{"healthy":true,"observedGeneration":1}} diff --git a/pkg/test/testreconciler/simpletest/testdata/reconcile/ssa/create/expected-http.yaml b/pkg/test/testreconciler/simpletest/testdata/reconcile/ssa/create/expected-http.yaml index 0fc0b2c0..7b0463a3 100644 --- a/pkg/test/testreconciler/simpletest/testdata/reconcile/ssa/create/expected-http.yaml +++ b/pkg/test/testreconciler/simpletest/testdata/reconcile/ssa/create/expected-http.yaml @@ -127,16 +127,16 @@ PUT http://kube-apiserver/apis/addons.example.org/v1alpha1/namespaces/ns1/simple Accept: application/json, */* Content-Type: application/json -{"kind":"SimpleTest","apiVersion":"addons.example.org/v1alpha1","metadata":{"name":"simple1","namespace":"ns1","uid":"00000000-0000-0000-0000-000000000002","resourceVersion":"2","generation":1,"creationTimestamp":"2022-01-01T00:00:01Z","labels":{"applyset.kubernetes.io/id":"applyset-xbxAWnAItX3p1Gxrs86F-ZQAGwGoys9xxQGK3IED7bY-v1"},"annotations":{"applyset.kubernetes.io/additional-namespaces":"","applyset.kubernetes.io/contains-group-kinds":"ConfigMap,Deployment.apps","applyset.kubernetes.io/tooling":"SimpleTest/"}},"spec":{"channel":"stable"},"status":{"healthy":false}} +{"kind":"SimpleTest","apiVersion":"addons.example.org/v1alpha1","metadata":{"name":"simple1","namespace":"ns1","uid":"00000000-0000-0000-0000-000000000002","resourceVersion":"2","generation":1,"creationTimestamp":"2022-01-01T00:00:01Z","labels":{"applyset.kubernetes.io/id":"applyset-xbxAWnAItX3p1Gxrs86F-ZQAGwGoys9xxQGK3IED7bY-v1"},"annotations":{"applyset.kubernetes.io/additional-namespaces":"","applyset.kubernetes.io/contains-group-kinds":"ConfigMap,Deployment.apps","applyset.kubernetes.io/tooling":"SimpleTest/"}},"spec":{"channel":"stable"},"status":{"healthy":false,"observedGeneration":0}} 200 OK Cache-Control: no-cache, private -Content-Length: 576 +Content-Length: 599 Content-Type: application/json Date: (removed) -{"apiVersion":"addons.example.org/v1alpha1","kind":"SimpleTest","metadata":{"annotations":{"applyset.kubernetes.io/additional-namespaces":"","applyset.kubernetes.io/contains-group-kinds":"ConfigMap,Deployment.apps","applyset.kubernetes.io/tooling":"SimpleTest/"},"creationTimestamp":"2022-01-01T00:00:01Z","generation":1,"labels":{"applyset.kubernetes.io/id":"applyset-xbxAWnAItX3p1Gxrs86F-ZQAGwGoys9xxQGK3IED7bY-v1"},"name":"simple1","namespace":"ns1","resourceVersion":"3","uid":"00000000-0000-0000-0000-000000000002"},"spec":{"channel":"stable"},"status":{"healthy":false}} +{"apiVersion":"addons.example.org/v1alpha1","kind":"SimpleTest","metadata":{"annotations":{"applyset.kubernetes.io/additional-namespaces":"","applyset.kubernetes.io/contains-group-kinds":"ConfigMap,Deployment.apps","applyset.kubernetes.io/tooling":"SimpleTest/"},"creationTimestamp":"2022-01-01T00:00:01Z","generation":1,"labels":{"applyset.kubernetes.io/id":"applyset-xbxAWnAItX3p1Gxrs86F-ZQAGwGoys9xxQGK3IED7bY-v1"},"name":"simple1","namespace":"ns1","resourceVersion":"3","uid":"00000000-0000-0000-0000-000000000002"},"spec":{"channel":"stable"},"status":{"healthy":false,"observedGeneration":0}} --- @@ -204,15 +204,15 @@ PUT http://kube-apiserver/apis/addons.example.org/v1alpha1/namespaces/ns1/simple Accept: application/json, */* Content-Type: application/json -{"apiVersion":"addons.example.org/v1alpha1","kind":"SimpleTest","metadata":{"annotations":{"applyset.kubernetes.io/additional-namespaces":"","applyset.kubernetes.io/contains-group-kinds":"ConfigMap,Deployment.apps","applyset.kubernetes.io/tooling":"SimpleTest/"},"creationTimestamp":"2022-01-01T00:00:01Z","generation":1,"labels":{"applyset.kubernetes.io/id":"applyset-xbxAWnAItX3p1Gxrs86F-ZQAGwGoys9xxQGK3IED7bY-v1"},"name":"simple1","namespace":"ns1","resourceVersion":"3","uid":"00000000-0000-0000-0000-000000000002"},"spec":{"channel":"stable"},"status":{"conditions":[{"lastTransitionTime":"2022-01-01T00:00:00Z","message":"all manifests are reconciled.","reason":"Normal","status":"True","type":"Ready"}],"healthy":true,"phase":"Current"}} +{"apiVersion":"addons.example.org/v1alpha1","kind":"SimpleTest","metadata":{"annotations":{"applyset.kubernetes.io/additional-namespaces":"","applyset.kubernetes.io/contains-group-kinds":"ConfigMap,Deployment.apps","applyset.kubernetes.io/tooling":"SimpleTest/"},"creationTimestamp":"2022-01-01T00:00:01Z","generation":1,"labels":{"applyset.kubernetes.io/id":"applyset-xbxAWnAItX3p1Gxrs86F-ZQAGwGoys9xxQGK3IED7bY-v1"},"name":"simple1","namespace":"ns1","resourceVersion":"3","uid":"00000000-0000-0000-0000-000000000002"},"spec":{"channel":"stable"},"status":{"conditions":[{"lastTransitionTime":"2022-01-01T00:00:00Z","message":"all manifests are reconciled.","reason":"Normal","status":"True","type":"Ready"}],"healthy":true,"observedGeneration":1,"phase":"Current"}} 200 OK Cache-Control: no-cache, private -Content-Length: 745 +Content-Length: 768 Content-Type: application/json Date: (removed) -{"apiVersion":"addons.example.org/v1alpha1","kind":"SimpleTest","metadata":{"annotations":{"applyset.kubernetes.io/additional-namespaces":"","applyset.kubernetes.io/contains-group-kinds":"ConfigMap,Deployment.apps","applyset.kubernetes.io/tooling":"SimpleTest/"},"creationTimestamp":"2022-01-01T00:00:01Z","generation":1,"labels":{"applyset.kubernetes.io/id":"applyset-xbxAWnAItX3p1Gxrs86F-ZQAGwGoys9xxQGK3IED7bY-v1"},"name":"simple1","namespace":"ns1","resourceVersion":"6","uid":"00000000-0000-0000-0000-000000000002"},"spec":{"channel":"stable"},"status":{"conditions":[{"lastTransitionTime":"2022-01-01T00:00:00Z","message":"all manifests are reconciled.","reason":"Normal","status":"True","type":"Ready"}],"healthy":true,"phase":"Current"}} +{"apiVersion":"addons.example.org/v1alpha1","kind":"SimpleTest","metadata":{"annotations":{"applyset.kubernetes.io/additional-namespaces":"","applyset.kubernetes.io/contains-group-kinds":"ConfigMap,Deployment.apps","applyset.kubernetes.io/tooling":"SimpleTest/"},"creationTimestamp":"2022-01-01T00:00:01Z","generation":1,"labels":{"applyset.kubernetes.io/id":"applyset-xbxAWnAItX3p1Gxrs86F-ZQAGwGoys9xxQGK3IED7bY-v1"},"name":"simple1","namespace":"ns1","resourceVersion":"6","uid":"00000000-0000-0000-0000-000000000002"},"spec":{"channel":"stable"},"status":{"conditions":[{"lastTransitionTime":"2022-01-01T00:00:00Z","message":"all manifests are reconciled.","reason":"Normal","status":"True","type":"Ready"}],"healthy":true,"observedGeneration":1,"phase":"Current"}} ---