How to show all deployments/daemonsets which mount specific configmap/secret? - kubernetes

Sometimes, I want to explore all deployments/daemonsets which mount specific configmap/secret.
Is there any way can achieve this by kubectl?

You need to have jq to do such a complex queries.
Here you go:
kubectl get -o json deploy,daemonset | jq '[.items[] | . as $parent | .spec.template.spec.volumes[]? | select(.configMap != null) | {kind:$parent.kind, name:$parent.metadata.name, configMap:.configMap.name}]'
The jq command de-constructed:
[ // output as array
.items[] // iterate over root key 'items'
|
. as $parent // store the current entry as $parent to refer to it later
|
.spec.template.spec.volumes[]? // iterate over its volumes (the ? to prevent error if there is no volume
|
select(.configMap != null) // select only those volumes with configMap key
|
{kind:$parent.kind, name:$parent.metadata.name, configMap:.configMap.name} // now construct the output using $parent's kind and name and the configMap's name
]
Example output:
[
{
"kind": "Deployment",
"name": "telemetry-agent",
"configMap": "telemetry-config-map"
},
{
"kind": "DaemonSet",
"name": "fluent-bit",
"configMap": "fluent-bit"
},
{
"kind": "DaemonSet",
"name": "telegraf",
"configMap": "telegraf"
}
]
N.B. If you want to find specific configMap, just replace the select() clause .configMap != null to .configMap.name == "specific-configmap". Also, feel free to add --all-namespaces to the kubectl get command if you want to query from all namespaces

Related

Kubectl json path select a field with special characters

