Skip to content

Commit

Permalink
Support --selector filter expressions (#23)
Browse files Browse the repository at this point in the history
You can now configure a `--selector` to use when querying the cluster
from `check`.

```yaml
source:
  filter:
    selector: app=my-app
```

Any valid label selector(s) can be specified, including combinations
using a comma separator.

```yaml
source:
  filter:
    selector: app=my-app,app.kubernetes.io/component in (frontend, backend)
```

See https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#label-selectors
Closes #21
  • Loading branch information
jgriff authored Sep 17, 2021
1 parent 59302fb commit d7d13e9
Show file tree
Hide file tree
Showing 5 changed files with 34 additions and 3 deletions.
8 changes: 8 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,14 @@ with a general purpose `put` for running any `kubectl` command.
For `check`/`get`, this will default to all namespaces (`--all-namespaces`). \
For `put`, this will default to remaining unset (not specified), but can be overridden with a step param (see [below](#out-execute-a-kubectl-command)).
* `filter`: _Optional_. Can contain any/all of the following criteria:
* `selector`: Specify a label `--selector` for the query. Can use any valid [label selector expression](https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#label-selectors). Defaults to empty.
```yaml
source:
filter:
selector: app=my-app,app.kubernetes.io/component in (frontend, backend)
```
**Note:** _Selectors are the only filter that are performed server-side, and can help cull down the response before it passes through the rest of the filters (below).
This can speed up `check` operations when dealing with a potentially large volume of resources._
* `name`: Matches against the `metadata.name` of the resource. Supports both literal (`my-ns-1`) and regular expressions (`"my-ns-[0-9]*$"`).
```yaml
source:
Expand Down
4 changes: 2 additions & 2 deletions assets/check
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@ queryForVersions() {
log "${red}Warning:${reset} No namespace configured! Defaulting to ${blue}--all-namespaces${reset}."
namespace_arg="--all-namespaces"
fi
log -p "\n--> querying k8s cluster ${blue}${source_url}${reset} in namespace ${blue}$(namespace)${reset} for ${yellow}${source_resource_types}${reset} resources..."
new_versions=$(kubectl --server=${source_url} --token=${source_token} ${certificate_arg} get ${source_resource_types} ${namespace_arg} --sort-by='{.metadata.resourceVersion}' -o json | jq '[.items[]]' ) || exit $1
log -p "\n--> querying k8s cluster ${blue}${source_url}${reset} in namespace ${blue}$(namespace)${reset} for ${yellow}${source_resource_types}${reset} resources with selector ${cyan}${source_filter_selector}${reset}..."
new_versions=$(kubectl --server=${source_url} --token=${source_token} ${certificate_arg} get ${source_resource_types} ${namespace_arg} --selector="${source_filter_selector}" --sort-by='{.metadata.resourceVersion}' -o json | jq '[.items[]]' ) || exit $1
log "$new_versions"
}

Expand Down
3 changes: 3 additions & 0 deletions assets/common
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,9 @@ source_namespace=$(jq -r '.source.namespace | select(.!=null)' < $payload)
source_sensitive=$(jq -r '.source.sensitive | select(.!=null)' < $payload)
source_insecure_skip_tls_verify=$(jq -r '.source.insecure_skip_tls_verify // false' < $payload)

# source filter config
source_filter_selector=$(jq -r '.source.filter.selector | select(. != null)' < $payload)

# params config
params_kubectl=$(jq -r '.params.kubectl | select(.!=null)' < $payload)
params_namespace=$(jq -r '.params.namespace | select(.!=null)' < $payload)
Expand Down
15 changes: 14 additions & 1 deletion test/check.bats
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ source_check() {

# mock kubectl to return our expected response
local expected_kubectl_args="--server=$source_url --token=$source_token ${expected_ca_arg:---certificate-authority=$source_ca_file} \
get $source_resource_types ${expected_namespace_arg:---all-namespaces} --sort-by={.metadata.resourceVersion} -o json"
get $source_resource_types ${expected_namespace_arg:---all-namespaces} --selector=${expected_selector_arg} --sort-by={.metadata.resourceVersion} -o json"

if [ $kubectl_response == "FAIL" ]; then
stub kubectl "$expected_kubectl_args : exit 1"
Expand Down Expand Up @@ -708,3 +708,16 @@ teardown() {
assert_equal "$(jq -r '.[1].metadata.name' <<< "$new_versions")" 'namespace-2'
assert_equal "$(jq -r '.[2].metadata.name' <<< "$new_versions")" 'namespace-other'
}

@test "[check] GH-21 filter by selector includes --selector arg to kubectl" {
expected_selector_arg="app=my-app"
source_check "stdin-source-filter-selector"

queryForVersions

# note that we mock the response, so it doesn't have to "make sense"... just that our mock matched our expected args (and therefore returned our mock response)
assert_equal $(jq length <<< "$new_versions") 3
assert_equal "$(jq -r '.[0].metadata.name' <<< "$new_versions")" 'namespace-1'
assert_equal "$(jq -r '.[1].metadata.name' <<< "$new_versions")" 'namespace-2'
assert_equal "$(jq -r '.[2].metadata.name' <<< "$new_versions")" 'namespace-other'
}
7 changes: 7 additions & 0 deletions test/fixtures/stdin-source-filter-selector.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"source": {
"filter": {
"selector": "app=my-app"
}
}
}

0 comments on commit d7d13e9

Please sign in to comment.