diff --git a/cmd/flux/get.go b/cmd/flux/get.go index 10ca5fad..ce44ca62 100644 --- a/cmd/flux/get.go +++ b/cmd/flux/get.go @@ -39,8 +39,9 @@ var getCmd = &cobra.Command{ } type GetFlags struct { - allNamespaces bool - noHeader bool + allNamespaces bool + noHeader bool + statusSelector string } var getArgs GetFlags @@ -49,6 +50,8 @@ func init() { getCmd.PersistentFlags().BoolVarP(&getArgs.allNamespaces, "all-namespaces", "A", false, "list the requested object(s) across all namespaces") getCmd.PersistentFlags().BoolVarP(&getArgs.noHeader, "no-header", "", false, "skip the header when printing the results") + getCmd.PersistentFlags().StringVar(&getArgs.statusSelector, "status-selector", "", + "specify the status condition name and the desired state to filter the get result") rootCmd.AddCommand(getCmd) } @@ -56,6 +59,7 @@ type summarisable interface { listAdapter summariseItem(i int, includeNamespace bool, includeKind bool) []string headers(includeNamespace bool) []string + statusSelectorMatches(i int, conditionType, conditionStatus string) bool } // --- these help with implementations of summarisable @@ -67,6 +71,20 @@ func statusAndMessage(conditions []metav1.Condition) (string, string) { return string(metav1.ConditionFalse), "waiting to be reconciled" } +func statusMatches(conditionType, conditionStatus string, conditions []metav1.Condition) bool { + // we don't use apimeta.FindStatusCondition because we'd like to use EqualFold to compare two strings + var c *metav1.Condition + for i := range conditions { + if strings.EqualFold(conditions[i].Type, conditionType) { + c = &conditions[i] + } + } + if c != nil { + return strings.EqualFold(string(c.Status), conditionStatus) + } + return false +} + func nameColumns(item named, includeNamespace bool, includeKind bool) []string { name := item.GetName() if includeKind { @@ -123,10 +141,23 @@ func (get getCommand) run(cmd *cobra.Command, args []string) error { if !getArgs.noHeader { header = get.list.headers(getArgs.allNamespaces) } + noFilter := true + var conditionType, conditionStatus string + if getArgs.statusSelector != "" { + parts := strings.SplitN(getArgs.statusSelector, "=", 2) + if len(parts) != 2 { + return fmt.Errorf("expected status selector in type=status format, but found: %s", getArgs.statusSelector) + } + conditionType = parts[0] + conditionStatus = parts[1] + noFilter = false + } var rows [][]string for i := 0; i < get.list.len(); i++ { - row := get.list.summariseItem(i, getArgs.allNamespaces, getAll) - rows = append(rows, row) + if noFilter || get.list.statusSelectorMatches(i, conditionType, conditionStatus) { + row := get.list.summariseItem(i, getArgs.allNamespaces, getAll) + rows = append(rows, row) + } } utils.PrintTable(os.Stdout, header, rows) diff --git a/cmd/flux/get_alert.go b/cmd/flux/get_alert.go index 4b4f5478..91671967 100644 --- a/cmd/flux/get_alert.go +++ b/cmd/flux/get_alert.go @@ -55,3 +55,8 @@ func (s alertListAdapter) headers(includeNamespace bool) []string { } return headers } + +func (s alertListAdapter) statusSelectorMatches(i int, conditionType, conditionStatus string) bool { + item := s.Items[i] + return statusMatches(conditionType, conditionStatus, item.Status.Conditions) +} diff --git a/cmd/flux/get_alertprovider.go b/cmd/flux/get_alertprovider.go index 05128b53..917a0d99 100644 --- a/cmd/flux/get_alertprovider.go +++ b/cmd/flux/get_alertprovider.go @@ -52,3 +52,8 @@ func (s alertProviderListAdapter) headers(includeNamespace bool) []string { } return headers } + +func (s alertProviderListAdapter) statusSelectorMatches(i int, conditionType, conditionStatus string) bool { + item := s.Items[i] + return statusMatches(conditionType, conditionStatus, item.Status.Conditions) +} diff --git a/cmd/flux/get_helmrelease.go b/cmd/flux/get_helmrelease.go index 8737b93f..04822afa 100644 --- a/cmd/flux/get_helmrelease.go +++ b/cmd/flux/get_helmrelease.go @@ -56,3 +56,8 @@ func (a helmReleaseListAdapter) headers(includeNamespace bool) []string { } return headers } + +func (a helmReleaseListAdapter) statusSelectorMatches(i int, conditionType, conditionStatus string) bool { + item := a.Items[i] + return statusMatches(conditionType, conditionStatus, item.Status.Conditions) +} diff --git a/cmd/flux/get_image_policy.go b/cmd/flux/get_image_policy.go index 9136ffaa..d1a8f194 100644 --- a/cmd/flux/get_image_policy.go +++ b/cmd/flux/get_image_policy.go @@ -54,3 +54,8 @@ func (s imagePolicyListAdapter) headers(includeNamespace bool) []string { } return headers } + +func (s imagePolicyListAdapter) statusSelectorMatches(i int, conditionType, conditionStatus string) bool { + item := s.Items[i] + return statusMatches(conditionType, conditionStatus, item.Status.Conditions) +} diff --git a/cmd/flux/get_image_repository.go b/cmd/flux/get_image_repository.go index 23461f21..2ffe2dc9 100644 --- a/cmd/flux/get_image_repository.go +++ b/cmd/flux/get_image_repository.go @@ -63,3 +63,8 @@ func (s imageRepositoryListAdapter) headers(includeNamespace bool) []string { } return headers } + +func (s imageRepositoryListAdapter) statusSelectorMatches(i int, conditionType, conditionStatus string) bool { + item := s.Items[i] + return statusMatches(conditionType, conditionStatus, item.Status.Conditions) +} diff --git a/cmd/flux/get_image_update.go b/cmd/flux/get_image_update.go index d6a5e540..2232b419 100644 --- a/cmd/flux/get_image_update.go +++ b/cmd/flux/get_image_update.go @@ -62,3 +62,8 @@ func (s imageUpdateAutomationListAdapter) headers(includeNamespace bool) []strin } return headers } + +func (s imageUpdateAutomationListAdapter) statusSelectorMatches(i int, conditionType, conditionStatus string) bool { + item := s.Items[i] + return statusMatches(conditionType, conditionStatus, item.Status.Conditions) +} diff --git a/cmd/flux/get_kustomization.go b/cmd/flux/get_kustomization.go index 0961763e..f697fd9c 100644 --- a/cmd/flux/get_kustomization.go +++ b/cmd/flux/get_kustomization.go @@ -57,3 +57,8 @@ func (a kustomizationListAdapter) headers(includeNamespace bool) []string { } return headers } + +func (a kustomizationListAdapter) statusSelectorMatches(i int, conditionType, conditionStatus string) bool { + item := a.Items[i] + return statusMatches(conditionType, conditionStatus, item.Status.Conditions) +} diff --git a/cmd/flux/get_receiver.go b/cmd/flux/get_receiver.go index 4e72446e..f66af1ba 100644 --- a/cmd/flux/get_receiver.go +++ b/cmd/flux/get_receiver.go @@ -55,3 +55,8 @@ func (s receiverListAdapter) headers(includeNamespace bool) []string { } return headers } + +func (s receiverListAdapter) statusSelectorMatches(i int, conditionType, conditionStatus string) bool { + item := s.Items[i] + return statusMatches(conditionType, conditionStatus, item.Status.Conditions) +} diff --git a/cmd/flux/get_source_bucket.go b/cmd/flux/get_source_bucket.go index 58b55acc..dd0c767d 100644 --- a/cmd/flux/get_source_bucket.go +++ b/cmd/flux/get_source_bucket.go @@ -62,3 +62,8 @@ func (a bucketListAdapter) headers(includeNamespace bool) []string { } return headers } + +func (a bucketListAdapter) statusSelectorMatches(i int, conditionType, conditionStatus string) bool { + item := a.Items[i] + return statusMatches(conditionType, conditionStatus, item.Status.Conditions) +} diff --git a/cmd/flux/get_source_chart.go b/cmd/flux/get_source_chart.go index 3439034e..476bb22f 100644 --- a/cmd/flux/get_source_chart.go +++ b/cmd/flux/get_source_chart.go @@ -62,3 +62,8 @@ func (a helmChartListAdapter) headers(includeNamespace bool) []string { } return headers } + +func (a helmChartListAdapter) statusSelectorMatches(i int, conditionType, conditionStatus string) bool { + item := a.Items[i] + return statusMatches(conditionType, conditionStatus, item.Status.Conditions) +} diff --git a/cmd/flux/get_source_git.go b/cmd/flux/get_source_git.go index f58994c9..c2366806 100644 --- a/cmd/flux/get_source_git.go +++ b/cmd/flux/get_source_git.go @@ -62,3 +62,8 @@ func (a gitRepositoryListAdapter) headers(includeNamespace bool) []string { } return headers } + +func (a gitRepositoryListAdapter) statusSelectorMatches(i int, conditionType, conditionStatus string) bool { + item := a.Items[i] + return statusMatches(conditionType, conditionStatus, item.Status.Conditions) +} diff --git a/cmd/flux/get_source_helm.go b/cmd/flux/get_source_helm.go index 1c2f64e9..9bbb8522 100644 --- a/cmd/flux/get_source_helm.go +++ b/cmd/flux/get_source_helm.go @@ -62,3 +62,8 @@ func (a helmRepositoryListAdapter) headers(includeNamespace bool) []string { } return headers } + +func (a helmRepositoryListAdapter) statusSelectorMatches(i int, conditionType, conditionStatus string) bool { + item := a.Items[i] + return statusMatches(conditionType, conditionStatus, item.Status.Conditions) +}