mirror of
https://github.com/fluxcd/flux2.git
synced 2026-06-28 18:05:08 +00:00
Merge pull request #5952 from 3uzbcqje/status-selector-negation
Some checks failed
e2e-bootstrap / e2e-boostrap-github (push) Has been cancelled
e2e / e2e-amd64-kubernetes (push) Has been cancelled
scan / analyze (push) Has been cancelled
update / update-components (push) Has been cancelled
conformance / conform-kubernetes (1.34.1) (push) Has been cancelled
conformance / conform-kubernetes (1.35.2) (push) Has been cancelled
conformance / conform-kubernetes (1.36.1) (push) Has been cancelled
conformance / conform-k3s (1.34.8) (push) Has been cancelled
conformance / conform-k3s (1.35.5) (push) Has been cancelled
conformance / conform-k3s (1.36.1) (push) Has been cancelled
conformance / conform-openshift (4.20.0-okd) (push) Has been cancelled
conformance / conform-openshift (4.21.0-okd) (push) Has been cancelled
ossf / scorecard (push) Has been cancelled
Some checks failed
e2e-bootstrap / e2e-boostrap-github (push) Has been cancelled
e2e / e2e-amd64-kubernetes (push) Has been cancelled
scan / analyze (push) Has been cancelled
update / update-components (push) Has been cancelled
conformance / conform-kubernetes (1.34.1) (push) Has been cancelled
conformance / conform-kubernetes (1.35.2) (push) Has been cancelled
conformance / conform-kubernetes (1.36.1) (push) Has been cancelled
conformance / conform-k3s (1.34.8) (push) Has been cancelled
conformance / conform-k3s (1.35.5) (push) Has been cancelled
conformance / conform-k3s (1.36.1) (push) Has been cancelled
conformance / conform-openshift (4.20.0-okd) (push) Has been cancelled
conformance / conform-openshift (4.21.0-okd) (push) Has been cancelled
ossf / scorecard (push) Has been cancelled
cmd: support `type!=status` in get --status-selector
This commit is contained in:
commit
cd0ffe0151
6 changed files with 140 additions and 6 deletions
|
|
@ -78,7 +78,7 @@ func init() {
|
|||
getCmd.PersistentFlags().BoolVarP(&getArgs.noHeader, "no-header", "", false, "skip the header when printing the results")
|
||||
getCmd.PersistentFlags().BoolVarP(&getArgs.watch, "watch", "w", false, "After listing/getting the requested object, watch for changes.")
|
||||
getCmd.PersistentFlags().StringVar(&getArgs.statusSelector, "status-selector", "",
|
||||
"specify the status condition name and the desired state to filter the get result, e.g. ready=false")
|
||||
"specify the status condition name and the desired state to filter the get result, e.g. ready=false or ready!=true")
|
||||
getCmd.PersistentFlags().StringVarP(&getArgs.labelSelector, "label-selector", "l", "",
|
||||
"filter objects by label selector")
|
||||
rootCmd.AddCommand(getCmd)
|
||||
|
|
@ -228,20 +228,31 @@ func namespaceNameOrAny(allNamespaces bool, namespaceName string) string {
|
|||
}
|
||||
|
||||
func getRowsToPrint(getAll bool, list summarisable) ([][]string, error) {
|
||||
noFilter := true
|
||||
filter := func(i int) bool { return true }
|
||||
var conditionType, conditionStatus string
|
||||
if getArgs.statusSelector != "" {
|
||||
parts := strings.SplitN(getArgs.statusSelector, "=", 2)
|
||||
// Support both type=status (match) and type!=status (negated match).
|
||||
// "!=" must be checked first since it also contains "=".
|
||||
separator := "="
|
||||
filter = func(i int) bool {
|
||||
return list.statusSelectorMatches(i, conditionType, conditionStatus)
|
||||
}
|
||||
if strings.Contains(getArgs.statusSelector, "!=") {
|
||||
separator = "!="
|
||||
filter = func(i int) bool {
|
||||
return !list.statusSelectorMatches(i, conditionType, conditionStatus)
|
||||
}
|
||||
}
|
||||
parts := strings.SplitN(getArgs.statusSelector, separator, 2)
|
||||
if len(parts) != 2 {
|
||||
return nil, fmt.Errorf("expected status selector in type=status format, but found: %s", getArgs.statusSelector)
|
||||
return nil, fmt.Errorf("expected status selector in type=status or type!=status format, but found: %s", getArgs.statusSelector)
|
||||
}
|
||||
conditionType = parts[0]
|
||||
conditionStatus = parts[1]
|
||||
noFilter = false
|
||||
}
|
||||
var rows [][]string
|
||||
for i := 0; i < list.len(); i++ {
|
||||
if noFilter || list.statusSelectorMatches(i, conditionType, conditionStatus) {
|
||||
if filter(i) {
|
||||
row := list.summariseItem(i, getArgs.allNamespaces, getAll)
|
||||
rows = append(rows, row)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -63,6 +63,46 @@ func Test_GetCmd(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func Test_GetCmdStatusSelector(t *testing.T) {
|
||||
tmpl := map[string]string{
|
||||
"fluxns": allocateNamespace("flux-system"),
|
||||
}
|
||||
testEnv.CreateObjectFile("./testdata/get/status_objects.yaml", tmpl, t)
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
args string
|
||||
expected string
|
||||
}{
|
||||
{
|
||||
name: "equal status selector matches one",
|
||||
args: "--status-selector Ready=True",
|
||||
expected: "testdata/get/get_status_ready_true.golden",
|
||||
},
|
||||
{
|
||||
name: "equal status selector matches false",
|
||||
args: "--status-selector Ready=False",
|
||||
expected: "testdata/get/get_status_ready_false.golden",
|
||||
},
|
||||
{
|
||||
name: "not-equal status selector matches all not-true",
|
||||
args: "--status-selector Ready!=True",
|
||||
expected: "testdata/get/get_status_ready_not_true.golden",
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
cmd := cmdTestCase{
|
||||
args: "get sources git " + tt.args + " -n " + tmpl["fluxns"],
|
||||
assert: assertGoldenTemplateFile(tt.expected, nil),
|
||||
}
|
||||
|
||||
cmd.runTestCmd(t)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func Test_GetCmdErrors(t *testing.T) {
|
||||
tmpl := map[string]string{
|
||||
"fluxns": allocateNamespace("flux-system"),
|
||||
|
|
@ -84,6 +124,11 @@ func Test_GetCmdErrors(t *testing.T) {
|
|||
args: "get helmrelease -n " + tmpl["fluxns"],
|
||||
assert: assertError(fmt.Sprintf("no HelmRelease objects found in \"%s\" namespace", tmpl["fluxns"])),
|
||||
},
|
||||
{
|
||||
name: "malformed status selector",
|
||||
args: "get sources git --status-selector Ready -n " + tmpl["fluxns"],
|
||||
assert: assertError("expected status selector in type=status or type!=status format, but found: Ready"),
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
|
|
|
|||
2
cmd/flux/testdata/get/get_status_ready_false.golden
vendored
Normal file
2
cmd/flux/testdata/get/get_status_ready_false.golden
vendored
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
NAME REVISION SUSPENDED READY MESSAGE
|
||||
gr-failed False False failed to checkout and determine revision
|
||||
3
cmd/flux/testdata/get/get_status_ready_not_true.golden
vendored
Normal file
3
cmd/flux/testdata/get/get_status_ready_not_true.golden
vendored
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
NAME REVISION SUSPENDED READY MESSAGE
|
||||
gr-failed False False failed to checkout and determine revision
|
||||
gr-unknown False Unknown reconciliation in progress
|
||||
2
cmd/flux/testdata/get/get_status_ready_true.golden
vendored
Normal file
2
cmd/flux/testdata/get/get_status_ready_true.golden
vendored
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
NAME REVISION SUSPENDED READY MESSAGE
|
||||
gr-ready main@sha1:696f056d False True Fetched revision: main@sha1:696f056d
|
||||
71
cmd/flux/testdata/get/status_objects.yaml
vendored
Normal file
71
cmd/flux/testdata/get/status_objects.yaml
vendored
Normal file
|
|
@ -0,0 +1,71 @@
|
|||
---
|
||||
apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
name: {{ .fluxns }}
|
||||
---
|
||||
apiVersion: source.toolkit.fluxcd.io/v1
|
||||
kind: GitRepository
|
||||
metadata:
|
||||
name: gr-failed
|
||||
namespace: {{ .fluxns }}
|
||||
spec:
|
||||
ref:
|
||||
branch: main
|
||||
secretRef:
|
||||
name: flux-system
|
||||
url: ssh://git@github.com/example/repo
|
||||
interval: 5m
|
||||
status:
|
||||
conditions:
|
||||
- lastTransitionTime: "2021-07-20T00:48:16Z"
|
||||
message: 'failed to checkout and determine revision'
|
||||
reason: GitOperationFailed
|
||||
status: "False"
|
||||
type: Ready
|
||||
---
|
||||
apiVersion: source.toolkit.fluxcd.io/v1
|
||||
kind: GitRepository
|
||||
metadata:
|
||||
name: gr-ready
|
||||
namespace: {{ .fluxns }}
|
||||
spec:
|
||||
ref:
|
||||
branch: main
|
||||
secretRef:
|
||||
name: flux-system
|
||||
url: ssh://git@github.com/example/repo
|
||||
interval: 5m
|
||||
status:
|
||||
artifact:
|
||||
lastUpdateTime: "2021-08-01T04:28:42Z"
|
||||
revision: main@sha1:696f056df216eea4f9401adbee0ff744d4df390f
|
||||
path: "example"
|
||||
url: "example"
|
||||
digest: sha1:696f056df216eea4f9401adbee0ff744d4df390f
|
||||
conditions:
|
||||
- lastTransitionTime: "2021-07-20T00:48:16Z"
|
||||
message: 'Fetched revision: main@sha1:696f056df216eea4f9401adbee0ff744d4df390f'
|
||||
reason: GitOperationSucceed
|
||||
status: "True"
|
||||
type: Ready
|
||||
---
|
||||
apiVersion: source.toolkit.fluxcd.io/v1
|
||||
kind: GitRepository
|
||||
metadata:
|
||||
name: gr-unknown
|
||||
namespace: {{ .fluxns }}
|
||||
spec:
|
||||
ref:
|
||||
branch: main
|
||||
secretRef:
|
||||
name: flux-system
|
||||
url: ssh://git@github.com/example/repo
|
||||
interval: 5m
|
||||
status:
|
||||
conditions:
|
||||
- lastTransitionTime: "2021-07-20T00:48:16Z"
|
||||
message: 'reconciliation in progress'
|
||||
reason: Progressing
|
||||
status: "Unknown"
|
||||
type: Ready
|
||||
Loading…
Add table
Add a link
Reference in a new issue