Kubectl query for regex in JsonPath - kubernetes

I am trying to output the value for .metadata.name followed by the student's name in .spec.template.spec.containers[].students[] array using the regex in JsonPath for a Kubectl query.
I had actually asked a similar question linked here for this in jq.
How do I print a specific value of an array given a condition in jq if there is no key specified
The solution worked but I am wondering if there is an alternative solution for it using JsonPath or go-template perhaps (without the need for using jq).
For example, if I check the students[] array if it contains the word "Jeff", I would like the output to display as below:
student-deployment: Jefferson
What I've tried:
For JsonPath, I've tried the query below:
kubectl get deployment -o=jsonpath="{range .items[?(#.spec.template.spec.containers[*].students[*])]}{'\n'}{.metadata.name}{':\t'}{range .spec.template.spec.containers[*]}{.students[?(#=="Jefferson")]}{end}{end}"
But this only works to evaluate for matching words. Would it be possible to use JsonPath to query for regex as I've read here that JsonPath regex =~ doesn't work? I did try to use | grep and findstr but it still returned all values inside the array back to me. Other than jq, is there another way to retrieve the regex output?
https://github.com/kubernetes/kubernetes/issues/61406
The deployment template below is in json and I shortened it to only the relevant parts.
{
"apiVersion": "v1",
"items": [
{
"apiVersion": "apps/v1",
"kind": "Deployment",
"metadata": {
"name": "student-deployment",
"namespace": "default"
},
"spec": {
"template": {
"spec": {
"containers": [
{
"students": [
"Alice",
"Bob",
"Peter",
"Sally",
"Jefferson"
]
}
]
}
}
}
}
]
}

The documentation for JSONPath Support clearly describes that it is not possible with JSONPath and you can use jq.
https://kubernetes.io/docs/reference/kubectl/jsonpath/

Related

kubectl jsonpath query and output multiple object values

