From 1be006a45fc6fe9cd67ce42bf6762c82a2c4aa9e Mon Sep 17 00:00:00 2001 From: Chanwit Kaewkasi Date: Tue, 6 Jul 2021 22:52:33 +0700 Subject: [PATCH 1/2] implement status selector Signed-off-by: Chanwit Kaewkasi --- cmd/flux/get.go | 39 ++++++++++++++++++++++++++++---- cmd/flux/get_alert.go | 5 ++++ cmd/flux/get_alertprovider.go | 5 ++++ cmd/flux/get_helmrelease.go | 5 ++++ cmd/flux/get_image_policy.go | 5 ++++ cmd/flux/get_image_repository.go | 5 ++++ cmd/flux/get_image_update.go | 5 ++++ cmd/flux/get_kustomization.go | 5 ++++ cmd/flux/get_receiver.go | 5 ++++ cmd/flux/get_source_bucket.go | 5 ++++ cmd/flux/get_source_chart.go | 5 ++++ cmd/flux/get_source_git.go | 5 ++++ cmd/flux/get_source_helm.go | 5 ++++ 13 files changed, 95 insertions(+), 4 deletions(-) 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) +} From d8911e0c77d7fa4d1b970125b3888f7476e49fa6 Mon Sep 17 00:00:00 2001 From: Chanwit Kaewkasi Date: Wed, 7 Jul 2021 14:19:37 +0700 Subject: [PATCH 2/2] add an example to the status-selector flag's description Co-authored-by: Stefan Prodan Signed-off-by: Chanwit Kaewkasi --- cmd/flux/get.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/flux/get.go b/cmd/flux/get.go index ce44ca62..37c267a6 100644 --- a/cmd/flux/get.go +++ b/cmd/flux/get.go @@ -51,7 +51,7 @@ func init() { "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") + "specify the status condition name and the desired state to filter the get result, e.g. ready=false") rootCmd.AddCommand(getCmd) }