Skip to content

Commit

Permalink
Add support for filtering/sorting by array index
Browse files Browse the repository at this point in the history
For an object like

```
"status": {
    "podIPs": [
        "10.0.0.1",
        "10.0.0.2",
        "10.0.0.3",
    ]
}
```

add the ability to filter or sort by a single element in the array list:

```
GET /pods?filter=status.podIPs.2=10.0.0.2
GET /pods?sort=status.podIPs.2
```
  • Loading branch information
cmurphy committed Sep 19, 2023
1 parent 7e38c1d commit 6402cd4
Show file tree
Hide file tree
Showing 3 changed files with 197 additions and 2 deletions.
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ replace (
github.com/crewjam/saml => github.com/rancher/saml v0.2.0
github.com/knative/pkg => github.com/rancher/pkg v0.0.0-20181214184433-b04c0947ad2f
github.com/matryer/moq => github.com/rancher/moq v0.0.0-20190404221404-ee5226d43009
github.com/rancher/wrangler => github.com/cmurphy/wrangler v0.8.1-0.20230919185257-312ca830e7fd
k8s.io/client-go => github.com/rancher/client-go v1.27.4-rancher1
)

Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,8 @@ github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWR
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
github.com/cmurphy/wrangler v0.8.1-0.20230919185257-312ca830e7fd h1:bSqOT9et6EkS5ZK42hijGLju2fJYlyHcwD5wKhU/88U=
github.com/cmurphy/wrangler v0.8.1-0.20230919185257-312ca830e7fd/go.mod h1:0oPjv01nvzeavcmeuT0xMlGKs9IJaNk5NCPPQq1n8Ro=
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
Expand Down Expand Up @@ -525,8 +527,6 @@ github.com/rancher/norman v0.0.0-20230831160711-5de27f66385d h1:Ft/iTH91TlE2oBGm
github.com/rancher/norman v0.0.0-20230831160711-5de27f66385d/go.mod h1:Sm2Xqai+aecgmJ86ygyEe+TdPMLkauEpykSstBAu4Ko=
github.com/rancher/remotedialer v0.3.0 h1:y1EO8JCsgZo0RcqTUp6U8FXcBAv27R+TLnWRcpvX1sM=
github.com/rancher/remotedialer v0.3.0/go.mod h1:BwwztuvViX2JrLLUwDlsYt5DiyUwHLlzynRwkZLAY0Q=
github.com/rancher/wrangler v1.1.1-0.20230831050635-df1bd5aae9df h1:WJ+aaUICHPX8HeLmHE9JL/RFHhilMfcJlqmhgpc7gJU=
github.com/rancher/wrangler v1.1.1-0.20230831050635-df1bd5aae9df/go.mod h1:4T80p+rLh2OLbjCjdExIjRHKNBgK9NUAd7eIU/gRPKk=
github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
Expand Down
194 changes: 194 additions & 0 deletions pkg/stores/partition/listprocessor/processor_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -829,6 +829,100 @@ func TestFilterList(t *testing.T) {
},
},
},
{
name: "match element in array",
objects: [][]unstructured.Unstructured{
{
{
Object: map[string]interface{}{
"kind": "fruit",
"metadata": map[string]interface{}{
"name": "apple",
},
"data": map[string]interface{}{
"colors": []interface{}{
"pink",
"red",
"green",
"yellow",
},
},
},
},
{
Object: map[string]interface{}{
"kind": "fruit",
"metadata": map[string]interface{}{
"name": "berry",
},
"data": map[string]interface{}{
"colors": []interface{}{
"blue",
"red",
"black",
},
},
},
},
{
Object: map[string]interface{}{
"kind": "fruit",
"metadata": map[string]interface{}{
"name": "banana",
},
"data": map[string]interface{}{
"colors": []interface{}{
"yellow",
},
},
},
},
},
},
filters: []OrFilter{
{
filters: []Filter{
{
field: []string{"data", "colors", "1"},
match: "red",
},
},
},
},
want: []unstructured.Unstructured{
{
Object: map[string]interface{}{
"kind": "fruit",
"metadata": map[string]interface{}{
"name": "apple",
},
"data": map[string]interface{}{
"colors": []interface{}{
"pink",
"red",
"green",
"yellow",
},
},
},
},
{
Object: map[string]interface{}{
"kind": "fruit",
"metadata": map[string]interface{}{
"name": "berry",
},
"data": map[string]interface{}{
"colors": []interface{}{
"blue",
"red",
"black",
},
},
},
},
},
},
{
name: "single or filter, filter on one value",
objects: [][]unstructured.Unstructured{
Expand Down Expand Up @@ -2364,6 +2458,106 @@ func TestSortList(t *testing.T) {
},
},
},
{
name: "sort by array index",
objects: []unstructured.Unstructured{
{
Object: map[string]interface{}{
"kind": "apple",
"metadata": map[string]interface{}{
"name": "fuji",
},
"data": map[string]interface{}{
"attributes": []interface{}{
"small",
"pink",
"sweet",
},
},
},
},
{
Object: map[string]interface{}{
"kind": "apple",
"metadata": map[string]interface{}{
"name": "red-delicious",
},
"data": map[string]interface{}{
"attributes": []interface{}{
"large",
"red",
"bland",
},
},
},
},
{
Object: map[string]interface{}{
"kind": "apple",
"metadata": map[string]interface{}{
"name": "granny-smith",
},
"data": map[string]interface{}{
"attributes": []interface{}{
"medium",
"green",
"tart",
},
},
},
},
},
sort: Sort{
primaryField: []string{"data", "attributes", "1"},
},
want: []unstructured.Unstructured{
{
Object: map[string]interface{}{
"kind": "apple",
"metadata": map[string]interface{}{
"name": "granny-smith",
},
"data": map[string]interface{}{
"attributes": []interface{}{
"medium",
"green",
"tart",
},
},
},
},
{
Object: map[string]interface{}{
"kind": "apple",
"metadata": map[string]interface{}{
"name": "fuji",
},
"data": map[string]interface{}{
"attributes": []interface{}{
"small",
"pink",
"sweet",
},
},
},
},
{
Object: map[string]interface{}{
"kind": "apple",
"metadata": map[string]interface{}{
"name": "red-delicious",
},
"data": map[string]interface{}{
"attributes": []interface{}{
"large",
"red",
"bland",
},
},
},
},
},
},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
Expand Down

0 comments on commit 6402cd4

Please sign in to comment.