I have been using jq(1) and getting a similar response back from a kubernetes api (api/v1/nodes).
{
"kind": "NodeList",
"apiVersion": "v1",
"metadata": {
"selfLink": "/api/v1/nodes",
"resourceVersion": "8768"
},
"items": [
{
"metadata": {
"name": "ip-101-191-101-101.ec2.internal",
"selfLink": "/api/v1/nodes/ip-101-191-101-101.ec2.internal",
"uid": "2l3kje2ili-23e232-2e3ee-edwed-232398h9e3h98h",
"resourceVersion": "8768",
"creationTimestamp": "2020-11-19T12:27:05Z",
},
"spec": {
"podCIDR": "101.191.101.101/24",
"providerID": "aws:///us-west-1e/i-lidss9jsjldsjli",
"taints": [
{
"key": "worker-group",
"value": "prometheus",
"effect": "NoSchedule"
}
]
}
}
]
}
As you can see there can be many items in the Array. There are some with the .spec.taints and others without it. Some may be empty and some may be full.
My goal is to just ignore all items that have the taints "effect": "NoSchedule"
I'm finding this very troublesome because no matter what I try and I've been searching online for days, i can't get it to work properly.
I've gotten this far but am now stuck
curl api | jq -c '.items[].spec.taints |= map(select(.effect | . != "NoSchedule"))'
any help would be appreciated.
CodePudding user response:
I hope this can be useful, in this example there are 3 items one with effect: NoSchedule, one with effect: anyother and one with taints empty. If am correct, you need only the second one:
{
"kind": "NodeList",
"apiVersion": "v1",
"metadata": {
"selfLink": "/api/v1/nodes",
"resourceVersion": "8768"
},
"items": [
{
"metadata": {
"name": "ip-101-191-101-101.ec2.internal",
"selfLink": "/api/v1/nodes/ip-101-191-101-101.ec2.internal",
"uid": "2l3kje2ili-23e232-2e3ee-edwed-232398h9e3h98h",
"resourceVersion": "8768",
"creationTimestamp": "2020-11-19T12:27:05Z"
},
"spec": {
"podCIDR": "101.191.101.101/24",
"providerID": "aws:///us-west-1e/i-lidss9jsjldsjli",
"taints": [
{
"key": "worker-group",
"value": "prometheus",
"effect": "NoSchedule"
}
]
}
},
{
"metadata": {
"name": "ip-101-191-101-101.ec2.internal",
"selfLink": "/api/v1/nodes/ip-101-191-101-101.ec2.internal",
"uid": "2l3kje2ili-23e232-2e3ee-edwed-232398h9e3h98h",
"resourceVersion": "8768",
"creationTimestamp": "2020-11-19T12:27:05Z"
},
"spec": {
"podCIDR": "101.191.101.101/24",
"providerID": "aws:///us-west-1e/i-lidss9jsjldsjli",
"taints": [
{
"key": "worker-group",
"value": "prometheus",
"effect": "anyother"
}
]
}
},
{
"metadata": {
"name": "ip-101-191-101-101.ec2.internal",
"selfLink": "/api/v1/nodes/ip-101-191-101-101.ec2.internal",
"uid": "2l3kje2ili-23e232-2e3ee-edwed-232398h9e3h98h",
"resourceVersion": "8768",
"creationTimestamp": "2020-11-19T12:27:05Z"
},
"spec": {
"podCIDR": "101.191.101.101/24",
"providerID": "aws:///us-west-1e/i-lidss9jsjldsjli",
"taints": [
]
}
}
]
The command will be:
jq '.items[]|select(.spec.taints[].effect!="NoSchedule") ' data1.jtxt
result:
{
"metadata": {
"name": "ip-101-191-101-101.ec2.internal",
"selfLink": "/api/v1/nodes/ip-101-191-101-101.ec2.internal",
"uid": "2l3kje2ili-23e232-2e3ee-edwed-232398h9e3h98h",
"resourceVersion": "8768",
"creationTimestamp": "2020-11-19T12:27:05Z"
},
"spec": {
"podCIDR": "101.191.101.101/24",
"providerID": "aws:///us-west-1e/i-lidss9jsjldsjli",
"taints": [
{
"key": "worker-group",
"value": "prometheus",
"effect": "anyother"
}
]
}
}
Note: I put your data ina a file to simulate input.
CodePudding user response:
Based on the question, my understanding is that the taints
could have multiple entries. It could be a mix of NoSchedule
and other values. Here's the jq
where the item will be ignored if at least one taint with effect
value NoSchedule
exists.
. as $in | $in * { items: $in.items | map(select(.spec.taints | all(.effect != "NoSchedule"))) }```
CodePudding user response:
This deletes from the .items
array every member that has an array in .spec.taints
which in turn has at least one object item with .effect
set to "NoSchedule"
. In every other case, i.e. there's only objects with .effect
set to something else, or .taints
is empty, or there's no .taints
at all, or there's no .spec
at all, up to just an empty object {}
as member of the .items
array, that array member will be retained.
.items -= (.items | map(select(.spec.taints[].effect == "NoSchedule")?))
CodePudding user response:
You can use del
to delete the one(s) you intended :
curl api | jq 'del(.items[] | select(.spec.taints[].effect == "NoSchedule")?)'