From 4dcbbd7d24d20b53c97e6dc9d036d48be3d5fb0e Mon Sep 17 00:00:00 2001 From: SuminSSon <56192209+SuminSSon@users.noreply.github.com> Date: Wed, 30 Oct 2024 00:25:30 +0900 Subject: [PATCH 01/14] docs: correct typos in documentation (#20569) * docs: update Cluster Generator example for cluster name accuracy Signed-off-by: SuminSSon * docs: standardized 'GitPod' to 'Gitpod' for consistency Signed-off-by: SuminSSon --------- Signed-off-by: SuminSSon --- docs/developer-guide/use-gitpod.md | 2 +- docs/operator-manual/applicationset/Generators-Cluster.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/developer-guide/use-gitpod.md b/docs/developer-guide/use-gitpod.md index 12b2c49eabf40..36f783bdc99dc 100644 --- a/docs/developer-guide/use-gitpod.md +++ b/docs/developer-guide/use-gitpod.md @@ -1,7 +1,7 @@ # Use Gitpod [Gitpod](https://www.gitpod.io/) is an open-source platform for automated and ready-to-code development environments. -GitPod is probably the easiest way to get ready to use development environment with the most tools that are required +Gitpod is probably the easiest way to get ready to use development environment with the most tools that are required for Argo CD development. ## How To Use It diff --git a/docs/operator-manual/applicationset/Generators-Cluster.md b/docs/operator-manual/applicationset/Generators-Cluster.md index 3dea3743be301..5b70cc206e98c 100644 --- a/docs/operator-manual/applicationset/Generators-Cluster.md +++ b/docs/operator-manual/applicationset/Generators-Cluster.md @@ -309,7 +309,7 @@ spec: values: | clusters: - name: cluster1 - - name: cluster1 + - name: cluster2 ``` In case you are using several cluster generators, each with the flatList option, one Application would be generated by cluster generator, as we can't simply merge values and templates that would potentially differ in each generator. \ No newline at end of file From 3625689264215d9e83bfafc5fe165c8fcd764ece Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 29 Oct 2024 11:54:17 -0400 Subject: [PATCH 02/14] chore(deps): update dependency pymdown-extensions to v10.12 (#20567) Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- docs/requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/requirements.txt b/docs/requirements.txt index 180b8473c5a41..ad1dcf32ff1ea 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -6,4 +6,4 @@ markdown_include==0.8.1 pygments==2.18.0 jinja2==3.1.4 markdown==3.7 -pymdown-extensions==10.11.2 \ No newline at end of file +pymdown-extensions==10.12 \ No newline at end of file From 76fbc1f0c99df7bfc5005ec5e25ede61cf47d990 Mon Sep 17 00:00:00 2001 From: ABBOUD Moncef Date: Tue, 29 Oct 2024 19:31:11 +0100 Subject: [PATCH 03/14] fix(ci): ignore temporary files when checking for out of bound symlinks (#20527) Signed-off-by: cef --- util/app/path/path.go | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/util/app/path/path.go b/util/app/path/path.go index 2dc3af09e7322..66f4fe1c02678 100644 --- a/util/app/path/path.go +++ b/util/app/path/path.go @@ -1,6 +1,7 @@ package path import ( + "errors" "fmt" "os" "path/filepath" @@ -51,6 +52,11 @@ func CheckOutOfBoundsSymlinks(basePath string) error { } return filepath.Walk(absBasePath, func(path string, info os.FileInfo, err error) error { if err != nil { + // Ignore "no such file or directory" errors than can happen with + // temporary files such as .git/*.lock + if errors.Is(err, os.ErrNotExist) { + return nil + } return fmt.Errorf("failed to walk for symlinks in %s: %w", absBasePath, err) } if files.IsSymlink(info) { From 96876195410393c742bb40330c7f174c454f1a9d Mon Sep 17 00:00:00 2001 From: Julie Vogelman Date: Tue, 29 Oct 2024 12:32:01 -0700 Subject: [PATCH 04/14] fix: updates to health status for Numaplane resources (#20544) * fix: updates to health status for Numaplane resources Signed-off-by: Julie Vogelman * health checks Signed-off-by: Julie Vogelman * fix testdata path Signed-off-by: Julie Vogelman * additional health check tests Signed-off-by: Julie Vogelman * temporary file removal Signed-off-by: Julie Vogelman * add file renamed Signed-off-by: Julie Vogelman * fix: empty commit Signed-off-by: Julie Vogelman * move check for no status Signed-off-by: Julie Vogelman * fix: empty commit Signed-off-by: Julie Vogelman * fix: empty commit Signed-off-by: Julie Vogelman --------- Signed-off-by: Julie Vogelman --- .../ISBServiceRollout/health.lua | 72 ++++++++++----- .../ISBServiceRollout/health_test.yaml | 20 +++-- .../{ => ISBServiceRollout}/degraded.yaml | 0 .../{ => ISBServiceRollout}/healthy.yaml | 0 .../pending-upgrade-in-progress.yaml | 40 +++++++++ .../progressing-nostatus.yaml | 0 .../progressing-observedgen.yaml} | 0 .../progressing-reason.yaml | 0 .../actions/action_test.yaml | 8 +- .../rollout-paused.yaml | 0 .../rollout-running.yaml | 0 .../{ => MonoVertexRollout}/rollout.yaml | 0 .../MonoVertexRollout/health.lua | 80 ++++++++++++----- .../MonoVertexRollout/health_test.yaml | 16 ++-- .../{ => MonoVertexRollout}/degraded.yaml | 0 .../{ => MonoVertexRollout}/healthy.yaml | 0 .../pending-upgrade-in-progress.yaml | 47 ++++++++++ .../progressing-observedgen.yaml} | 0 .../progressing-reason.yaml | 0 .../NumaflowControllerRollout/health.lua | 73 +++++++++++----- .../health_test.yaml | 16 ++-- .../degraded.yaml | 0 .../healthy.yaml | 0 .../NumaflowControllerRollout/pending.yaml | 36 ++++++++ .../progressing-observedgen.yaml} | 0 .../progressing-reason.yaml | 0 .../PipelineRollout/actions/action_test.yaml | 16 ++-- .../rollout-allowing-data-loss.yaml | 0 .../rollout-disallowing-data-loss.yaml | 0 .../rollout-in-ppnd.yaml | 0 .../{ => PipelineRollout}/rollout-paused.yaml | 0 .../rollout-running.yaml | 0 .../{ => PipelineRollout}/rollout.yaml | 0 .../PipelineRollout/health.lua | 87 ++++++++++++------- .../PipelineRollout/health_test.yaml | 18 ++-- .../{ => PipelineRollout}/degraded.yaml | 0 .../{ => PipelineRollout}/healthy.yaml | 0 .../{ => PipelineRollout}/paused.yaml | 0 .../pending-upgrade-in-progress.yaml | 60 +++++++++++++ .../progressing-observedGen.yaml} | 0 .../progressing-reason.yaml | 0 41 files changed, 454 insertions(+), 135 deletions(-) rename resource_customizations/numaplane.numaproj.io/ISBServiceRollout/testdata/{ => ISBServiceRollout}/degraded.yaml (100%) rename resource_customizations/numaplane.numaproj.io/ISBServiceRollout/testdata/{ => ISBServiceRollout}/healthy.yaml (100%) create mode 100644 resource_customizations/numaplane.numaproj.io/ISBServiceRollout/testdata/ISBServiceRollout/pending-upgrade-in-progress.yaml rename resource_customizations/numaplane.numaproj.io/ISBServiceRollout/testdata/{ => ISBServiceRollout}/progressing-nostatus.yaml (100%) rename resource_customizations/numaplane.numaproj.io/ISBServiceRollout/testdata/{progressing.yaml => ISBServiceRollout/progressing-observedgen.yaml} (100%) rename resource_customizations/numaplane.numaproj.io/ISBServiceRollout/testdata/{ => ISBServiceRollout}/progressing-reason.yaml (100%) rename resource_customizations/numaplane.numaproj.io/MonoVertexRollout/actions/testdata/{ => MonoVertexRollout}/rollout-paused.yaml (100%) rename resource_customizations/numaplane.numaproj.io/MonoVertexRollout/actions/testdata/{ => MonoVertexRollout}/rollout-running.yaml (100%) rename resource_customizations/numaplane.numaproj.io/MonoVertexRollout/actions/testdata/{ => MonoVertexRollout}/rollout.yaml (100%) rename resource_customizations/numaplane.numaproj.io/MonoVertexRollout/testdata/{ => MonoVertexRollout}/degraded.yaml (100%) rename resource_customizations/numaplane.numaproj.io/MonoVertexRollout/testdata/{ => MonoVertexRollout}/healthy.yaml (100%) create mode 100644 resource_customizations/numaplane.numaproj.io/MonoVertexRollout/testdata/MonoVertexRollout/pending-upgrade-in-progress.yaml rename resource_customizations/numaplane.numaproj.io/MonoVertexRollout/testdata/{progressing.yaml => MonoVertexRollout/progressing-observedgen.yaml} (100%) rename resource_customizations/numaplane.numaproj.io/MonoVertexRollout/testdata/{ => MonoVertexRollout}/progressing-reason.yaml (100%) rename resource_customizations/numaplane.numaproj.io/NumaflowControllerRollout/testdata/{ => NumaflowControllerRollout}/degraded.yaml (100%) rename resource_customizations/numaplane.numaproj.io/NumaflowControllerRollout/testdata/{ => NumaflowControllerRollout}/healthy.yaml (100%) create mode 100644 resource_customizations/numaplane.numaproj.io/NumaflowControllerRollout/testdata/NumaflowControllerRollout/pending.yaml rename resource_customizations/numaplane.numaproj.io/NumaflowControllerRollout/testdata/{progressing.yaml => NumaflowControllerRollout/progressing-observedgen.yaml} (100%) rename resource_customizations/numaplane.numaproj.io/NumaflowControllerRollout/testdata/{ => NumaflowControllerRollout}/progressing-reason.yaml (100%) rename resource_customizations/numaplane.numaproj.io/PipelineRollout/actions/testdata/{ => PipelineRollout}/rollout-allowing-data-loss.yaml (100%) rename resource_customizations/numaplane.numaproj.io/PipelineRollout/actions/testdata/{ => PipelineRollout}/rollout-disallowing-data-loss.yaml (100%) rename resource_customizations/numaplane.numaproj.io/PipelineRollout/actions/testdata/{ => PipelineRollout}/rollout-in-ppnd.yaml (100%) rename resource_customizations/numaplane.numaproj.io/PipelineRollout/actions/testdata/{ => PipelineRollout}/rollout-paused.yaml (100%) rename resource_customizations/numaplane.numaproj.io/PipelineRollout/actions/testdata/{ => PipelineRollout}/rollout-running.yaml (100%) rename resource_customizations/numaplane.numaproj.io/PipelineRollout/actions/testdata/{ => PipelineRollout}/rollout.yaml (100%) rename resource_customizations/numaplane.numaproj.io/PipelineRollout/testdata/{ => PipelineRollout}/degraded.yaml (100%) rename resource_customizations/numaplane.numaproj.io/PipelineRollout/testdata/{ => PipelineRollout}/healthy.yaml (100%) rename resource_customizations/numaplane.numaproj.io/PipelineRollout/testdata/{ => PipelineRollout}/paused.yaml (100%) create mode 100644 resource_customizations/numaplane.numaproj.io/PipelineRollout/testdata/PipelineRollout/pending-upgrade-in-progress.yaml rename resource_customizations/numaplane.numaproj.io/PipelineRollout/testdata/{progressing.yaml => PipelineRollout/progressing-observedGen.yaml} (100%) rename resource_customizations/numaplane.numaproj.io/PipelineRollout/testdata/{ => PipelineRollout}/progressing-reason.yaml (100%) diff --git a/resource_customizations/numaplane.numaproj.io/ISBServiceRollout/health.lua b/resource_customizations/numaplane.numaproj.io/ISBServiceRollout/health.lua index 1bcd2892b4160..934c59d5859cb 100644 --- a/resource_customizations/numaplane.numaproj.io/ISBServiceRollout/health.lua +++ b/resource_customizations/numaplane.numaproj.io/ISBServiceRollout/health.lua @@ -1,32 +1,60 @@ local hs = {} local healthyCondition = {} -if obj.status ~= nil then - if obj.status.conditions ~= nil then - for i, condition in ipairs(obj.status.conditions) do - if condition.type == "ChildResourcesHealthy" then - healthyCondition = condition - end +-- check for certain cases of "Progressing" + +if obj.status == nil then -- if there's no Status at all, we haven't been reconciled + hs.status = "Progressing" + hs.message = "Not yet reconciled" + return hs +end + +if obj.metadata.generation ~= obj.status.observedGeneration then + hs.status = "Progressing" + hs.message = "Not yet reconciled" + return hs +end + +if obj.status.phase == "Pending" then + hs.status = "Progressing" + hs.message = "Phase=Pending" + return hs +end + +if obj.status.upgradeInProgress ~= nil and obj.status.upgradeInProgress ~= "" then + hs.status = "Progressing" + hs.message = "Update in progress" + return hs +end + +-- now check the Conditions + +if obj.status.conditions ~= nil then + for i, condition in ipairs(obj.status.conditions) do + if condition.type == "ChildResourcesHealthy" then + healthyCondition = condition end end +end - if obj.metadata.generation == obj.status.observedGeneration then - if (healthyCondition ~= {} and healthyCondition.status == "False" and (obj.metadata.generation == healthyCondition.observedGeneration) and healthyCondition.reason == "ISBSvcFailed") or obj.status.phase == "Failed" then - hs.status = "Degraded" - if obj.status.phase == "Failed" then - hs.message = obj.status.message - else - hs.message = healthyCondition.message - end - return hs - elseif healthyCondition ~= {} and healthyCondition.status == "True" and (obj.metadata.generation == healthyCondition.observedGeneration) and obj.status.phase == "Deployed" then - hs.status = "Healthy" - hs.message = healthyCondition.message - return hs - end +if (healthyCondition ~= {} and healthyCondition.status == "False" and healthyCondition.reason == "ISBSvcFailed") or obj.status.phase == "Failed" then + hs.status = "Degraded" + if obj.status.phase == "Failed" then + hs.message = obj.status.message + else + hs.message = healthyCondition.message end + return hs +elseif healthyCondition ~= {} and healthyCondition.status == "False" and healthyCondition.reason == "Progressing" then + hs.status = "Progressing" + hs.message = healthyCondition.message + return hs +elseif healthyCondition ~= {} and healthyCondition.status == "True" and obj.status.phase == "Deployed" then + hs.status = "Healthy" + hs.message = healthyCondition.message + return hs end -hs.status = "Progressing" -hs.message = "Waiting for ISBService status" +hs.status = "Unknown" +hs.message = "Unknown ISBService status" return hs \ No newline at end of file diff --git a/resource_customizations/numaplane.numaproj.io/ISBServiceRollout/health_test.yaml b/resource_customizations/numaplane.numaproj.io/ISBServiceRollout/health_test.yaml index b0b683266c6eb..c728c3d300a68 100644 --- a/resource_customizations/numaplane.numaproj.io/ISBServiceRollout/health_test.yaml +++ b/resource_customizations/numaplane.numaproj.io/ISBServiceRollout/health_test.yaml @@ -1,21 +1,25 @@ tests: - healthStatus: status: Progressing - message: "Waiting for ISBService status" - inputPath: testdata/progressing.yaml + message: "Not yet reconciled" + inputPath: testdata/ISBServiceRollout/progressing-observedgen.yaml - healthStatus: status: Healthy message: "Successful" - inputPath: testdata/healthy.yaml + inputPath: testdata/ISBServiceRollout/healthy.yaml - healthStatus: status: Degraded message: "ISBService Failed" - inputPath: testdata/degraded.yaml + inputPath: testdata/ISBServiceRollout/degraded.yaml - healthStatus: status: Progressing - message: "Waiting for ISBService status" - inputPath: testdata/progressing-nostatus.yaml + message: "Not yet reconciled" + inputPath: testdata/ISBServiceRollout/progressing-nostatus.yaml - healthStatus: status: Progressing - message: "Waiting for ISBService status" - inputPath: testdata/progressing-reason.yaml \ No newline at end of file + message: "Progressing" + inputPath: testdata/ISBServiceRollout/progressing-reason.yaml +- healthStatus: + status: Progressing + message: "Phase=Pending" + inputPath: testdata/ISBServiceRollout/pending-upgrade-in-progress.yaml \ No newline at end of file diff --git a/resource_customizations/numaplane.numaproj.io/ISBServiceRollout/testdata/degraded.yaml b/resource_customizations/numaplane.numaproj.io/ISBServiceRollout/testdata/ISBServiceRollout/degraded.yaml similarity index 100% rename from resource_customizations/numaplane.numaproj.io/ISBServiceRollout/testdata/degraded.yaml rename to resource_customizations/numaplane.numaproj.io/ISBServiceRollout/testdata/ISBServiceRollout/degraded.yaml diff --git a/resource_customizations/numaplane.numaproj.io/ISBServiceRollout/testdata/healthy.yaml b/resource_customizations/numaplane.numaproj.io/ISBServiceRollout/testdata/ISBServiceRollout/healthy.yaml similarity index 100% rename from resource_customizations/numaplane.numaproj.io/ISBServiceRollout/testdata/healthy.yaml rename to resource_customizations/numaplane.numaproj.io/ISBServiceRollout/testdata/ISBServiceRollout/healthy.yaml diff --git a/resource_customizations/numaplane.numaproj.io/ISBServiceRollout/testdata/ISBServiceRollout/pending-upgrade-in-progress.yaml b/resource_customizations/numaplane.numaproj.io/ISBServiceRollout/testdata/ISBServiceRollout/pending-upgrade-in-progress.yaml new file mode 100644 index 0000000000000..154c91cffffb3 --- /dev/null +++ b/resource_customizations/numaplane.numaproj.io/ISBServiceRollout/testdata/ISBServiceRollout/pending-upgrade-in-progress.yaml @@ -0,0 +1,40 @@ +apiVersion: numaplane.numaproj.io/v1alpha1 +kind: ISBServiceRollout +metadata: + annotations: + argocd.argoproj.io/sync-wave: '2' + kubectl.kubernetes.io/last-applied-configuration: > + {"apiVersion":"numaplane.numaproj.io/v1alpha1","kind":"ISBServiceRollout","metadata":{"annotations":{"argocd.argoproj.io/sync-wave":"2"},"labels":{"argocd.argoproj.io/instance":"demo-app"},"name":"my-isbsvc","namespace":"demo-app"},"spec":{"interStepBufferService":{"jetstream":{"persistence":{"volumeSize":"1Gi"},"version":"latest"}}}} + creationTimestamp: '2024-07-12T20:56:22Z' + finalizers: + - numaplane.numaproj.io/numaplane-controller + generation: 1 + labels: + argocd.argoproj.io/instance: demo-app + name: my-isbsvc + namespace: demo-app + resourceVersion: '5455982' + uid: 0a364143-ddfb-4bb8-9a61-b17b7954de4b +spec: + interStepBufferService: + jetstream: + persistence: + volumeSize: 1Gi + version: latest +status: + upgradeInProgress: 'progressive' + conditions: + - lastTransitionTime: '2024-07-12T20:56:23Z' + message: Successful + observedGeneration: 1 + reason: Successful + status: 'True' + type: ChildResourceDeployed + - lastTransitionTime: '2024-07-12T20:56:23Z' + message: Successful + observedGeneration: 1 + reason: Successful + status: 'True' + type: ChildResourcesHealthy + observedGeneration: 1 + phase: Pending \ No newline at end of file diff --git a/resource_customizations/numaplane.numaproj.io/ISBServiceRollout/testdata/progressing-nostatus.yaml b/resource_customizations/numaplane.numaproj.io/ISBServiceRollout/testdata/ISBServiceRollout/progressing-nostatus.yaml similarity index 100% rename from resource_customizations/numaplane.numaproj.io/ISBServiceRollout/testdata/progressing-nostatus.yaml rename to resource_customizations/numaplane.numaproj.io/ISBServiceRollout/testdata/ISBServiceRollout/progressing-nostatus.yaml diff --git a/resource_customizations/numaplane.numaproj.io/ISBServiceRollout/testdata/progressing.yaml b/resource_customizations/numaplane.numaproj.io/ISBServiceRollout/testdata/ISBServiceRollout/progressing-observedgen.yaml similarity index 100% rename from resource_customizations/numaplane.numaproj.io/ISBServiceRollout/testdata/progressing.yaml rename to resource_customizations/numaplane.numaproj.io/ISBServiceRollout/testdata/ISBServiceRollout/progressing-observedgen.yaml diff --git a/resource_customizations/numaplane.numaproj.io/ISBServiceRollout/testdata/progressing-reason.yaml b/resource_customizations/numaplane.numaproj.io/ISBServiceRollout/testdata/ISBServiceRollout/progressing-reason.yaml similarity index 100% rename from resource_customizations/numaplane.numaproj.io/ISBServiceRollout/testdata/progressing-reason.yaml rename to resource_customizations/numaplane.numaproj.io/ISBServiceRollout/testdata/ISBServiceRollout/progressing-reason.yaml diff --git a/resource_customizations/numaplane.numaproj.io/MonoVertexRollout/actions/action_test.yaml b/resource_customizations/numaplane.numaproj.io/MonoVertexRollout/actions/action_test.yaml index 13a1e7cdffc9f..516e32f793df5 100644 --- a/resource_customizations/numaplane.numaproj.io/MonoVertexRollout/actions/action_test.yaml +++ b/resource_customizations/numaplane.numaproj.io/MonoVertexRollout/actions/action_test.yaml @@ -1,7 +1,7 @@ actionTests: - action: pause - inputPath: testdata/rollout.yaml - expectedOutputPath: testdata/rollout-paused.yaml + inputPath: testdata/MonoVertexRollout/rollout.yaml + expectedOutputPath: testdata/MonoVertexRollout/rollout-paused.yaml - action: unpause - inputPath: testdata/rollout-paused.yaml - expectedOutputPath: testdata/rollout-running.yaml \ No newline at end of file + inputPath: testdata/MonoVertexRollout/rollout-paused.yaml + expectedOutputPath: testdata/MonoVertexRollout/rollout-running.yaml \ No newline at end of file diff --git a/resource_customizations/numaplane.numaproj.io/MonoVertexRollout/actions/testdata/rollout-paused.yaml b/resource_customizations/numaplane.numaproj.io/MonoVertexRollout/actions/testdata/MonoVertexRollout/rollout-paused.yaml similarity index 100% rename from resource_customizations/numaplane.numaproj.io/MonoVertexRollout/actions/testdata/rollout-paused.yaml rename to resource_customizations/numaplane.numaproj.io/MonoVertexRollout/actions/testdata/MonoVertexRollout/rollout-paused.yaml diff --git a/resource_customizations/numaplane.numaproj.io/MonoVertexRollout/actions/testdata/rollout-running.yaml b/resource_customizations/numaplane.numaproj.io/MonoVertexRollout/actions/testdata/MonoVertexRollout/rollout-running.yaml similarity index 100% rename from resource_customizations/numaplane.numaproj.io/MonoVertexRollout/actions/testdata/rollout-running.yaml rename to resource_customizations/numaplane.numaproj.io/MonoVertexRollout/actions/testdata/MonoVertexRollout/rollout-running.yaml diff --git a/resource_customizations/numaplane.numaproj.io/MonoVertexRollout/actions/testdata/rollout.yaml b/resource_customizations/numaplane.numaproj.io/MonoVertexRollout/actions/testdata/MonoVertexRollout/rollout.yaml similarity index 100% rename from resource_customizations/numaplane.numaproj.io/MonoVertexRollout/actions/testdata/rollout.yaml rename to resource_customizations/numaplane.numaproj.io/MonoVertexRollout/actions/testdata/MonoVertexRollout/rollout.yaml diff --git a/resource_customizations/numaplane.numaproj.io/MonoVertexRollout/health.lua b/resource_customizations/numaplane.numaproj.io/MonoVertexRollout/health.lua index 2e221a7323649..8ae7650e5cf2b 100644 --- a/resource_customizations/numaplane.numaproj.io/MonoVertexRollout/health.lua +++ b/resource_customizations/numaplane.numaproj.io/MonoVertexRollout/health.lua @@ -1,32 +1,66 @@ local hs = {} local healthyCondition = {} -if obj.status ~= nil then - if obj.status.conditions ~= nil then - for i, condition in ipairs(obj.status.conditions) do - if condition.type == "ChildResourcesHealthy" then - healthyCondition = condition - end - end - end +-- check for certain cases of "Progressing" + +if obj.status == nil then -- if there's no Status at all, we haven't been reconciled + hs.status = "Progressing" + hs.message = "Not yet reconciled" + return hs +end + +if obj.metadata.generation ~= obj.status.observedGeneration then + hs.status = "Progressing" + hs.message = "Not yet reconciled" + return hs +end + +if obj.status.phase == "Pending" then + hs.status = "Progressing" + hs.message = "Phase=Pending" + return hs +end + +if obj.status.upgradeInProgress ~= nil and obj.status.upgradeInProgress ~= "" then + hs.status = "Progressing" + hs.message = "Update in progress" + return hs +end - if obj.metadata.generation == obj.status.observedGeneration then - if (healthyCondition ~= {} and healthyCondition.status == "False" and (obj.metadata.generation == healthyCondition.observedGeneration) and healthyCondition.reason == "MonoVertexFailed") or obj.status.phase == "Failed" then - hs.status = "Degraded" - if obj.status.phase == "Failed" then - hs.message = obj.status.message - else - hs.message = healthyCondition.message - end - return hs - elseif healthyCondition ~= {} and healthyCondition.status == "True" and (obj.metadata.generation == healthyCondition.observedGeneration) and obj.status.phase == "Deployed" then - hs.status = "Healthy" - hs.message = healthyCondition.message - return hs + +-- now check the Conditions + +if obj.status.conditions ~= nil then + for i, condition in ipairs(obj.status.conditions) do + if condition.type == "ChildResourcesHealthy" then + healthyCondition = condition end end end -hs.status = "Progressing" -hs.message = "Waiting for MonoVertex status" + +if (healthyCondition ~= {} and healthyCondition.status == "False" and healthyCondition.reason == "MonoVertexFailed") or obj.status.phase == "Failed" then + hs.status = "Degraded" + if obj.status.phase == "Failed" then + hs.message = obj.status.message + else + hs.message = healthyCondition.message + end + return hs +elseif healthyCondition ~= {} and healthyCondition.status == "False" and healthyCondition.reason == "Progressing" then + hs.status = "Progressing" + hs.message = healthyCondition.message + return hs +elseif healthyCondition ~= {} and healthyCondition.status == "True" and obj.status.phase == "Deployed" then + hs.status = "Healthy" + hs.message = healthyCondition.message + return hs +end + + + + + +hs.status = "Unknown" +hs.message = "Unknown MonoVertex status" return hs \ No newline at end of file diff --git a/resource_customizations/numaplane.numaproj.io/MonoVertexRollout/health_test.yaml b/resource_customizations/numaplane.numaproj.io/MonoVertexRollout/health_test.yaml index aee12b9ceb9c3..82a52ec141c23 100644 --- a/resource_customizations/numaplane.numaproj.io/MonoVertexRollout/health_test.yaml +++ b/resource_customizations/numaplane.numaproj.io/MonoVertexRollout/health_test.yaml @@ -1,17 +1,21 @@ tests: - healthStatus: status: Progressing - message: "Waiting for MonoVertex status" - inputPath: testdata/progressing.yaml + message: "Not yet reconciled" + inputPath: testdata/MonoVertexRollout/progressing-observedgen.yaml - healthStatus: status: Healthy message: "Successful" - inputPath: testdata/healthy.yaml + inputPath: testdata/MonoVertexRollout/healthy.yaml - healthStatus: status: Degraded message: "MonoVertex Failed" - inputPath: testdata/degraded.yaml + inputPath: testdata/MonoVertexRollout/degraded.yaml - healthStatus: status: Progressing - message: "Waiting for MonoVertex status" - inputPath: testdata/progressing-reason.yaml \ No newline at end of file + message: "Progressing" + inputPath: testdata/MonoVertexRollout/progressing-reason.yaml +- healthStatus: + status: Progressing + message: "Phase=Pending" + inputPath: testdata/MonoVertexRollout/pending-upgrade-in-progress.yaml \ No newline at end of file diff --git a/resource_customizations/numaplane.numaproj.io/MonoVertexRollout/testdata/degraded.yaml b/resource_customizations/numaplane.numaproj.io/MonoVertexRollout/testdata/MonoVertexRollout/degraded.yaml similarity index 100% rename from resource_customizations/numaplane.numaproj.io/MonoVertexRollout/testdata/degraded.yaml rename to resource_customizations/numaplane.numaproj.io/MonoVertexRollout/testdata/MonoVertexRollout/degraded.yaml diff --git a/resource_customizations/numaplane.numaproj.io/MonoVertexRollout/testdata/healthy.yaml b/resource_customizations/numaplane.numaproj.io/MonoVertexRollout/testdata/MonoVertexRollout/healthy.yaml similarity index 100% rename from resource_customizations/numaplane.numaproj.io/MonoVertexRollout/testdata/healthy.yaml rename to resource_customizations/numaplane.numaproj.io/MonoVertexRollout/testdata/MonoVertexRollout/healthy.yaml diff --git a/resource_customizations/numaplane.numaproj.io/MonoVertexRollout/testdata/MonoVertexRollout/pending-upgrade-in-progress.yaml b/resource_customizations/numaplane.numaproj.io/MonoVertexRollout/testdata/MonoVertexRollout/pending-upgrade-in-progress.yaml new file mode 100644 index 0000000000000..ac7e35bd71928 --- /dev/null +++ b/resource_customizations/numaplane.numaproj.io/MonoVertexRollout/testdata/MonoVertexRollout/pending-upgrade-in-progress.yaml @@ -0,0 +1,47 @@ +apiVersion: numaplane.numaproj.io/v1alpha1 +kind: MonoVertexRollout +metadata: + annotations: + kubectl.kubernetes.io/last-applied-configuration: > + {"apiVersion":"numaplane.numaproj.io/v1alpha1","kind":"MonoVertexRollout","metadata":{"annotations":{},"labels":{"argocd.argoproj.io/instance":"demo-app"},"name":"my-monovertex","namespace":"example-namespace"},"spec":{"monoVertex":{"spec":{"sink":{"udsink":{"container":{"image":"quay.io/numaio/numaflow-java/simple-sink:stable"}}},"source":{"transformer":{"container":{"image":"quay.io/numaio/numaflow-rs/source-transformer-now:stable"}},"udsource":{"container":{"image":"quay.io/numaio/numaflow-java/source-simple-source:stable"}}}}}}} + creationTimestamp: '2024-08-21T20:44:18Z' + finalizers: + - numaplane.numaproj.io/numaplane-controller + generation: 1 + labels: + argocd.argoproj.io/instance: demo-app + name: my-monovertex + namespace: example-namespace + resourceVersion: '947414' + uid: a63f377e-1500-437e-9267-579f4a790518 +spec: + monoVertex: + spec: + sink: + udsink: + container: + image: 'quay.io/numaio/numaflow-java/simple-sink:stable' + source: + transformer: + container: + image: 'quay.io/numaio/numaflow-rs/source-transformer-now:stable' + udsource: + container: + image: 'quay.io/numaio/numaflow-java/source-simple-source:stable' +status: + upgradeInProgress: progressive + conditions: + - lastTransitionTime: '2024-08-21T20:44:18Z' + message: Successful + observedGeneration: 1 + reason: Successful + status: 'True' + type: ChildResourceDeployed + - lastTransitionTime: '2024-08-22T21:10:23Z' + message: Successful + observedGeneration: 1 + reason: Successful + status: 'True' + type: ChildResourcesHealthy + observedGeneration: 1 + phase: Pending \ No newline at end of file diff --git a/resource_customizations/numaplane.numaproj.io/MonoVertexRollout/testdata/progressing.yaml b/resource_customizations/numaplane.numaproj.io/MonoVertexRollout/testdata/MonoVertexRollout/progressing-observedgen.yaml similarity index 100% rename from resource_customizations/numaplane.numaproj.io/MonoVertexRollout/testdata/progressing.yaml rename to resource_customizations/numaplane.numaproj.io/MonoVertexRollout/testdata/MonoVertexRollout/progressing-observedgen.yaml diff --git a/resource_customizations/numaplane.numaproj.io/MonoVertexRollout/testdata/progressing-reason.yaml b/resource_customizations/numaplane.numaproj.io/MonoVertexRollout/testdata/MonoVertexRollout/progressing-reason.yaml similarity index 100% rename from resource_customizations/numaplane.numaproj.io/MonoVertexRollout/testdata/progressing-reason.yaml rename to resource_customizations/numaplane.numaproj.io/MonoVertexRollout/testdata/MonoVertexRollout/progressing-reason.yaml diff --git a/resource_customizations/numaplane.numaproj.io/NumaflowControllerRollout/health.lua b/resource_customizations/numaplane.numaproj.io/NumaflowControllerRollout/health.lua index 9ff005740f6e8..4975882d7dea6 100644 --- a/resource_customizations/numaplane.numaproj.io/NumaflowControllerRollout/health.lua +++ b/resource_customizations/numaplane.numaproj.io/NumaflowControllerRollout/health.lua @@ -1,32 +1,61 @@ local hs = {} local healthyCondition = {} -if obj.status ~= nil then - if obj.status.conditions ~= nil then - for i, condition in ipairs(obj.status.conditions) do - if condition.type == "ChildResourcesHealthy" then - healthyCondition = condition - end +-- check for certain cases of "Progressing" + +if obj.status == nil then -- if there's no Status at all, we haven't been reconciled + hs.status = "Progressing" + hs.message = "Not yet reconciled" + return hs +end + +if obj.metadata.generation ~= obj.status.observedGeneration then + hs.status = "Progressing" + hs.message = "Not yet reconciled" + return hs +end + +if obj.status.phase == "Pending" then + hs.status = "Progressing" + hs.message = "Phase=Pending" + return hs +end + +if obj.status.upgradeInProgress ~= nil and obj.status.upgradeInProgress ~= "" then + hs.status = "Progressing" + hs.message = "Update in progress" + return hs +end + + -- now check the Conditions + +if obj.status.conditions ~= nil then + for i, condition in ipairs(obj.status.conditions) do + if condition.type == "ChildResourcesHealthy" then + healthyCondition = condition end end +end - if obj.metadata.generation == obj.status.observedGeneration then - if (healthyCondition ~= {} and healthyCondition.status == "False" and (obj.metadata.generation == healthyCondition.observedGeneration) and healthyCondition.reason == "Degraded") or obj.status.phase == "Failed" then - hs.status = "Degraded" - if obj.status.phase == "Failed" then - hs.message = obj.status.message - else - hs.message = healthyCondition.message - end - return hs - elseif healthyCondition ~= {} and healthyCondition.status == "True" and (obj.metadata.generation == healthyCondition.observedGeneration) and obj.status.phase == "Deployed" then - hs.status = "Healthy" - hs.message = healthyCondition.message - return hs - end + +if (healthyCondition ~= {} and healthyCondition.status == "False" and healthyCondition.reason == "Degraded") or obj.status.phase == "Failed" then + hs.status = "Degraded" + if obj.status.phase == "Failed" then + hs.message = obj.status.message + else + hs.message = healthyCondition.message end + return hs +elseif healthyCondition ~= {} and healthyCondition.status == "False" and healthyCondition.reason == "Progressing" then + hs.status = "Progressing" + hs.message = healthyCondition.message + return hs +elseif healthyCondition ~= {} and healthyCondition.status == "True" and obj.status.phase == "Deployed" then + hs.status = "Healthy" + hs.message = healthyCondition.message + return hs end -hs.status = "Progressing" -hs.message = "Waiting for NumaflowController status" +hs.status = "Unknown" +hs.message = "Unknown NumaflowController status" return hs \ No newline at end of file diff --git a/resource_customizations/numaplane.numaproj.io/NumaflowControllerRollout/health_test.yaml b/resource_customizations/numaplane.numaproj.io/NumaflowControllerRollout/health_test.yaml index 30bb880f2d38a..ef2778da7dc2b 100644 --- a/resource_customizations/numaplane.numaproj.io/NumaflowControllerRollout/health_test.yaml +++ b/resource_customizations/numaplane.numaproj.io/NumaflowControllerRollout/health_test.yaml @@ -1,17 +1,21 @@ tests: - healthStatus: status: Progressing - message: "Waiting for NumaflowController status" - inputPath: testdata/progressing.yaml + message: "Not yet reconciled" + inputPath: testdata/NumaflowControllerRollout/progressing-observedgen.yaml - healthStatus: status: Healthy message: "Successful" - inputPath: testdata/healthy.yaml + inputPath: testdata/NumaflowControllerRollout/healthy.yaml - healthStatus: status: Degraded message: "no controller definition found for version degraded" - inputPath: testdata/degraded.yaml + inputPath: testdata/NumaflowControllerRollout/degraded.yaml - healthStatus: status: Progressing - message: "Waiting for NumaflowController status" - inputPath: testdata/progressing-reason.yaml \ No newline at end of file + message: "Progressing" + inputPath: testdata/NumaflowControllerRollout/progressing-reason.yaml +- healthStatus: + status: Progressing + message: "Phase=Pending" + inputPath: testdata/NumaflowControllerRollout/pending.yaml \ No newline at end of file diff --git a/resource_customizations/numaplane.numaproj.io/NumaflowControllerRollout/testdata/degraded.yaml b/resource_customizations/numaplane.numaproj.io/NumaflowControllerRollout/testdata/NumaflowControllerRollout/degraded.yaml similarity index 100% rename from resource_customizations/numaplane.numaproj.io/NumaflowControllerRollout/testdata/degraded.yaml rename to resource_customizations/numaplane.numaproj.io/NumaflowControllerRollout/testdata/NumaflowControllerRollout/degraded.yaml diff --git a/resource_customizations/numaplane.numaproj.io/NumaflowControllerRollout/testdata/healthy.yaml b/resource_customizations/numaplane.numaproj.io/NumaflowControllerRollout/testdata/NumaflowControllerRollout/healthy.yaml similarity index 100% rename from resource_customizations/numaplane.numaproj.io/NumaflowControllerRollout/testdata/healthy.yaml rename to resource_customizations/numaplane.numaproj.io/NumaflowControllerRollout/testdata/NumaflowControllerRollout/healthy.yaml diff --git a/resource_customizations/numaplane.numaproj.io/NumaflowControllerRollout/testdata/NumaflowControllerRollout/pending.yaml b/resource_customizations/numaplane.numaproj.io/NumaflowControllerRollout/testdata/NumaflowControllerRollout/pending.yaml new file mode 100644 index 0000000000000..ba49dbc42d844 --- /dev/null +++ b/resource_customizations/numaplane.numaproj.io/NumaflowControllerRollout/testdata/NumaflowControllerRollout/pending.yaml @@ -0,0 +1,36 @@ +apiVersion: numaplane.numaproj.io/v1alpha1 +kind: NumaflowControllerRollout +metadata: + annotations: + argocd.argoproj.io/sync-wave: '1' + kubectl.kubernetes.io/last-applied-configuration: > + {"apiVersion":"numaplane.numaproj.io/v1alpha1","kind":"NumaflowControllerRollout","metadata":{"annotations":{"argocd.argoproj.io/sync-wave":"1"},"labels":{"argocd.argoproj.io/instance":"demo-app"},"name":"numaflow-controller","namespace":"demo-app"},"spec":{"controller":{"version":"1.2.1"}}} + creationTimestamp: '2024-07-12T20:56:20Z' + finalizers: + - numaplane.numaproj.io/numaplane-controller + generation: 1 + labels: + argocd.argoproj.io/instance: demo-app + name: numaflow-controller + namespace: demo-app + resourceVersion: '5456204' + uid: 904ab9bb-953e-4979-a124-5c92e8e25147 +spec: + controller: + version: 1.2.1 +status: + conditions: + - lastTransitionTime: '2024-07-12T20:56:26Z' + message: Successful + observedGeneration: 1 + reason: Successful + status: 'True' + type: ChildResourceDeployed + - lastTransitionTime: '2024-07-12T20:56:26Z' + message: Successful + observedGeneration: 1 + reason: Successful + status: 'True' + type: ChildResourcesHealthy + observedGeneration: 1 + phase: Pending diff --git a/resource_customizations/numaplane.numaproj.io/NumaflowControllerRollout/testdata/progressing.yaml b/resource_customizations/numaplane.numaproj.io/NumaflowControllerRollout/testdata/NumaflowControllerRollout/progressing-observedgen.yaml similarity index 100% rename from resource_customizations/numaplane.numaproj.io/NumaflowControllerRollout/testdata/progressing.yaml rename to resource_customizations/numaplane.numaproj.io/NumaflowControllerRollout/testdata/NumaflowControllerRollout/progressing-observedgen.yaml diff --git a/resource_customizations/numaplane.numaproj.io/NumaflowControllerRollout/testdata/progressing-reason.yaml b/resource_customizations/numaplane.numaproj.io/NumaflowControllerRollout/testdata/NumaflowControllerRollout/progressing-reason.yaml similarity index 100% rename from resource_customizations/numaplane.numaproj.io/NumaflowControllerRollout/testdata/progressing-reason.yaml rename to resource_customizations/numaplane.numaproj.io/NumaflowControllerRollout/testdata/NumaflowControllerRollout/progressing-reason.yaml diff --git a/resource_customizations/numaplane.numaproj.io/PipelineRollout/actions/action_test.yaml b/resource_customizations/numaplane.numaproj.io/PipelineRollout/actions/action_test.yaml index 6dbc5b4c90f03..b9652682b8c59 100644 --- a/resource_customizations/numaplane.numaproj.io/PipelineRollout/actions/action_test.yaml +++ b/resource_customizations/numaplane.numaproj.io/PipelineRollout/actions/action_test.yaml @@ -1,13 +1,13 @@ actionTests: - action: pause - inputPath: testdata/rollout.yaml - expectedOutputPath: testdata/rollout-paused.yaml + inputPath: testdata/PipelineRollout/rollout.yaml + expectedOutputPath: testdata/PipelineRollout/rollout-paused.yaml - action: unpause - inputPath: testdata/rollout-paused.yaml - expectedOutputPath: testdata/rollout-running.yaml + inputPath: testdata/PipelineRollout/rollout-paused.yaml + expectedOutputPath: testdata/PipelineRollout/rollout-running.yaml - action: allow-data-loss - inputPath: testdata/rollout-in-ppnd.yaml - expectedOutputPath: testdata/rollout-allowing-data-loss.yaml + inputPath: testdata/PipelineRollout/rollout-in-ppnd.yaml + expectedOutputPath: testdata/PipelineRollout/rollout-allowing-data-loss.yaml - action: disallow-data-loss - inputPath: testdata/rollout-allowing-data-loss.yaml - expectedOutputPath: testdata/rollout-disallowing-data-loss.yaml \ No newline at end of file + inputPath: testdata/PipelineRollout/rollout-allowing-data-loss.yaml + expectedOutputPath: testdata/PipelineRollout/rollout-disallowing-data-loss.yaml \ No newline at end of file diff --git a/resource_customizations/numaplane.numaproj.io/PipelineRollout/actions/testdata/rollout-allowing-data-loss.yaml b/resource_customizations/numaplane.numaproj.io/PipelineRollout/actions/testdata/PipelineRollout/rollout-allowing-data-loss.yaml similarity index 100% rename from resource_customizations/numaplane.numaproj.io/PipelineRollout/actions/testdata/rollout-allowing-data-loss.yaml rename to resource_customizations/numaplane.numaproj.io/PipelineRollout/actions/testdata/PipelineRollout/rollout-allowing-data-loss.yaml diff --git a/resource_customizations/numaplane.numaproj.io/PipelineRollout/actions/testdata/rollout-disallowing-data-loss.yaml b/resource_customizations/numaplane.numaproj.io/PipelineRollout/actions/testdata/PipelineRollout/rollout-disallowing-data-loss.yaml similarity index 100% rename from resource_customizations/numaplane.numaproj.io/PipelineRollout/actions/testdata/rollout-disallowing-data-loss.yaml rename to resource_customizations/numaplane.numaproj.io/PipelineRollout/actions/testdata/PipelineRollout/rollout-disallowing-data-loss.yaml diff --git a/resource_customizations/numaplane.numaproj.io/PipelineRollout/actions/testdata/rollout-in-ppnd.yaml b/resource_customizations/numaplane.numaproj.io/PipelineRollout/actions/testdata/PipelineRollout/rollout-in-ppnd.yaml similarity index 100% rename from resource_customizations/numaplane.numaproj.io/PipelineRollout/actions/testdata/rollout-in-ppnd.yaml rename to resource_customizations/numaplane.numaproj.io/PipelineRollout/actions/testdata/PipelineRollout/rollout-in-ppnd.yaml diff --git a/resource_customizations/numaplane.numaproj.io/PipelineRollout/actions/testdata/rollout-paused.yaml b/resource_customizations/numaplane.numaproj.io/PipelineRollout/actions/testdata/PipelineRollout/rollout-paused.yaml similarity index 100% rename from resource_customizations/numaplane.numaproj.io/PipelineRollout/actions/testdata/rollout-paused.yaml rename to resource_customizations/numaplane.numaproj.io/PipelineRollout/actions/testdata/PipelineRollout/rollout-paused.yaml diff --git a/resource_customizations/numaplane.numaproj.io/PipelineRollout/actions/testdata/rollout-running.yaml b/resource_customizations/numaplane.numaproj.io/PipelineRollout/actions/testdata/PipelineRollout/rollout-running.yaml similarity index 100% rename from resource_customizations/numaplane.numaproj.io/PipelineRollout/actions/testdata/rollout-running.yaml rename to resource_customizations/numaplane.numaproj.io/PipelineRollout/actions/testdata/PipelineRollout/rollout-running.yaml diff --git a/resource_customizations/numaplane.numaproj.io/PipelineRollout/actions/testdata/rollout.yaml b/resource_customizations/numaplane.numaproj.io/PipelineRollout/actions/testdata/PipelineRollout/rollout.yaml similarity index 100% rename from resource_customizations/numaplane.numaproj.io/PipelineRollout/actions/testdata/rollout.yaml rename to resource_customizations/numaplane.numaproj.io/PipelineRollout/actions/testdata/PipelineRollout/rollout.yaml diff --git a/resource_customizations/numaplane.numaproj.io/PipelineRollout/health.lua b/resource_customizations/numaplane.numaproj.io/PipelineRollout/health.lua index 649cbb643d7f9..2fa58a94b0bfe 100644 --- a/resource_customizations/numaplane.numaproj.io/PipelineRollout/health.lua +++ b/resource_customizations/numaplane.numaproj.io/PipelineRollout/health.lua @@ -2,39 +2,68 @@ local hs = {} local healthyCondition = {} local pipelinePaused = {} -if obj.status ~= nil then - if obj.status.conditions ~= nil then - for i, condition in ipairs(obj.status.conditions) do - if condition.type == "ChildResourcesHealthy" then - healthyCondition = condition - end - if condition.type == "PipelinePausingOrPaused" then - pipelinePaused = condition - end +-- check for certain cases of "Progressing" + +if obj.status == nil then -- if there's no Status at all, we haven't been reconciled + hs.status = "Progressing" + hs.message = "Not yet reconciled" + return hs +end + +if obj.metadata.generation ~= obj.status.observedGeneration then + hs.status = "Progressing" + hs.message = "Not yet reconciled" + return hs +end + +if obj.status.phase == "Pending" then + hs.status = "Progressing" + hs.message = "Phase=Pending" + return hs +end + +if obj.status.upgradeInProgress ~= nil and obj.status.upgradeInProgress ~= "" then + hs.status = "Progressing" + hs.message = "Update in progress" + return hs +end + +-- now check the Conditions + +if obj.status.conditions ~= nil then + for i, condition in ipairs(obj.status.conditions) do + if condition.type == "ChildResourcesHealthy" then + healthyCondition = condition + end + if condition.type == "PipelinePausingOrPaused" then + pipelinePaused = condition end end +end - if obj.metadata.generation == obj.status.observedGeneration then - if (healthyCondition ~= {} and healthyCondition.status == "False" and (obj.metadata.generation == healthyCondition.observedGeneration) and healthyCondition.reason == "PipelineFailed") or obj.status.phase == "Failed" then - hs.status = "Degraded" - if obj.status.phase == "Failed" then - hs.message = obj.status.message - else - hs.message = healthyCondition.message - end - return hs - elseif (pipelinePaused ~= {} and pipelinePaused.status == "True") and (obj.metadata.generation == pipelinePaused.observedGeneration) then - hs.status = "Suspended" - hs.message = pipelinePaused.message - return hs - elseif (healthyCondition ~= {} and healthyCondition.status == "True") and (obj.metadata.generation == healthyCondition.observedGeneration) and obj.status.phase == "Deployed" then - hs.status = "Healthy" - hs.message = healthyCondition.message - return hs - end + +if (healthyCondition ~= {} and healthyCondition.status == "False" and healthyCondition.reason == "PipelineFailed") or obj.status.phase == "Failed" then + hs.status = "Degraded" + if obj.status.phase == "Failed" then + hs.message = obj.status.message + else + hs.message = healthyCondition.message end + return hs +elseif healthyCondition ~= {} and healthyCondition.status == "False" and healthyCondition.reason == "Progressing" then + hs.status = "Progressing" + hs.message = healthyCondition.message + return hs +elseif (pipelinePaused ~= {} and pipelinePaused.status == "True") then + hs.status = "Suspended" + hs.message = pipelinePaused.message + return hs +elseif (healthyCondition ~= {} and healthyCondition.status == "True") and obj.status.phase == "Deployed" then + hs.status = "Healthy" + hs.message = healthyCondition.message + return hs end -hs.status = "Progressing" -hs.message = "Waiting for Pipeline status" +hs.status = "Unknown" +hs.message = "Unknown Pipeline status" return hs \ No newline at end of file diff --git a/resource_customizations/numaplane.numaproj.io/PipelineRollout/health_test.yaml b/resource_customizations/numaplane.numaproj.io/PipelineRollout/health_test.yaml index 99274d213992b..3ff01e4435656 100644 --- a/resource_customizations/numaplane.numaproj.io/PipelineRollout/health_test.yaml +++ b/resource_customizations/numaplane.numaproj.io/PipelineRollout/health_test.yaml @@ -1,21 +1,25 @@ tests: - healthStatus: status: Progressing - message: "Waiting for Pipeline status" - inputPath: testdata/progressing.yaml + message: "Not yet reconciled" + inputPath: testdata/PipelineRollout/progressing-observedGen.yaml - healthStatus: status: Healthy message: "Successful" - inputPath: testdata/healthy.yaml + inputPath: testdata/PipelineRollout/healthy.yaml - healthStatus: status: Suspended message: "Pipeline paused" - inputPath: testdata/paused.yaml + inputPath: testdata/PipelineRollout/paused.yaml - healthStatus: status: Degraded message: "Pipeline Failed" - inputPath: testdata/degraded.yaml + inputPath: testdata/PipelineRollout/degraded.yaml - healthStatus: status: Progressing - message: "Waiting for Pipeline status" - inputPath: testdata/progressing-reason.yaml \ No newline at end of file + message: "Progressing" + inputPath: testdata/PipelineRollout/progressing-reason.yaml +- healthStatus: + status: Progressing + message: "Phase=Pending" + inputPath: testdata/PipelineRollout/pending-upgrade-in-progress.yaml \ No newline at end of file diff --git a/resource_customizations/numaplane.numaproj.io/PipelineRollout/testdata/degraded.yaml b/resource_customizations/numaplane.numaproj.io/PipelineRollout/testdata/PipelineRollout/degraded.yaml similarity index 100% rename from resource_customizations/numaplane.numaproj.io/PipelineRollout/testdata/degraded.yaml rename to resource_customizations/numaplane.numaproj.io/PipelineRollout/testdata/PipelineRollout/degraded.yaml diff --git a/resource_customizations/numaplane.numaproj.io/PipelineRollout/testdata/healthy.yaml b/resource_customizations/numaplane.numaproj.io/PipelineRollout/testdata/PipelineRollout/healthy.yaml similarity index 100% rename from resource_customizations/numaplane.numaproj.io/PipelineRollout/testdata/healthy.yaml rename to resource_customizations/numaplane.numaproj.io/PipelineRollout/testdata/PipelineRollout/healthy.yaml diff --git a/resource_customizations/numaplane.numaproj.io/PipelineRollout/testdata/paused.yaml b/resource_customizations/numaplane.numaproj.io/PipelineRollout/testdata/PipelineRollout/paused.yaml similarity index 100% rename from resource_customizations/numaplane.numaproj.io/PipelineRollout/testdata/paused.yaml rename to resource_customizations/numaplane.numaproj.io/PipelineRollout/testdata/PipelineRollout/paused.yaml diff --git a/resource_customizations/numaplane.numaproj.io/PipelineRollout/testdata/PipelineRollout/pending-upgrade-in-progress.yaml b/resource_customizations/numaplane.numaproj.io/PipelineRollout/testdata/PipelineRollout/pending-upgrade-in-progress.yaml new file mode 100644 index 0000000000000..2731f79aeb9de --- /dev/null +++ b/resource_customizations/numaplane.numaproj.io/PipelineRollout/testdata/PipelineRollout/pending-upgrade-in-progress.yaml @@ -0,0 +1,60 @@ +apiVersion: numaplane.numaproj.io/v1alpha1 +kind: PipelineRollout +metadata: + annotations: + argocd.argoproj.io/sync-wave: '3' + kubectl.kubernetes.io/last-applied-configuration: > + {"apiVersion":"numaplane.numaproj.io/v1alpha1","kind":"PipelineRollout","metadata":{"annotations":{"argocd.argoproj.io/sync-wave":"3"},"labels":{"argocd.argoproj.io/instance":"demo-app"},"name":"my-other-pipeline","namespace":"demo-app"},"spec":{"pipeline":{"edges":[{"from":"in","to":"cat"},{"from":"cat","to":"out"},{"from":"cat","to":"out2"}],"interStepBufferServiceName":"my-isbsvc","vertices":[{"name":"in","source":{"generator":{"duration":"15s","rpu":5}}},{"name":"cat","udf":{"builtin":{"name":"cat"}}},{"name":"out","sink":{"log":{}}},{"name":"out2","sink":{"log":{}}}]}}} + creationTimestamp: '2024-07-12T20:56:24Z' + finalizers: + - numaplane.numaproj.io/numaplane-controller + generation: 1 + labels: + argocd.argoproj.io/instance: demo-app + name: my-other-pipeline + namespace: demo-app + resourceVersion: '5456110' + uid: 472d6284-b2d9-45ee-a159-fd4c3ad08d8c +spec: + pipeline: + edges: + - from: in + to: cat + - from: cat + to: out + - from: cat + to: out2 + interStepBufferServiceName: my-isbsvc + vertices: + - name: in + source: + generator: + duration: 15s + rpu: 5 + - name: cat + udf: + builtin: + name: cat + - name: out + sink: + log: {} + - name: out2 + sink: + log: {} +status: + upgradeInProgress: 'progressive' + conditions: + - lastTransitionTime: '2024-07-12T20:56:24Z' + message: Successful + observedGeneration: 1 + reason: Successful + status: 'True' + type: ChildResourceDeployed + - lastTransitionTime: '2024-07-12T20:56:24Z' + message: Successful + observedGeneration: 1 + reason: Successful + status: 'True' + type: ChildResourcesHealthy + observedGeneration: 1 + phase: Pending \ No newline at end of file diff --git a/resource_customizations/numaplane.numaproj.io/PipelineRollout/testdata/progressing.yaml b/resource_customizations/numaplane.numaproj.io/PipelineRollout/testdata/PipelineRollout/progressing-observedGen.yaml similarity index 100% rename from resource_customizations/numaplane.numaproj.io/PipelineRollout/testdata/progressing.yaml rename to resource_customizations/numaplane.numaproj.io/PipelineRollout/testdata/PipelineRollout/progressing-observedGen.yaml diff --git a/resource_customizations/numaplane.numaproj.io/PipelineRollout/testdata/progressing-reason.yaml b/resource_customizations/numaplane.numaproj.io/PipelineRollout/testdata/PipelineRollout/progressing-reason.yaml similarity index 100% rename from resource_customizations/numaplane.numaproj.io/PipelineRollout/testdata/progressing-reason.yaml rename to resource_customizations/numaplane.numaproj.io/PipelineRollout/testdata/PipelineRollout/progressing-reason.yaml From 73fbcc9ce4df743f119dfe1606fc6bc27844fe7d Mon Sep 17 00:00:00 2001 From: Chirag Jain Date: Wed, 30 Oct 2024 01:12:01 +0530 Subject: [PATCH 05/14] chore: add bajaj finserv health ltd. in list of users (#20555) Signed-off-by: Chirag Jain --- USERS.md | 1 + 1 file changed, 1 insertion(+) diff --git a/USERS.md b/USERS.md index 14281df77c425..ae939c5477b47 100644 --- a/USERS.md +++ b/USERS.md @@ -35,6 +35,7 @@ Currently, the following organizations are **officially** using Argo CD: 1. [Axians ACSP](https://www.axians.fr) 1. [Axual B.V.](https://axual.com) 1. [Back Market](https://www.backmarket.com) +1. [Bajaj Finserv Health Ltd.](https://www.bajajfinservhealth.in) 1. [Baloise](https://www.baloise.com) 1. [BCDevExchange DevOps Platform](https://bcdevexchange.org/DevOpsPlatform) 1. [Beat](https://thebeat.co/en/) From 683d0308431237f2c8c5b0fc2671caa1abfc6692 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 29 Oct 2024 20:37:38 +0000 Subject: [PATCH 06/14] chore(deps): bump actions/setup-node from 4.0.4 to 4.1.0 (#20528) Bumps [actions/setup-node](https://github.com/actions/setup-node) from 4.0.4 to 4.1.0. - [Release notes](https://github.com/actions/setup-node/releases) - [Commits](https://github.com/actions/setup-node/compare/0a44ba7841725637a19e28fa30b79a866c81b0a6...39370e3970a6d050c480ffad4ff0ed4d3fdee5af) --- updated-dependencies: - dependency-name: actions/setup-node dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/ci-build.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci-build.yaml b/.github/workflows/ci-build.yaml index 24ac70a0283c7..bc7962c69103f 100644 --- a/.github/workflows/ci-build.yaml +++ b/.github/workflows/ci-build.yaml @@ -305,7 +305,7 @@ jobs: - name: Checkout code uses: actions/checkout@8410ad0602e1e429cee44a835ae9f77f654a6694 # v4.0.0 - name: Setup NodeJS - uses: actions/setup-node@0a44ba7841725637a19e28fa30b79a866c81b0a6 # v4.0.4 + uses: actions/setup-node@39370e3970a6d050c480ffad4ff0ed4d3fdee5af # v4.1.0 with: # renovate: datasource=node-version packageName=node versioning=node node-version: '22.9.0' From bb1e75fe824ebdec361d1df14a826e98f4bb7162 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 29 Oct 2024 20:40:35 +0000 Subject: [PATCH 07/14] chore(deps): bump actions/setup-go from 5.0.2 to 5.1.0 (#20529) Bumps [actions/setup-go](https://github.com/actions/setup-go) from 5.0.2 to 5.1.0. - [Release notes](https://github.com/actions/setup-go/releases) - [Commits](https://github.com/actions/setup-go/compare/0a12ed9d6a96ab950c8f026ed9f722fe0da7ef32...41dfa10bad2bb2ae585af6ee5bb4d7d973ad74ed) --- updated-dependencies: - dependency-name: actions/setup-go dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/ci-build.yaml | 14 +++++++------- .github/workflows/codeql.yml | 2 +- .github/workflows/image-reuse.yaml | 2 +- .github/workflows/release.yaml | 4 ++-- 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/.github/workflows/ci-build.yaml b/.github/workflows/ci-build.yaml index bc7962c69103f..7cc2476fc185c 100644 --- a/.github/workflows/ci-build.yaml +++ b/.github/workflows/ci-build.yaml @@ -57,7 +57,7 @@ jobs: - name: Checkout code uses: actions/checkout@8410ad0602e1e429cee44a835ae9f77f654a6694 # v4.0.0 - name: Setup Golang - uses: actions/setup-go@0a12ed9d6a96ab950c8f026ed9f722fe0da7ef32 # v5.0.2 + uses: actions/setup-go@41dfa10bad2bb2ae585af6ee5bb4d7d973ad74ed # v5.1.0 with: go-version: ${{ env.GOLANG_VERSION }} - name: Download all Go modules @@ -78,7 +78,7 @@ jobs: - name: Checkout code uses: actions/checkout@8410ad0602e1e429cee44a835ae9f77f654a6694 # v4.0.0 - name: Setup Golang - uses: actions/setup-go@0a12ed9d6a96ab950c8f026ed9f722fe0da7ef32 # v5.0.2 + uses: actions/setup-go@41dfa10bad2bb2ae585af6ee5bb4d7d973ad74ed # v5.1.0 with: go-version: ${{ env.GOLANG_VERSION }} - name: Restore go build cache @@ -105,7 +105,7 @@ jobs: - name: Checkout code uses: actions/checkout@8410ad0602e1e429cee44a835ae9f77f654a6694 # v4.0.0 - name: Setup Golang - uses: actions/setup-go@0a12ed9d6a96ab950c8f026ed9f722fe0da7ef32 # v5.0.2 + uses: actions/setup-go@41dfa10bad2bb2ae585af6ee5bb4d7d973ad74ed # v5.1.0 with: go-version: ${{ env.GOLANG_VERSION }} - name: Run golangci-lint @@ -133,7 +133,7 @@ jobs: - name: Create symlink in GOPATH run: ln -s $(pwd) ~/go/src/github.com/argoproj/argo-cd - name: Setup Golang - uses: actions/setup-go@0a12ed9d6a96ab950c8f026ed9f722fe0da7ef32 # v5.0.2 + uses: actions/setup-go@41dfa10bad2bb2ae585af6ee5bb4d7d973ad74ed # v5.1.0 with: go-version: ${{ env.GOLANG_VERSION }} - name: Install required packages @@ -197,7 +197,7 @@ jobs: - name: Create symlink in GOPATH run: ln -s $(pwd) ~/go/src/github.com/argoproj/argo-cd - name: Setup Golang - uses: actions/setup-go@0a12ed9d6a96ab950c8f026ed9f722fe0da7ef32 # v5.0.2 + uses: actions/setup-go@41dfa10bad2bb2ae585af6ee5bb4d7d973ad74ed # v5.1.0 with: go-version: ${{ env.GOLANG_VERSION }} - name: Install required packages @@ -253,7 +253,7 @@ jobs: - name: Checkout code uses: actions/checkout@8410ad0602e1e429cee44a835ae9f77f654a6694 # v4.0.0 - name: Setup Golang - uses: actions/setup-go@0a12ed9d6a96ab950c8f026ed9f722fe0da7ef32 # v5.0.2 + uses: actions/setup-go@41dfa10bad2bb2ae585af6ee5bb4d7d973ad74ed # v5.1.0 with: go-version: ${{ env.GOLANG_VERSION }} - name: Create symlink in GOPATH @@ -432,7 +432,7 @@ jobs: - name: Checkout code uses: actions/checkout@8410ad0602e1e429cee44a835ae9f77f654a6694 # v4.0.0 - name: Setup Golang - uses: actions/setup-go@0a12ed9d6a96ab950c8f026ed9f722fe0da7ef32 # v5.0.2 + uses: actions/setup-go@41dfa10bad2bb2ae585af6ee5bb4d7d973ad74ed # v5.1.0 with: go-version: ${{ env.GOLANG_VERSION }} - name: GH actions workaround - Kill XSP4 process diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index 530340127708c..634fbb2647787 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -33,7 +33,7 @@ jobs: # Use correct go version. https://github.com/github/codeql-action/issues/1842#issuecomment-1704398087 - name: Setup Golang - uses: actions/setup-go@0a12ed9d6a96ab950c8f026ed9f722fe0da7ef32 # v5.0.2 + uses: actions/setup-go@41dfa10bad2bb2ae585af6ee5bb4d7d973ad74ed # v5.1.0 with: go-version-file: go.mod diff --git a/.github/workflows/image-reuse.yaml b/.github/workflows/image-reuse.yaml index 1accb04f32982..571f7b6f31ab6 100644 --- a/.github/workflows/image-reuse.yaml +++ b/.github/workflows/image-reuse.yaml @@ -69,7 +69,7 @@ jobs: if: ${{ github.ref_type != 'tag'}} - name: Setup Golang - uses: actions/setup-go@0a12ed9d6a96ab950c8f026ed9f722fe0da7ef32 # v5.0.2 + uses: actions/setup-go@41dfa10bad2bb2ae585af6ee5bb4d7d973ad74ed # v5.1.0 with: go-version: ${{ inputs.go-version }} diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index bb10472f0fba4..e5e42f13fed67 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -70,7 +70,7 @@ jobs: run: git fetch --force --tags - name: Setup Golang - uses: actions/setup-go@0a12ed9d6a96ab950c8f026ed9f722fe0da7ef32 # v5.0.2 + uses: actions/setup-go@41dfa10bad2bb2ae585af6ee5bb4d7d973ad74ed # v5.1.0 with: go-version: ${{ env.GOLANG_VERSION }} @@ -151,7 +151,7 @@ jobs: token: ${{ secrets.GITHUB_TOKEN }} - name: Setup Golang - uses: actions/setup-go@0a12ed9d6a96ab950c8f026ed9f722fe0da7ef32 # v5.0.2 + uses: actions/setup-go@41dfa10bad2bb2ae585af6ee5bb4d7d973ad74ed # v5.1.0 with: go-version: ${{ env.GOLANG_VERSION }} From d8fe100278df0ed6d56edc8d4feebb4f7f375afb Mon Sep 17 00:00:00 2001 From: Shubham Zanzad <147542081+Shubhamzanzad@users.noreply.github.com> Date: Wed, 30 Oct 2024 09:58:23 +0530 Subject: [PATCH 08/14] Docs: Added prerequisites for argoCD, fork and clone repository, upstreaming, common make targets, steps before submitting a PR. (#20540) Signed-off-by: Shubham Zanzad Co-authored-by: Dan Garfield --- .../contributors-quickstart.md | 68 +++++++++++++++++-- 1 file changed, 61 insertions(+), 7 deletions(-) diff --git a/docs/developer-guide/contributors-quickstart.md b/docs/developer-guide/contributors-quickstart.md index 6aaa0d7723e56..5544742b7a06b 100644 --- a/docs/developer-guide/contributors-quickstart.md +++ b/docs/developer-guide/contributors-quickstart.md @@ -7,20 +7,49 @@ and the [toolchain guide](toolchain-guide.md). ## Getting Started -### Install Go +### Prerequisites - +Before starting, ensure you have the following tools installed with the specified minimum versions: -Install Go with a version equal to or greater than the version listed in `go.mod` (verify go version with `go version`). +* Git (v2.0.0+) +* Go (version specified in `go.mod` - check with `go version`) +* Docker (v20.10.0+) Or Podman (v3.0.0+) +* Kind (v0.11.0+) Or Minikube (v1.23.0+) +* Yarn (v1.22.0+) +* Goreman (latest version) + +### Fork and Clone the Repository -### Clone the Argo CD repo +1. Fork the Argo CD repository to your personal Github Account +2. Clone the forked repository: ```shell -mkdir -p $GOPATH/src/github.com/argoproj/ && -cd $GOPATH/src/github.com/argoproj && -git clone https://github.com/argoproj/argo-cd.git +mkdir -p $GOPATH/src/github.com/argoproj/ +cd $GOPATH/src/github.com/argoproj/ +git clone https://github.com/YOUR-USERNAME/argo-cd.git +``` + +3. Add the upstream remote for rebasing: +```shell +cd argo-cd +git remote add upstream https://github.com/argoproj/argo-cd.git ``` +### Install Required Tools + +1. Install development tools: +```shell +make install-go-tools-local +make install-code-gen-tools-local +``` + +### Install Go + + + +Install Go with a version equal to or greater than the version listed in `go.mod` (verify go version with `go version`). + + ### Install Docker or Podman #### Installation guide for docker: @@ -103,8 +132,33 @@ DOCKER=podman make start-local ARGOCD_GPG_ENABLED=false If the UI is not working, check the logs from `make start-local`. The logs are `DEBUG` level by default. If the logs are too noisy to find the problem, try editing log levels for the commands in the `Procfile` in the root of the Argo CD repo. +## Common Make Targets + +Here are some frequently used make targets: + +* `make start-local` - Start Argo CD locally +* `make test` - Run unit tests +* `make test-e2e` - Run end-to-end tests +* `make lint` - Run linting +* `make serve-docs` - Serve documentation locally +* `make pre-commit-local` - Run pre-commit checks locally +* `make build` - Build Argo CD binaries + ## Making Changes +### Before Submitting a PR + +1. Rebase your branch against upstream main: +```shell +git fetch upstream +git rebase upstream/main +``` + +2. Run pre-commit checks: +```shell +make pre-commit-local +``` + ### Docs Changes Modifying the docs auto-reloads the changes on the [documentation website](https://argo-cd.readthedocs.io/) that can be locally built using `make serve-docs` command. From d408909df6f950dd4b1a0b898c3b77259aef394f Mon Sep 17 00:00:00 2001 From: Preethi Sureshkumar <40830235+preethi-sv@users.noreply.github.com> Date: Wed, 30 Oct 2024 09:59:52 +0530 Subject: [PATCH 09/14] docs: Update Dex OIDC example (#20545) * docs: Update Dex OIDC example Type for using OIDC claim should be `oidc` instead of `OIDC`. Signed-off-by: Preethi Sureshkumar <40830235+preethi-sv@users.noreply.github.com> * docs: Update Dex OIDC example Signed-off-by: Preethi Sureshkumar <40830235+preethi-sv@users.noreply.github.com> --------- Signed-off-by: Preethi Sureshkumar <40830235+preethi-sv@users.noreply.github.com> Co-authored-by: Dan Garfield --- docs/operator-manual/user-management/index.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/operator-manual/user-management/index.md b/docs/operator-manual/user-management/index.md index 8616764172988..cae97ac6d0d20 100644 --- a/docs/operator-manual/user-management/index.md +++ b/docs/operator-manual/user-management/index.md @@ -262,7 +262,7 @@ data: dex.config: | connectors: # OIDC - - type: OIDC + - type: oidc id: oidc name: OIDC config: @@ -292,7 +292,7 @@ data: dex.config: | connectors: # OIDC - - type: OIDC + - type: oidc id: oidc name: OIDC config: From 092bb7328cc7aeeb75460fc25fafa575418cacd3 Mon Sep 17 00:00:00 2001 From: austin5219 <3936059+austin5219@users.noreply.github.com> Date: Wed, 30 Oct 2024 05:37:18 -0500 Subject: [PATCH 10/14] fix(pkce): 20111 PKCE auth flow does not return user to previous path like dex auth flow (#20202) * Adding non-default basehref support for PKCE auth flow Signed-off-by: austin5219 <3936059+austin5219@users.noreply.github.com> * Adding ; for linting Signed-off-by: austin5219 <3936059+austin5219@users.noreply.github.com> * removing hook function Signed-off-by: austin5219 <3936059+austin5219@users.noreply.github.com> * Moving unauthorized error handling to class component to access context for error handling within 401 error Signed-off-by: austin5219 <3936059+austin5219@users.noreply.github.com> * Store the subsrition handle to close in unmount Signed-off-by: austin5219 <3936059+austin5219@users.noreply.github.com> * reorder imports Signed-off-by: austin5219 <3936059+austin5219@users.noreply.github.com> * Actually saving the subscriptions now Signed-off-by: austin5219 <3936059+austin5219@users.noreply.github.com> * returning the 401 subscription from helper function Signed-off-by: austin5219 <3936059+austin5219@users.noreply.github.com> * Handle the promise of a subscription Signed-off-by: austin5219 <3936059+austin5219@users.noreply.github.com> * Removing then from non async subscribe Signed-off-by: austin5219 <3936059+austin5219@users.noreply.github.com> * Linter fixes Signed-off-by: austin5219 <3936059+austin5219@users.noreply.github.com> * Adding path caching to sessionStorage on pkceLogin and redirect step to cached path if available in pkceCallback to mirror Dex functionality Signed-off-by: austin5219 <3936059+austin5219@users.noreply.github.com> --------- Signed-off-by: austin5219 <3936059+austin5219@users.noreply.github.com> --- ui/src/app/app.tsx | 79 ++++++++++++++------- ui/src/app/login/components/pkce-verify.tsx | 3 +- ui/src/app/login/components/utils.ts | 24 ++++++- 3 files changed, 78 insertions(+), 28 deletions(-) diff --git a/ui/src/app/app.tsx b/ui/src/app/app.tsx index 7b73bc50ac70c..2d2e192590fa2 100644 --- a/ui/src/app/app.tsx +++ b/ui/src/app/app.tsx @@ -1,9 +1,10 @@ -import {DataLoader, NavigationManager, Notifications, NotificationsManager, PageContext, Popup, PopupManager, PopupProps} from 'argo-ui'; +import {DataLoader, NavigationManager, NotificationType, Notifications, NotificationsManager, PageContext, Popup, PopupManager, PopupProps} from 'argo-ui'; import {createBrowserHistory} from 'history'; import * as PropTypes from 'prop-types'; import * as React from 'react'; import {Helmet} from 'react-helmet'; import {Redirect, Route, RouteComponentProps, Router, Switch} from 'react-router'; +import {Subscription} from 'rxjs'; import applications from './applications'; import help from './help'; import login from './login'; @@ -19,6 +20,7 @@ import {Banner} from './ui-banner/ui-banner'; import userInfo from './user-info'; import {AuthSettings} from './shared/models'; import {PKCEVerification} from './login/components/pkce-verify'; +import {getPKCERedirectURI, pkceLogin} from './login/components/utils'; import {SystemLevelExtension} from './shared/services/extensions-service'; services.viewPreferences.init(); @@ -86,28 +88,6 @@ async function isExpiredSSO() { return false; } -requests.onError.subscribe(async err => { - if (err.status === 401) { - if (history.location.pathname.startsWith('/login')) { - return; - } - - const isSSO = await isExpiredSSO(); - // location might change after async method call, so we need to check again. - if (history.location.pathname.startsWith('/login')) { - return; - } - // Query for basehref and remove trailing /. - // If basehref is the default `/` it will become an empty string. - const basehref = document.querySelector('head > base').getAttribute('href').replace(/\/$/, ''); - if (isSSO) { - window.location.href = `${basehref}/auth/login?return_url=${encodeURIComponent(location.href)}`; - } else { - history.push(`/login?return_url=${encodeURIComponent(location.href)}`); - } - } -}); - export class App extends React.Component< {}, {popupProps: PopupProps; showVersionPanel: boolean; error: Error; navItems: NavItem[]; routes: Routes; extensionsLoaded: boolean; authSettings: AuthSettings} @@ -126,6 +106,8 @@ export class App extends React.Component< private navigationManager: NavigationManager; private navItems: NavItem[]; private routes: Routes; + private popupPropsSubscription: Subscription; + private unauthorizedSubscription: Subscription; constructor(props: {}) { super(props); @@ -135,11 +117,16 @@ export class App extends React.Component< this.navigationManager = new NavigationManager(history); this.navItems = navItems; this.routes = routes; + this.popupPropsSubscription = null; + this.unauthorizedSubscription = null; services.extensions.addEventListener('systemLevel', this.onAddSystemLevelExtension.bind(this)); } public async componentDidMount() { - this.popupManager.popupProps.subscribe(popupProps => this.setState({popupProps})); + this.popupPropsSubscription = this.popupManager.popupProps.subscribe(popupProps => this.setState({popupProps})); + this.subscribeUnauthorized().then(subscription => { + this.unauthorizedSubscription = subscription; + }); const authSettings = await services.authService.settings(); const {trackingID, anonymizeUsers} = authSettings.googleAnalytics || {trackingID: '', anonymizeUsers: true}; const {loggedIn, username} = await services.users.get(); @@ -167,6 +154,15 @@ export class App extends React.Component< this.setState({...this.state, navItems: this.navItems, routes: this.routes, extensionsLoaded: false, authSettings}); } + public componentWillUnmount() { + if (this.popupPropsSubscription) { + this.popupPropsSubscription.unsubscribe(); + } + if (this.unauthorizedSubscription) { + this.unauthorizedSubscription.unsubscribe(); + } + } + public render() { if (this.state.error != null) { const stack = this.state.error.stack; @@ -242,6 +238,41 @@ export class App extends React.Component< return {history, apis: {popup: this.popupManager, notifications: this.notificationsManager, navigation: this.navigationManager}}; } + private async subscribeUnauthorized() { + return requests.onError.subscribe(async err => { + if (err.status === 401) { + if (history.location.pathname.startsWith('/login')) { + return; + } + + const isSSO = await isExpiredSSO(); + // location might change after async method call, so we need to check again. + if (history.location.pathname.startsWith('/login')) { + return; + } + // Query for basehref and remove trailing /. + // If basehref is the default `/` it will become an empty string. + const basehref = document.querySelector('head > base').getAttribute('href').replace(/\/$/, ''); + if (isSSO) { + const authSettings = await services.authService.settings(); + + if (authSettings?.oidcConfig?.enablePKCEAuthentication) { + pkceLogin(authSettings.oidcConfig, getPKCERedirectURI().toString()).catch(err => { + this.getChildContext().apis.notifications.show({ + type: NotificationType.Error, + content: err?.message || JSON.stringify(err) + }); + }); + } else { + window.location.href = `${basehref}/auth/login?return_url=${encodeURIComponent(location.href)}`; + } + } else { + history.push(`/login?return_url=${encodeURIComponent(location.href)}`); + } + } + }); + } + private onAddSystemLevelExtension(extension: SystemLevelExtension) { const extendedNavItems = this.navItems; const extendedRoutes = this.routes; diff --git a/ui/src/app/login/components/pkce-verify.tsx b/ui/src/app/login/components/pkce-verify.tsx index ee3f420fe07ea..9c069e7eda3b5 100644 --- a/ui/src/app/login/components/pkce-verify.tsx +++ b/ui/src/app/login/components/pkce-verify.tsx @@ -2,6 +2,7 @@ import React, {useEffect, useState} from 'react'; import {RouteComponentProps} from 'react-router'; import {services} from '../../shared/services'; import {PKCECodeVerifier, PKCEState, PKCELoginError, getPKCERedirectURI, pkceCallback} from './utils'; +import requests from '../../shared/services/requests'; import './pkce-verify.scss'; @@ -32,7 +33,7 @@ export const PKCEVerification = (props: RouteComponentProps) => {

Error occurred:

{error?.message || JSON.stringify(error)}

- Try to Login again + Try to Login again
); diff --git a/ui/src/app/login/components/utils.ts b/ui/src/app/login/components/utils.ts index 94372797f4912..b363a4a934d63 100644 --- a/ui/src/app/login/components/utils.ts +++ b/ui/src/app/login/components/utils.ts @@ -13,6 +13,7 @@ import { validateAuthResponse } from 'oauth4webapi'; import {AuthSettings} from '../../shared/models'; +import requests from '../../shared/services/requests'; export const discoverAuthServer = (issuerURL: URL): Promise => discoveryRequest(issuerURL).then(res => processDiscoveryResponse(issuerURL, res)); @@ -31,7 +32,7 @@ export const PKCEState = { export const getPKCERedirectURI = () => { const currentOrigin = new URL(window.location.origin); - currentOrigin.pathname = '/pkce/verify'; + currentOrigin.pathname = requests.toAbsURL('/pkce/verify'); return currentOrigin; }; @@ -76,6 +77,12 @@ const validateAndGetOIDCForPKCE = async (oidcConfig: AuthSettings['oidcConfig']) export const pkceLogin = async (oidcConfig: AuthSettings['oidcConfig'], redirectURI: string) => { const {authorizationServer} = await validateAndGetOIDCForPKCE(oidcConfig); + // This sets the return path for the user after the pkce auth flow. + // This is ignored if the return path would be the login page as it would just loop. + if (!location.pathname.startsWith(requests.toAbsURL('/login'))) { + sessionStorage.setItem('return_url', location.pathname + location.search); + } + if (!authorizationServer.authorization_endpoint) { throw new PKCELoginError('No Authorization Server endpoint found'); } @@ -153,7 +160,18 @@ export const pkceCallback = async (queryParams: string, oidcConfig: AuthSettings throw new PKCELoginError('No token in response'); } - document.cookie = `argocd.token=${result.id_token}; path=/`; + // This regex removes any leading or trailing '/' characters and the result is appended to a '/'. + // This is because when base href if not just '/' toAbsURL() will append a trailing '/'. + // Just removing a trailing '/' from the string would break when base href is not specified, defaulted to '/'. + // This pattern is used to handle both cases. + document.cookie = `argocd.token=${result.id_token}; path=/${requests.toAbsURL('').replace(/^\/|\/$/g, '')}`; - window.location.replace('/applications'); + const returnURL = sessionStorage.getItem('return_url'); + + if (returnURL) { + sessionStorage.removeItem('return_url'); + window.location.replace(returnURL); + } else { + window.location.replace(requests.toAbsURL('/applications')); + } }; From 38546a5e434ebcb525567356f4b7f9ac0a29b59e Mon Sep 17 00:00:00 2001 From: q-yusufmahtab Date: Wed, 30 Oct 2024 14:12:33 +0000 Subject: [PATCH 11/14] Fix docs/user-guide/diffing.md code block (#20596) Signed-off-by: Yusuf Mahtab --- docs/user-guide/diffing.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/user-guide/diffing.md b/docs/user-guide/diffing.md index 7e5b72d97959c..895f330dfc80a 100644 --- a/docs/user-guide/diffing.md +++ b/docs/user-guide/diffing.md @@ -199,3 +199,4 @@ metadata: name: argocd-cmd-params-cm data: ignore.normalizer.jq.timeout: "5s" +``` From 83eb0b18712de4ab214c1382ced8dec419fa6eb3 Mon Sep 17 00:00:00 2001 From: Yiwei Gong Date: Wed, 30 Oct 2024 23:22:19 +0800 Subject: [PATCH 12/14] rerender when extensions update (#20559) Signed-off-by: Yiwei Gong --- .../application-details.tsx | 57 ++++++++++++------- .../app/shared/services/extensions-service.ts | 4 +- 2 files changed, 39 insertions(+), 22 deletions(-) diff --git a/ui/src/app/applications/components/application-details/application-details.tsx b/ui/src/app/applications/components/application-details/application-details.tsx index d20a7ba945a3c..2e7a8cc67bca3 100644 --- a/ui/src/app/applications/components/application-details/application-details.tsx +++ b/ui/src/app/applications/components/application-details/application-details.tsx @@ -86,6 +86,41 @@ export class ApplicationDetails extends React.Component) { super(props); + this.state = { + page: 0, + groupedResources: [], + slidingPanelPage: 0, + filteredGraph: [], + truncateNameOnRight: false, + collapsedNodes: [], + ...this.getExtensionsState() + }; + if (typeof this.props.match.params.appnamespace === 'undefined') { + this.appNamespace = ''; + } else { + this.appNamespace = this.props.match.params.appnamespace; + } + } + + public componentDidMount() { + services.extensions.addEventListener('resource', this.onExtensionsUpdate); + services.extensions.addEventListener('appView', this.onExtensionsUpdate); + services.extensions.addEventListener('statusPanel', this.onExtensionsUpdate); + services.extensions.addEventListener('topBar', this.onExtensionsUpdate); + } + + public componentWillUnmount() { + services.extensions.removeEventListener('resource', this.onExtensionsUpdate); + services.extensions.removeEventListener('appView', this.onExtensionsUpdate); + services.extensions.removeEventListener('statusPanel', this.onExtensionsUpdate); + services.extensions.removeEventListener('topBar', this.onExtensionsUpdate); + } + + private onExtensionsUpdate = () => { + this.setState({...this.state, ...this.getExtensionsState()}); + }; + + private getExtensionsState = () => { const extensions = services.extensions.getAppViewExtensions(); const extensionsMap: {[key: string]: AppViewExtension} = {}; extensions.forEach(ext => { @@ -101,26 +136,8 @@ export class ApplicationDetails extends React.Component { topBarActionMenuExtsMap[ext.id] = ext; }); - this.state = { - page: 0, - groupedResources: [], - slidingPanelPage: 0, - filteredGraph: [], - truncateNameOnRight: false, - collapsedNodes: [], - extensions, - extensionsMap, - statusExtensions, - statusExtensionsMap, - topBarActionMenuExts, - topBarActionMenuExtsMap - }; - if (typeof this.props.match.params.appnamespace === 'undefined') { - this.appNamespace = ''; - } else { - this.appNamespace = this.props.match.params.appnamespace; - } - } + return {extensions, extensionsMap, statusExtensions, statusExtensionsMap, topBarActionMenuExts, topBarActionMenuExtsMap}; + }; private get showOperationState() { return new URLSearchParams(this.props.history.location.search).get('operation') === 'true'; diff --git a/ui/src/app/shared/services/extensions-service.ts b/ui/src/app/shared/services/extensions-service.ts index 887b767df3305..20e5ca36f568b 100644 --- a/ui/src/app/shared/services/extensions-service.ts +++ b/ui/src/app/shared/services/extensions-service.ts @@ -3,7 +3,7 @@ import * as minimatch from 'minimatch'; import {Application, ApplicationTree, State} from '../models'; -type ExtensionsEventType = 'resource' | 'systemLevel' | 'appView' | 'statusPanel' | 'top-bar'; +type ExtensionsEventType = 'resource' | 'systemLevel' | 'appView' | 'statusPanel' | 'topBar'; type ExtensionsType = ResourceTabExtension | SystemLevelExtension | AppViewExtension | StatusPanelExtension | TopBarActionMenuExt; class ExtensionsEventTarget { @@ -73,7 +73,7 @@ function registerTopBarActionMenuExt( ) { const ext = {component, flyout, shouldDisplay, title, id, iconClassName, isMiddle}; extensions.topBarActionMenuExts.push(ext); - extensions.eventTarget.emit('top-bar', ext); + extensions.eventTarget.emit('topBar', ext); } let legacyInitialized = false; From eb10b70e8a2e24d08137143cf01a8d9c26783b12 Mon Sep 17 00:00:00 2001 From: Siddhesh Ghadi <61187612+svghadi@users.noreply.github.com> Date: Wed, 30 Oct 2024 22:22:37 +0530 Subject: [PATCH 13/14] feat: Add ability to hide certain annotations on secret resources (#18216) Signed-off-by: Siddhesh Ghadi --- controller/appcontroller.go | 2 +- docs/operator-manual/argocd-cm.yaml | 3 ++ docs/operator-manual/declarative-setup.md | 8 ++++ go.mod | 2 +- go.sum | 4 +- server/application/application.go | 14 +++--- test/e2e/mask_secret_values_test.go | 58 +++++++++++++++++++++++ test/e2e/testdata/empty-dir/.gitignore | 0 util/settings/settings.go | 24 ++++++++++ util/settings/settings_test.go | 34 +++++++++++++ 10 files changed, 138 insertions(+), 11 deletions(-) create mode 100644 test/e2e/mask_secret_values_test.go create mode 100644 test/e2e/testdata/empty-dir/.gitignore diff --git a/controller/appcontroller.go b/controller/appcontroller.go index 431777dd78972..a3947ca634a72 100644 --- a/controller/appcontroller.go +++ b/controller/appcontroller.go @@ -759,7 +759,7 @@ func (ctrl *ApplicationController) hideSecretData(app *appv1.Application, compar resDiff := res.Diff if res.Kind == kube.SecretKind && res.Group == "" { var err error - target, live, err = diff.HideSecretData(res.Target, res.Live) + target, live, err = diff.HideSecretData(res.Target, res.Live, ctrl.settingsMgr.GetSensitiveAnnotations()) if err != nil { return nil, fmt.Errorf("error hiding secret data: %w", err) } diff --git a/docs/operator-manual/argocd-cm.yaml b/docs/operator-manual/argocd-cm.yaml index 59edf5f156bd1..e00c2f420d240 100644 --- a/docs/operator-manual/argocd-cm.yaml +++ b/docs/operator-manual/argocd-cm.yaml @@ -222,6 +222,9 @@ data: clusters: - "*.local" + # An optional comma-separated list of annotation keys to mask in UI/CLI on secrets + resource.sensitive.mask.annotations: openshift.io/token-secret.value,api-key + # An optional comma-separated list of metadata.labels to observe in the UI. resource.customLabels: tier diff --git a/docs/operator-manual/declarative-setup.md b/docs/operator-manual/declarative-setup.md index 134f98cfc5eeb..d3b93d27c1601 100644 --- a/docs/operator-manual/declarative-setup.md +++ b/docs/operator-manual/declarative-setup.md @@ -1225,6 +1225,14 @@ Notes: * Invalid globs result in the whole rule being ignored. * If you add a rule that matches existing resources, these will appear in the interface as `OutOfSync`. +## Mask sensitive Annotations on Secrets + +An optional comma-separated list of `metadata.annotations` keys can be configured with `resource.sensitive.mask.annotations` to mask their values in UI/CLI on Secrets. + +```yaml + resource.sensitive.mask.annotations: openshift.io/token-secret.value, api-key +``` + ## Auto respect RBAC for controller Argocd controller can be restricted from discovering/syncing specific resources using just controller rbac, without having to manually configure resource exclusions. diff --git a/go.mod b/go.mod index cc30b6d9d3429..d697a4c74f427 100644 --- a/go.mod +++ b/go.mod @@ -10,7 +10,7 @@ require ( github.com/TomOnTime/utfutil v0.0.0-20180511104225-09c41003ee1d github.com/alicebob/miniredis/v2 v2.33.0 github.com/antonmedv/expr v1.15.1 - github.com/argoproj/gitops-engine v0.7.1-0.20241023134423-09e5225f8472 + github.com/argoproj/gitops-engine v0.7.1-0.20241029102952-9ab0b2ecae96 github.com/argoproj/notifications-engine v0.4.1-0.20241007194503-2fef5c9049fd github.com/argoproj/pkg v0.13.7-0.20230626144333-d56162821bd1 github.com/aws/aws-sdk-go v1.55.5 diff --git a/go.sum b/go.sum index 8f36620fb58d8..aa6cdee5f74f7 100644 --- a/go.sum +++ b/go.sum @@ -84,8 +84,8 @@ github.com/antonmedv/expr v1.15.1/go.mod h1:0E/6TxnOlRNp81GMzX9QfDPAmHo2Phg00y4J github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= github.com/apache/thrift v0.13.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= github.com/appscode/go v0.0.0-20191119085241-0887d8ec2ecc/go.mod h1:OawnOmAL4ZX3YaPdN+8HTNwBveT1jMsqP74moa9XUbE= -github.com/argoproj/gitops-engine v0.7.1-0.20241023134423-09e5225f8472 h1:NSUzj5CWkOR6xrbGBT4dhZ7WsHhT/pbud+fsvQuUe7k= -github.com/argoproj/gitops-engine v0.7.1-0.20241023134423-09e5225f8472/go.mod h1:b1vuwkyMUszyUK+USUJqC8vJijnQsEPNDpC+sDdDLtM= +github.com/argoproj/gitops-engine v0.7.1-0.20241029102952-9ab0b2ecae96 h1:7Guh0VsAHmccy0c55XfzVMT5Y/t76N3j/O0CXk22/A4= +github.com/argoproj/gitops-engine v0.7.1-0.20241029102952-9ab0b2ecae96/go.mod h1:b1vuwkyMUszyUK+USUJqC8vJijnQsEPNDpC+sDdDLtM= github.com/argoproj/notifications-engine v0.4.1-0.20241007194503-2fef5c9049fd h1:lOVVoK89j9Nd4+JYJiKAaMNYC1402C0jICROOfUPWn0= github.com/argoproj/notifications-engine v0.4.1-0.20241007194503-2fef5c9049fd/go.mod h1:N0A4sEws2soZjEpY4hgZpQS8mRIEw6otzwfkgc3g9uQ= github.com/argoproj/pkg v0.13.7-0.20230626144333-d56162821bd1 h1:qsHwwOJ21K2Ao0xPju1sNuqphyMnMYkyB3ZLoLtxWpo= diff --git a/server/application/application.go b/server/application/application.go index 055bdca54f2b9..de961c82ea5f7 100644 --- a/server/application/application.go +++ b/server/application/application.go @@ -557,7 +557,7 @@ func (s *Server) GetManifests(ctx context.Context, q *application.ApplicationMan return nil, fmt.Errorf("error unmarshaling manifest into unstructured: %w", err) } if obj.GetKind() == kube.SecretKind && obj.GroupVersionKind().Group == "" { - obj, _, err = diff.HideSecretData(obj, nil) + obj, _, err = diff.HideSecretData(obj, nil, s.settingsMgr.GetSensitiveAnnotations()) if err != nil { return nil, fmt.Errorf("error hiding secret data: %w", err) } @@ -684,7 +684,7 @@ func (s *Server) GetManifestsWithFiles(stream application.ApplicationService_Get return fmt.Errorf("error unmarshaling manifest into unstructured: %w", err) } if obj.GetKind() == kube.SecretKind && obj.GroupVersionKind().Group == "" { - obj, _, err = diff.HideSecretData(obj, nil) + obj, _, err = diff.HideSecretData(obj, nil, s.settingsMgr.GetSensitiveAnnotations()) if err != nil { return fmt.Errorf("error hiding secret data: %w", err) } @@ -1373,7 +1373,7 @@ func (s *Server) GetResource(ctx context.Context, q *application.ApplicationReso if err != nil { return nil, fmt.Errorf("error getting resource: %w", err) } - obj, err = replaceSecretValues(obj) + obj, err = s.replaceSecretValues(obj) if err != nil { return nil, fmt.Errorf("error replacing secret values: %w", err) } @@ -1385,9 +1385,9 @@ func (s *Server) GetResource(ctx context.Context, q *application.ApplicationReso return &application.ApplicationResourceResponse{Manifest: &manifest}, nil } -func replaceSecretValues(obj *unstructured.Unstructured) (*unstructured.Unstructured, error) { +func (s *Server) replaceSecretValues(obj *unstructured.Unstructured) (*unstructured.Unstructured, error) { if obj.GetKind() == kube.SecretKind && obj.GroupVersionKind().Group == "" { - _, obj, err := diff.HideSecretData(nil, obj) + _, obj, err := diff.HideSecretData(nil, obj, s.settingsMgr.GetSensitiveAnnotations()) if err != nil { return nil, err } @@ -1424,7 +1424,7 @@ func (s *Server) PatchResource(ctx context.Context, q *application.ApplicationRe if manifest == nil { return nil, fmt.Errorf("failed to patch resource: manifest was nil") } - manifest, err = replaceSecretValues(manifest) + manifest, err = s.replaceSecretValues(manifest) if err != nil { return nil, fmt.Errorf("error replacing secret values: %w", err) } @@ -2184,7 +2184,7 @@ func (s *Server) ListResourceLinks(ctx context.Context, req *application.Applica return nil, fmt.Errorf("failed to read application deep links from configmap: %w", err) } - obj, err = replaceSecretValues(obj) + obj, err = s.replaceSecretValues(obj) if err != nil { return nil, fmt.Errorf("error replacing secret values: %w", err) } diff --git a/test/e2e/mask_secret_values_test.go b/test/e2e/mask_secret_values_test.go new file mode 100644 index 0000000000000..691cf2f7ec50e --- /dev/null +++ b/test/e2e/mask_secret_values_test.go @@ -0,0 +1,58 @@ +package e2e + +import ( + "regexp" + "testing" + + "github.com/stretchr/testify/assert" + + "github.com/argoproj/gitops-engine/pkg/health" + + . "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + . "github.com/argoproj/argo-cd/v2/test/e2e/fixture" + . "github.com/argoproj/argo-cd/v2/test/e2e/fixture/app" +) + +// Values of `.data` & `.stringData“ fields in Secret resources are masked in UI/CLI +// Optionally, values of `.metadata.annotations` can also be masked, if needed. +func TestMaskSecretValues(t *testing.T) { + sensitiveData := regexp.MustCompile(`SECRETVAL|NEWSECRETVAL|U0VDUkVUVkFM`) + + Given(t). + Path("empty-dir"). + When(). + SetParamInSettingConfigMap("resource.sensitive.mask.annotations", "token"). // hide sensitive annotation + AddFile("secrets.yaml", `apiVersion: v1 +kind: Secret +metadata: + name: secret + annotations: + token: SECRETVAL + app: test +stringData: + username: SECRETVAL +data: + password: U0VDUkVUVkFM +`). + CreateApp(). + Sync(). + Then(). + Expect(SyncStatusIs(SyncStatusCodeSynced)). + Expect(HealthIs(health.HealthStatusHealthy)). + // sensitive data should be masked in manifests output + And(func(app *Application) { + mnfs, _ := RunCli("app", "manifests", app.Name) + assert.False(t, sensitiveData.MatchString(mnfs)) + }). + When(). + PatchFile("secrets.yaml", `[{"op": "replace", "path": "/stringData/username", "value": "NEWSECRETVAL"}]`). + PatchFile("secrets.yaml", `[{"op": "add", "path": "/metadata/annotations", "value": {"token": "NEWSECRETVAL"}}]`). + Refresh(RefreshTypeHard). + Then(). + Expect(SyncStatusIs(SyncStatusCodeOutOfSync)). + // sensitive data should be masked in diff output + And(func(app *Application) { + diff, _ := RunCli("app", "diff", app.Name) + assert.False(t, sensitiveData.MatchString(diff)) + }) +} diff --git a/test/e2e/testdata/empty-dir/.gitignore b/test/e2e/testdata/empty-dir/.gitignore new file mode 100644 index 0000000000000..e69de29bb2d1d diff --git a/util/settings/settings.go b/util/settings/settings.go index 2d1a072505867..516116f0ecd99 100644 --- a/util/settings/settings.go +++ b/util/settings/settings.go @@ -461,6 +461,8 @@ const ( resourceInclusionsKey = "resource.inclusions" // resourceIgnoreResourceUpdatesEnabledKey is the key to a boolean determining whether the resourceIgnoreUpdates feature is enabled resourceIgnoreResourceUpdatesEnabledKey = "resource.ignoreResourceUpdatesEnabled" + // resourceSensitiveAnnotationsKey is the key to list of annotations to mask in secret resource + resourceSensitiveAnnotationsKey = "resource.sensitive.mask.annotations" // resourceCustomLabelKey is the key to a custom label to show in node info, if present resourceCustomLabelsKey = "resource.customLabels" // resourceIncludeEventLabelKeys is the key to labels to be added onto Application k8s events if present on an Application or it's AppProject. Supports wildcard. @@ -2341,6 +2343,28 @@ func (mgr *SettingsManager) GetExcludeEventLabelKeys() []string { return labelKeys } +func (mgr *SettingsManager) GetSensitiveAnnotations() map[string]bool { + annotationKeys := make(map[string]bool) + + argoCDCM, err := mgr.getConfigMap() + if err != nil { + log.Error(fmt.Errorf("failed getting configmap: %w", err)) + return annotationKeys + } + + value, ok := argoCDCM.Data[resourceSensitiveAnnotationsKey] + if !ok || value == "" { + return annotationKeys + } + + value = strings.ReplaceAll(value, " ", "") + keys := strings.Split(value, ",") + for _, k := range keys { + annotationKeys[k] = true + } + return annotationKeys +} + func (mgr *SettingsManager) GetMaxWebhookPayloadSize() int64 { argoCDCM, err := mgr.getConfigMap() if err != nil { diff --git a/util/settings/settings_test.go b/util/settings/settings_test.go index b8a01e69bed9d..1a220bc2f063a 100644 --- a/util/settings/settings_test.go +++ b/util/settings/settings_test.go @@ -1820,3 +1820,37 @@ func TestIsImpersonationEnabled(t *testing.T) { require.NoError(t, err, "when user enables the flag in argocd-cm config map, IsImpersonationEnabled() must not return any error") } + +func TestSettingsManager_GetHideSecretAnnotations(t *testing.T) { + tests := []struct { + name string + input string + output map[string]bool + }{ + { + name: "Empty input", + input: "", + output: map[string]bool{}, + }, + { + name: "Comma separated data", + input: "example.com/token-secret.value,token,key", + output: map[string]bool{"example.com/token-secret.value": true, "token": true, "key": true}, + }, + { + name: "Comma separated data with space", + input: "example.com/token-secret.value, token, key", + output: map[string]bool{"example.com/token-secret.value": true, "token": true, "key": true}, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + _, settingsManager := fixtures(map[string]string{ + resourceSensitiveAnnotationsKey: tt.input, + }) + keys := settingsManager.GetSensitiveAnnotations() + assert.Equal(t, len(tt.output), len(keys)) + assert.Equal(t, tt.output, keys) + }) + } +} From e861b550e0a9a74f4ec8b8d84c3a87c7de857ed4 Mon Sep 17 00:00:00 2001 From: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> Date: Wed, 30 Oct 2024 21:35:23 -0400 Subject: [PATCH 14/14] fix(diff): avoid cache miss in server-side diff (#20605) Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> --- controller/state.go | 4 ++++ controller/state_test.go | 4 ++++ pkg/apis/application/v1alpha1/types.go | 6 ++++++ 3 files changed, 14 insertions(+) diff --git a/controller/state.go b/controller/state.go index bb4fdd3d21fed..b6bafcb5c83ac 100644 --- a/controller/state.go +++ b/controller/state.go @@ -965,6 +965,10 @@ func specEqualsCompareTo(spec v1alpha1.ApplicationSpec, comparedTo v1alpha1.Comp currentSpec.Destination.Name = "" } + // Set IsServerInferred to false on both, because that field is not important for comparison. + comparedTo.Destination.SetIsServerInferred(false) + currentSpec.Destination.SetIsServerInferred(false) + return reflect.DeepEqual(comparedTo, currentSpec) } diff --git a/controller/state_test.go b/controller/state_test.go index 971b7ac751273..658e72224aeb9 100644 --- a/controller/state_test.go +++ b/controller/state_test.go @@ -1528,6 +1528,10 @@ func TestUseDiffCache(t *testing.T) { t.Fatalf("error merging app: %s", err) } } + if app.Spec.Destination.Name != "" && app.Spec.Destination.Server != "" { + // Simulate the controller's process for populating both of these fields. + app.Spec.Destination.SetInferredServer(app.Spec.Destination.Server) + } return app } diff --git a/pkg/apis/application/v1alpha1/types.go b/pkg/apis/application/v1alpha1/types.go index 4afeac5183615..998b1fbf1dfb6 100644 --- a/pkg/apis/application/v1alpha1/types.go +++ b/pkg/apis/application/v1alpha1/types.go @@ -1003,6 +1003,12 @@ type ApplicationDestination struct { isServerInferred bool `json:"-"` } +// SetIsServerInferred sets the isServerInferred flag. This is used to allow comparison between two destinations where +// one server is inferred and the other is not. +func (d *ApplicationDestination) SetIsServerInferred(inferred bool) { + d.isServerInferred = inferred +} + type ResourceHealthLocation string var (