Below is my output of kubectl get deploy --all-namespaces:
{
"apiVersion": "v1",
"items": [
{
"apiVersion": "apps/v1",
"kind": "Deployment",
"metadata": {
"annotations": {
"downscaler/uptime": "Mon-Fri 07:00-23:59 Australia/Sydney",
"name": "actiontest-v2.0.9",
"namespace": "actiontest",
},
"spec": {
......
......
},
{
"apiVersion": "apps/v1",
"kind": "Deployment",
"metadata": {
"annotations": {
"downscaler/uptime": "Mon-Fri 07:00-21:00 Australia/Sydney",
"name": "anotherapp-v0.1.10",
"namespace": "anotherapp",
},
"spec": {
......
......
}
}
I need to find the name of the deployment and its namespace if the annotation "downscaler/uptime" matches the value "Mon-Fri 07:00-21:00 Australia/Sydney". I am expecting an output like below:
deployment_name,namespace
If I am running below query against a single deployment, I get the required output.
#kubectl get deploy -n anotherapp -o jsonpath='{range .[*]}{.items[?(#.metadata.annotations.downscaler/uptime=="Mon-Fri 07:00-21:00 Australia/Sydney")].metadata.name}{","}{.items[?(#.metadata.annotations.downscaler/uptime=="Mon-Fri 07:00-21:00 Australia/Sydney")].metadata.namespace}{"\n"}'
anotherapp-v0.1.10,anotherapp
But when I run it against all namespaces, I am getting an output like below:
#kubectl get deploy --all-namespaces -o jsonpath='{range .[*]}{.items[?(#.metadata.annotations.downscaler/uptime=="Mon-Fri 07:00-21:00 Australia/Sydney")].metadata.name}{","}{.items[?(#.metadata.annotations.downscaler/uptime=="Mon-Fri 07:00-21:00 Australia/Sydney")].metadata.namespace}{"\n"}'
actiontest-v2.0.9 anotherapp-v0.1.10, actiontest anotherapp
This is quite short answer, however you can use this option:
kubectl get deploy --all-namespaces -o jsonpath='{range .items[?(.metadata.annotations.downscaler/uptime=="Mon-Fri 07:00-21:00 Australia/Sydney")]}{.metadata.name}{"\t"}{.metadata.namespace}{"\n"}'
What I changed is logic how to work with data:
First thing what happens is getting into range list of elements we need to work on, not everything. I used filter expression - see Jsonpath notation - syntax elements.
And once we have already filtered entities in the list, we can easily retrieve other fields we need.

Kubernetes API server filtering by field - in request time

I'm trying to get all the secrets in the cluster of type helm.sh/release.v1:
$ curl -X GET $APISERVER/api/v1/secrets --header "Authorization: Bearer $TOKEN" --insecure
{
"kind": "SecretList",
"apiVersion": "v1",
"metadata": {
"selfLink": "/api/v1/secrets",
"resourceVersion": "442181"
},
"items": [
{
"metadata": {
...
},
"data": {
...
},
"type": "helm.sh/release.v1"
},
{
"metadata": {
...
},
"data": {
...
},
"type": "kubernetes.io/service-account-token"
},
{
"metadata": {
...
},
"data": {
...
},
"type": "kubernetes.io/service-account-token"
},
...
}
I can use the command above and then filter by myself (jq or whatever) but I wonder if there's an option to filter in the API by adding query parameters or something, for example (didn't work):
curl -X GET $APISERVER/api/v1/secrets?type=<value>
any idea how to filter by specific field? (type) can I also request specific fields in the response (if I don't care about the data for instance)?
I'm going to use HTTP requests from my application (python) that runs
within a pod in the cluster. I am trying to be more efficient and ask
only for what I need (only specific type and not all secrets in the
cluster)
If your application is written in Python, maybe it's a good idea to use Kubernetes Python Client library to get the secrets ?
If you want to get all the secrets in the cluster of type helm.sh/release.v1, you can do it with the following Python code:
from kubernetes import client , config
config.load_kube_config()
v1 = client.CoreV1Api()
list_secrets = v1.list_secret_for_all_namespaces(field_selector='type=helm.sh/release.v1')
If you also want to count them, use:
print(len(list_secrets.items))
to print secret's name use:
print(list_secrets.items[0].metadata.name)
to retrieve it's data:
print(list_secrets.items[0].data)
and so on...
More details, including arguments that can be used with this method, you can find here (just search for list_secret_for_all_namespaces):
# **list_secret_for_all_namespaces**
> V1SecretList list_secret_for_all_namespaces(allow_watch_bookmarks=allow_watch_bookmarks, _continue=_continue, field_selector=field_selector, label_selector=label_selector, limit=limit, pretty=pretty, resource_version=resource_version, timeout_seconds=timeout_seconds, watch=watch)

Orion Context Broker Using Match Pattern with number

For example I have a person like below.
I wan to query person has phoneNumber contains "354".
I will use the query like this: GET /v2/entities?q=phoneNumber~=354.
So is it possible to do the query like this in orion context broker?
As I have seen that the match pattern only support target property as string.
Match pattern: ~=. The value matches a given pattern, expressed as a
regular expression, e.g. color~=ow. For an entity to match, it must
contain the target property (color) and the target property value must
match the string in the right-hand side, 'ow' in this example (brown
and yellow would match, black and white would not). This operation is
only valid for target properties of type string.
http://telefonicaid.github.io/fiware-orion/api/v2/stable/ Section: Simple Query Language
{
"type": "Person",
"isPattern": "false",
"id": "1",
"attributes": [
{
"name": "phoneNumber",
"type": "string",
"value": "0102354678"
}
]
}
Many thanks.
It works as you said.
For instance, using Orion 2.2.0 with an empty database in localhost:1026, creating an entity like the one you propose (but using NGSIv2 endpoint, as NGSIv1 is a deprecated API):
$ curl localhost:1026/v2/entities -H 'content-type: application/json' -d #- <<EOF
{
"type": "Person",
"id": "1",
"phoneNumber": {
"type": "string",
"value": "0102354678"
}
}
EOF
Then, you can do a query with "354" pattern and you will get the entity:
$ curl -s -S 'localhost:1026/v2/entities?q=phoneNumber~=354' | python -mjson.tool
[
{
"id": "1",
"phoneNumber": {
"metadata": {},
"type": "string",
"value": "0102354678"
},
"type": "Person"
}
]
On the contrary, if you do a query for a non-matching pattern (such as "999") you will not get any entity:
$ curl -s -S 'localhost:1026/v2/entities?q=phoneNumber~=999' | python -mjson.tool
[]

Kubeedge on Kataocoda - no matches for kind "Node" in version "v1"

I am following Kubeedge v1.0.0 deployment on Katacoda and on executing the following command.
kubectl apply -f $GOPATH/src/github.com/kubeedge/kubeedge/build/node.json -s <kubedge-node-ip-address>:8080
It gives me an error
error: unable to recognize "/root/kubeedge/src/github.com/kubeedge/kubeedge/build/node.json": no matches for kind "Node" in version "v1"
Tried searching for this error but found no relevant answers. Anyone has idea on to get through this?
Below is the content of my node.json file
{
"kind": "Node",
"apiVersion": "v1",
"metadata": {
"name": "edge-node-1",
"labels": {
"name": "edge-node",
"node-role.kubernetes.io/edge": ""
}
}
}
I have reproduced it in Katakoda and in my case it works perfectly. I recommend you to go through the tutorial once again and take each step carefully.
You need to pay attention for step 7. Change metadata.name to the name of the edge node:
vim $GOPATH/src/github.com/kubeedge/kubeedge/build/node.json
{
"kind": "Node",
"apiVersion": "v1",
"metadata": {
"name": "edge-node",
"labels": {
"name": "edge-node",
"node-role.kubernetes.io/edge": ""
}
}
}
Then, execute following command, where you need to change IP address:
kubectl apply -f $GOPATH/src/github.com/kubeedge/kubeedge/build/node.json -s <kubedge-node-ip-address>:8080
Another command to check if a correct API version was used, is:
kubectl explain node -s <kubedge-node-ip-address>:8080
After successful creation of node you should see:
node/edge-node created

hbase fuzzy/filter list matching for REST from shell

I am trying to formulate some RESTful calls to return specific data from a hbase table using fuzzy logic OR multiple filters (filterList). My rowkey is made up of 'BatchId + UserId + Timestamp' + 'ModelId', as an example i would like to be able to find all people where rowkey contains UserId of xyz' & 'ModelId' of 'yxz' (irrespective of BatchId & Timestamp values).
I've had no luck replicating fuzzy filters from the shell, as a last resort i'm attempting to use a filter list (multiple filters) to filter on each of the columns individually (this comes at a performance cost, which i can accept).
With regards the filter list, when trying to filter on the RK itself, i am not sure what value to pass for qualifier & column family too or the syntax for adding more than one filter, any help greatly appreciated.
Find my curl command & the args file contents for filterlist below.
CURL:
curl -vi -X PUT -H "Content-Type:text/xml" -d #args.xml "host-rest-machine-address/namespace:table/scanner"
ARGS.XML:
<Scanner batch ="1024">
<filter>
{
"type": "FilterList",
"op": "MUST_PASS_ONE",
"filters": [{
"type": "FilterList",
"op": "MUST_PASS_ALL",
"filters": [{
"type": "FamilyFilter",
"op": "EQUAL",
"comparator": {
"type": "BinaryComparator",
"value": "Y2Yx"
}
}, {
"type": "QualifierFilter",
"op": "EQUAL",
"comparator": {
"type": "BinaryComparator",
"value": "cm93S2V5"
}
}, {
"type": "RowFilter",
"op": "EQUAL",
"comparator": {
"type": "BinaryComparator",
"value": "MjAwMDAyMDE4OTM3Mw=="
}
}]
}]
}
</filter>
</Scanner>
My column family: cf1 (not sure if this is applicable when searching against row key?)
Qualifier: column name in hbase table (also unsure of how to refer to rowkey here - have tried row, rowkey, my sql alias on import with no luck)
Value: value to filter on for given column/table
Note - all values being passed are base_64 encoded
Thanks in advance