I want to write a kubectl command to query all the namespace and then collect the value of a specific lable.
{
"apiVersion": "v1",
"items": [
{
"apiVersion": "v1",
"kind": "Namespace",
"metadata": {
"annotations": {
"kubectl.kubernetes.io/last-applied-configuration": "{\"apiVersion\":\"v1\",\"kind\":\"Namespace\",\"metadata\":{\"annotations\":{},\"labels\":{\"app.kubernetes.io/created-by\":\"testuser\",\"app.kubernetes.io/instance\":\"thisisatest\",\"app.kubernetes.io/name\":\"company\",\"app.kubernetes.io/version\":\"2.5\"},\"name\":\"thisiatest\"}}\n"
},
"creationTimestamp": "2022-09-01T13:16:12Z",
"labels": {
"app.kubernetes.io/created-by": "testuser",
...
I have a version with jq that works.
printf "\ncreated by:\n"
kubectl get namespace -l app.kubernetes.io/name=phoenics -o json | jq '.items [] | .metadata | .labels | ."app.kubernetes.io/created-by"'
But i can't really get a version with jsonpath to work. What am i doing wrong?
printf "\ncreated by: JsonPath\n"
kubectl get namespace -l app.kubernetes.io/name=phoenics -o jsonpath="{range ['items'][*]['metadata']['labels']['app.kubernetes.io/created-by']}{'\n'}{end}"
There is no output. Oh, and i'm working on windows with a git bash.
this should work:
kubectl get namespace -l app.kubernetes.io/name=phoenics \
-o jsonpath="{range .items[*]}{.metadata.labels.app\.kubernetes\.io/created-by}{'\n'}{end}"
No escape sequence required. Tested with k8s 1.22.12:
$ kubectl get namespace -l kubernetes.io/metadata.name=kube-system -o jsonpath="{range ['items'][*]}{['metadata']['labels']}{['kubernetes.io/metadata.name']}{'\n'}{end}"
$ {"kubernetes.io/metadata.name":"kube-system"}

parsing kubectl json output with jq or jsonpath

I would like to select, and list the crds which are containing the "v1beta1" in the
.spec.versions.*.name
The versions part of the crd object looks similar like this
"versions": [
{
"name": "v1alpha2",
"served": true,
"storage": true,
"subresources": {
"status": {}
},
"name": "v1beta1"
"served": true,
"storage": true,
"subresources": {
"status": {}
}
}
]
I tried some different queries like the following, but no success.
$ kubectl get crd -ojson | jq -r '.items[] | map(select(.spec.versions[] | contains("v1beta1"))).metadata.name'
jq: error (at <stdin>:250345): Cannot index string with string "spec"
Jsonpath solution would be also great. I tried something like this without success.
$ kubectl get crd -ojsonpath="{range .items.*.spec.versions.*}{.name[?(#=='v1beta1')].metadata.name}{'\n'}{end}"
Could someone help me please?
This will show the name using jsonpath: kubectl get crd -o jsonpath='{range .items[?(#.spec.versions[].name=="v1beta1")].metadata}{.name}{"\n"}'
You could base a jq solution on:
.spec.versions[] | select(.name | contains("v1beta1"))
or similar, e.g.
.spec.versions[] | select(.name | startswith("v1beta1"))

Getting just a string from a list

How do I just get 1 output from "labels"?
tried doing -o=jsonpath='{.metadata.labels[0]}' in hopes of getting the first string but that threw an error.
"metadata": {
"labels": {
"beta.kubernetes.io/arch": "amd64",
"beta.kubernetes.io/os": "linux",
"kubernetes.io/arch": "amd64",
"kubernetes.io/hostname": "143.110.156.190",
"kubernetes.io/os": "linux",
"node-role.kubernetes.io/controlplane": "true",
"node-role.kubernetes.io/etcd": "true",
"node-role.kubernetes.io/worker": "true"
},
metadata.labels is not an array, so don't think '{.metadata.labels[0]}' will work.
One of the option is perhaps you can try is to use shell to fetch the first value as following:
kubectl get ingress -o json | jq '.items[0].metadata.labels' | head -2 |tr -d , |cat - <(echo "}") | jq
Kubectl uses JSONPath expressions to filter on specific fields in the JSON object and format the output:
kubectl get ingress -o=jsonpath='{.items[0].metadata.labels}'
For reference use the following link:
https://kubernetes.io/docs/reference/kubectl/jsonpath/

AWS CLI : How to get the API Gateway ID

Is there a way/possible on how we can get the API GAteway ID by name or can we iterate the list and return by its name from AWS CLI, i tried the following way and it doesn't return any thing
aws apigateway get-rest-apis --query 'items[?name==`TestAPI`].value' --output text --region us-east-1
thanks in advance
Updated the list output
"items": [
{
"id": "5aa9gcij77",
"name": "JavaLamdba",
"description": "JavaLamdba",
"createdDate": 1608225655,
"apiKeySource": "HEADER",
"endpointConfiguration": {
"types": [
"REGIONAL"
]
}
},
aws apigateway get-rest-apis --query 'items[?name==`JavaLamdba`].id' --output text --region us-east-1
This should give you the expected result
> select name, description, created_date from aws.aws_api_gateway_rest_api where name = 'lambda-test';
+-------------+-------------+---------------------+
| name | description | created_date |
+-------------+-------------+---------------------+
| lambda-test | lambda-test | 2019-07-25 09:05:16 |
+-------------+-------------+---------------------
https://steampipe.io/

kubectl and seeing (cluster)roles assigned to subjects

I can use kubectl to see to which subjects a cluster role is applied, eg:
kubectl get clusterrolebindings system:node --all-namespaces -o json
{
"apiVersion": "rbac.authorization.k8s.io/v1beta1",
"kind": "ClusterRoleBinding",
....
....
"subjects": [
{
"apiGroup": "rbac.authorization.k8s.io",
"kind": "Group",
"name": "system:nodes"
}
]
}
I would like to get this info the other way around, eg: I want to list all policies applied to the "system:nodes" subject.
How can I do that?
There is no API for the reverse index. You can look up bindings and filter on ones containing the expected subject. For example, using bash, jq, and kubectl:
# $1 is kind (User, Group, ServiceAccount)
# $2 is name ("system:nodes", etc)
# $3 is namespace (optional, only applies to kind=ServiceAccount)
function getRoles() {
local kind="${1}"
local name="${2}"
local namespace="${3:-}"
kubectl get clusterrolebinding -o json | jq -r "
.items[]
|
select(
.subjects[]?
|
select(
.kind == \"${kind}\"
and
.name == \"${name}\"
and
(if .namespace then .namespace else \"\" end) == \"${namespace}\"
)
)
|
(.roleRef.kind + \"/\" + .roleRef.name)
"
}
$ getRoles Group system:authenticated
ClusterRole/system:basic-user
ClusterRole/system:discovery
$ getRoles ServiceAccount attachdetach-controller kube-system
ClusterRole/system:controller:attachdetach-controller