From cec25b5d1ee087d0bc2e6f31cb4612dd2526e5ec Mon Sep 17 00:00:00 2001 From: Matheus Pimenta Date: Thu, 25 Jun 2026 12:14:24 +0100 Subject: [PATCH 1/2] Fix 'flux get all --status-selector' for empty results Signed-off-by: Matheus Pimenta --- cmd/flux/get.go | 3 + cmd/flux/get_test.go | 62 +++++++++++++++++++ cmd/flux/testdata/get/kustomization_only.yaml | 26 ++++++++ 3 files changed, 91 insertions(+) create mode 100644 cmd/flux/testdata/get/kustomization_only.yaml diff --git a/cmd/flux/get.go b/cmd/flux/get.go index 09fb7da9..a736e025 100644 --- a/cmd/flux/get.go +++ b/cmd/flux/get.go @@ -207,6 +207,9 @@ func (get getCommand) run(cmd *cobra.Command, args []string) error { if err != nil { return err } + if getAll && len(rows) == 0 { + return nil + } err = printers.TablePrinter(header).Print(cmd.OutOrStdout(), rows) if err != nil { diff --git a/cmd/flux/get_test.go b/cmd/flux/get_test.go index 7376ff04..90e77ce2 100644 --- a/cmd/flux/get_test.go +++ b/cmd/flux/get_test.go @@ -103,6 +103,68 @@ func Test_GetCmdStatusSelector(t *testing.T) { } } +func Test_GetAllCmdStatusSelectorNoMatches(t *testing.T) { + tmpl := map[string]string{ + "fluxns": allocateNamespace("flux-system"), + } + testEnv.CreateObjectFile("./testdata/get/status_objects.yaml", tmpl, t) + + cmd := cmdTestCase{ + args: "get all --status-selector foo=bar -n " + tmpl["fluxns"], + assert: assertGoldenValue(""), + } + + cmd.runTestCmd(t) +} + +func Test_GetAllCmdStatusSelectorKustomizationOnlyMatches(t *testing.T) { + tmpl := map[string]string{ + "fluxns": allocateNamespace("flux-system"), + } + testEnv.CreateObjectFile("./testdata/get/kustomization_only.yaml", tmpl, t) + + unfilteredOutput, err := executeCommand("get all -n " + tmpl["fluxns"]) + if err != nil { + t.Fatalf("get all failed: %v", err) + } + if unfilteredOutput == "" { + t.Fatal("expected get all output for namespace with one Kustomization") + } + + filteredOutput, err := executeCommand("get all --status-selector Ready=True -n " + tmpl["fluxns"]) + if err != nil { + t.Fatalf("get all with matching status selector failed: %v", err) + } + + if filteredOutput != unfilteredOutput { + t.Fatalf("expected filtered output to match unfiltered output:\nfiltered:\n%s\nunfiltered:\n%s", filteredOutput, unfilteredOutput) + } +} + +func Test_GetAllCmdStatusSelectorKustomizationOnlyNoMatch(t *testing.T) { + tmpl := map[string]string{ + "fluxns": allocateNamespace("flux-system"), + } + testEnv.CreateObjectFile("./testdata/get/kustomization_only.yaml", tmpl, t) + + emptyNamespace := allocateNamespace("empty") + setupTestNamespace(emptyNamespace, t) + + emptyOutput, err := executeCommand("get all -n " + emptyNamespace) + if err != nil { + t.Fatalf("get all in empty namespace failed: %v", err) + } + + filteredOutput, err := executeCommand("get all --status-selector Ready=False -n " + tmpl["fluxns"]) + if err != nil { + t.Fatalf("get all with non-matching status selector failed: %v", err) + } + + if filteredOutput != emptyOutput { + t.Fatalf("expected filtered output to match empty namespace output:\nfiltered:\n%s\nempty namespace:\n%s", filteredOutput, emptyOutput) + } +} + func Test_GetCmdErrors(t *testing.T) { tmpl := map[string]string{ "fluxns": allocateNamespace("flux-system"), diff --git a/cmd/flux/testdata/get/kustomization_only.yaml b/cmd/flux/testdata/get/kustomization_only.yaml new file mode 100644 index 00000000..50d62ccc --- /dev/null +++ b/cmd/flux/testdata/get/kustomization_only.yaml @@ -0,0 +1,26 @@ +--- +apiVersion: v1 +kind: Namespace +metadata: + name: {{ .fluxns }} +--- +apiVersion: kustomize.toolkit.fluxcd.io/v1 +kind: Kustomization +metadata: + name: podinfo + namespace: {{ .fluxns }} +spec: + interval: 5m + path: ./clusters/production + prune: true + sourceRef: + kind: GitRepository + name: podinfo +status: + lastAppliedRevision: main@sha1:696f056df216eea4f9401adbee0ff744d4df390f + conditions: + - lastTransitionTime: "2021-08-01T04:52:56Z" + message: 'Applied revision: main@sha1:696f056df216eea4f9401adbee0ff744d4df390f' + reason: ReconciliationSucceeded + status: "True" + type: Ready From 65d46357090bfdc1136452cbefa3c8b45d48f7c9 Mon Sep 17 00:00:00 2001 From: Matheus Pimenta Date: Thu, 25 Jun 2026 12:15:26 +0100 Subject: [PATCH 2/2] Fix 'flux get all --status-selector' for Alert and Provider Signed-off-by: Matheus Pimenta --- cmd/flux/get.go | 5 +++ cmd/flux/get_alert.go | 2 +- cmd/flux/get_alertprovider.go | 2 +- cmd/flux/get_test.go | 33 +++++++++++++++++++ .../testdata/get/notification_objects.yaml | 31 +++++++++++++++++ 5 files changed, 71 insertions(+), 2 deletions(-) create mode 100644 cmd/flux/testdata/get/notification_objects.yaml diff --git a/cmd/flux/get.go b/cmd/flux/get.go index a736e025..9103abaa 100644 --- a/cmd/flux/get.go +++ b/cmd/flux/get.go @@ -114,6 +114,11 @@ func statusMatches(conditionType, conditionStatus string, conditions []metav1.Co return false } +func readyStatusMatches(conditionType, conditionStatus string) bool { + return strings.EqualFold(conditionType, meta.ReadyCondition) && + strings.EqualFold(conditionStatus, string(metav1.ConditionTrue)) +} + func nameColumns(item named, includeNamespace bool, includeKind bool) []string { name := item.GetName() if includeKind { diff --git a/cmd/flux/get_alert.go b/cmd/flux/get_alert.go index 54b2afe6..657ad1fc 100644 --- a/cmd/flux/get_alert.go +++ b/cmd/flux/get_alert.go @@ -92,5 +92,5 @@ func (s alertListAdapter) headers(includeNamespace bool) []string { } func (s alertListAdapter) statusSelectorMatches(i int, conditionType, conditionStatus string) bool { - return false + return readyStatusMatches(conditionType, conditionStatus) } diff --git a/cmd/flux/get_alertprovider.go b/cmd/flux/get_alertprovider.go index 11d50cb3..3119c88a 100644 --- a/cmd/flux/get_alertprovider.go +++ b/cmd/flux/get_alertprovider.go @@ -88,5 +88,5 @@ func (s alertProviderListAdapter) headers(includeNamespace bool) []string { } func (s alertProviderListAdapter) statusSelectorMatches(i int, conditionType, conditionStatus string) bool { - return false + return readyStatusMatches(conditionType, conditionStatus) } diff --git a/cmd/flux/get_test.go b/cmd/flux/get_test.go index 90e77ce2..0281cc75 100644 --- a/cmd/flux/get_test.go +++ b/cmd/flux/get_test.go @@ -103,6 +103,39 @@ func Test_GetCmdStatusSelector(t *testing.T) { } } +func Test_GetCmdStatusSelectorSyntheticReady(t *testing.T) { + tmpl := map[string]string{ + "fluxns": allocateNamespace("flux-system"), + } + testEnv.CreateObjectFile("./testdata/get/notification_objects.yaml", tmpl, t) + + commands := []string{ + "get alerts", + "get alert-providers", + "get all", + } + for _, command := range commands { + t.Run(command, func(t *testing.T) { + unfilteredOutput, err := executeCommand(command + " -n " + tmpl["fluxns"]) + if err != nil { + t.Fatalf("%s failed: %v", command, err) + } + if unfilteredOutput == "" { + t.Fatalf("expected %s output for namespace with notification objects", command) + } + + filteredOutput, err := executeCommand(command + " --status-selector Ready=True -n " + tmpl["fluxns"]) + if err != nil { + t.Fatalf("%s with Ready=True status selector failed: %v", command, err) + } + + if filteredOutput != unfilteredOutput { + t.Fatalf("expected Ready=True filtered output to match unfiltered output:\nfiltered:\n%s\nunfiltered:\n%s", filteredOutput, unfilteredOutput) + } + }) + } +} + func Test_GetAllCmdStatusSelectorNoMatches(t *testing.T) { tmpl := map[string]string{ "fluxns": allocateNamespace("flux-system"), diff --git a/cmd/flux/testdata/get/notification_objects.yaml b/cmd/flux/testdata/get/notification_objects.yaml new file mode 100644 index 00000000..abdb7af3 --- /dev/null +++ b/cmd/flux/testdata/get/notification_objects.yaml @@ -0,0 +1,31 @@ +--- +apiVersion: v1 +kind: Namespace +metadata: + name: {{ .fluxns }} +--- +apiVersion: notification.toolkit.fluxcd.io/v1beta3 +kind: Provider +metadata: + name: slack + namespace: {{ .fluxns }} +spec: + address: https://hooks.slack.com/services/mock + channel: alerts + type: slack +--- +apiVersion: notification.toolkit.fluxcd.io/v1beta3 +kind: Alert +metadata: + name: flux-system + namespace: {{ .fluxns }} +spec: + eventSeverity: info + eventSources: + - kind: GitRepository + name: '*' + - kind: Kustomization + name: '*' + providerRef: + name: slack + summary: Slack notification