Skip to content

Commit

Permalink
Allow both single-quoted and double-quoted value matching, doc differ…
Browse files Browse the repository at this point in the history
…ence.
  • Loading branch information
ericpromislow committed Jan 17, 2025
1 parent 21c93d2 commit 7dd7067
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 11 deletions.
19 changes: 18 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ is empty.
#### `filter`

Filter results by a designated field. Filter keys use dot notation to denote
the subfield of an object to filter on. The filter value is matched as a
the subfield of an object to filter on. The filter value is normally matched as a
substring.

Example, filtering by object name:
Expand All @@ -117,6 +117,23 @@ Example, filtering by object name:
/v1/{type}?filter=metadata.name=foo
```

if a target value is surrounded by single-quotes, it succeeds only on an exact match:

Example, filtering by object name:

```
/v1/{type}?filter=metadata.name='match-this-exactly'
```
```
A target value can be delimited by double-quotes, but this will succeed on a partial match:
Example, filtering by object name:
```
/v1/{type}?filter=metadata.name="can-be-a-substri"
```
One filter can list multiple possible fields to match, these are ORed together:
```
Expand Down
24 changes: 16 additions & 8 deletions pkg/stores/sqlpartition/listprocessor/processor.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,18 +76,23 @@ func k8sOpToRancherOp(k8sOp selection.Operator) (informer.Op, error) {
}

// Determine if the value field is surrounded by a pair of single- or double-quotes
// This is a difference we implement from the CLI: if the target value of a (not) equal
// test is quoted, we use the full string. Otherwise we do a substring match
// This is a difference we implement from the kubernetes CLI: if the target value of a (not) equal
// test is single-quoted, we use the full string. Otherwise we do a substring match
// (which is implemented as 'SELECT ... some-field ... LIKE "%VALUE%" ...' in the query)
func isQuotedStringTarget(values []string) bool {
//
// The caller also needs to know if it should strip delimiting quotes, so this returns two bools
func isQuotedStringTarget(values []string) (isQuoted bool, isSingleQuoted bool) {
if len(values) != 1 || len(values[0]) == 0 {
return false
return false, false
}
s1 := values[0][0:1]
if !strings.Contains(`"'`, s1) {
return false
return false, false
}
return strings.HasSuffix(values[0], s1)
if !strings.HasSuffix(values[0], s1) {
return false, false
}
return true, s1[0] == '\''
}

// k8sRequirementToOrFilter - convert one k8s Requirement to a list of Filter's:
Expand All @@ -100,10 +105,13 @@ func k8sRequirementToOrFilter(requirement queryparser.Requirement) (informer.Fil
return informer.Filter{}, err
}
usePartialMatch := true
if isQuotedStringTarget(values) {
usePartialMatch = false
isQuoted, isSingleQuoted := isQuotedStringTarget(values)
if isQuoted {
// Strip off the quotes
values[0] = values[0][1 : len(values[0])-1]
if isSingleQuoted {
usePartialMatch = false
}
}
return informer.Filter{
Field: queryFields,
Expand Down
4 changes: 2 additions & 2 deletions pkg/stores/sqlpartition/listprocessor/processor_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -259,7 +259,7 @@ func TestParseQuery(t *testing.T) {
},
})
tests = append(tests, testCase{
description: "ParseQuery() with filter param set, with value in double quotes, should include filter with partial set to false in list options.",
description: "ParseQuery() with filter param set, with value in double quotes, should include filter with partial set to true in list options.",
req: &types.APIRequest{
Request: &http.Request{
URL: &url.URL{RawQuery: `filter=a1="c1"`},
Expand All @@ -274,7 +274,7 @@ func TestParseQuery(t *testing.T) {
Field: []string{"a1"},
Matches: []string{"c1"},
Op: informer.Eq,
Partial: false,
Partial: true,
},
},
},
Expand Down

0 comments on commit 7dd7067

Please sign in to comment.