'jq error cannot iterate over null but need to make a different choice
I have a jq filter that selects the rows I need. But sometimes these lines can be empty, and then everything breaks and the rule does not work. I tried to use the if-then-else construct but to no avail.
A rule that works if you process the following json:
.metadata.namespace as $ns | (.spec.rules[0].match.any[].resources.kinds[] / "/") | [select(.[1])[0] // null, select(.[2])[1] // null, last] as [$version,$group,$kind] | {namespace: $ns, kind: $kind, group: $version, version: $group} | with_entries(select(.value!=null))
suitable json:
{
"apiVersion": "kyverno.io/v1",
"kind": "posdfsdf",
"metadata": {
"name": "e-eion",
"namespace": "kke",
"annotations": {
"policies.kyverno.io/title": "Dation",
"policies.kyverno.io/category": "Pod Security Standards (Restricted)",
"policies.kyverno.io/severity": "medium",
"policies.kyverno.io/subject": "Pod",
"kyverno.io/kyverno-version": "1.6.0",
"kyverno.io/kubernetes-version": "1.22-1.23",
"policies.kyverno.io/description": "se`. "
}
},
"spec": {
"validationFailureAction": "audit",
"background": true,
"rules": [
{
"name": "tion",
"match": {
"any": [
{
"resources": {
"kinds": [
"Pod"
]
}
}
]
},
"validate": {
"message": "Prisd",
"pattern": {
"spec": {
"=(eners)": [
{
"secxt": {
"altion": "false"
}
}
],
"=(i)": [
{
"sext": {
"alcalation": "false"
}
}
],
"containers": [
{
"setext": {
"an": "false"
}
}
]
}
}
}
}
]
}
}
example on which the rule stops working:
{
"apiVersion": "k/v1",
"kind": "Picy",
"metadata": {
"name": "denylation",
"namespace": "what",
},
"spec": {
"validationFailureAction": "audit",
"background": true,
"rules": [
{
"name": "deny-privilege-escalation",
"match": {
"resources": {
"kinds": [
"Pod"
]
}
},
"validate": {
"message": "Priviles[*].securityContext.allowPrind spec.initContalse`.",
"pattern": {
"spec": {
"=(iners)": [
{
"=(seext)": {
"=(aln)": "false"
}
}
],
"containers": [
{
"=(stext)": {
"=(al)": "false"
}
}
]
}
}
}
}
]
}
}
how can this be fixed? I need the rule to work out in any cases and give output
Solution 1:[1]
This should work :
.metadata.namespace as $ns |
((.spec.rules[0].match | .. | (objects | .resources.kinds[]?)) / "/") |
[select(.[1])[0] // null, select(.[2])[1] // null, last] as [$version,$group,$kind] |
{namespace: $ns, kind: $kind, group: $version, version: $group} |
with_entries(select(.value!=null))
Solution 2:[2]
The failing json gives the following error:
parse error: Expected another key-value pair at line 7, column 3
This is caused by the trailing comma found here:
"metadata": {
"name": "denylation",
"namespace": "what",
},
Removing that comma, the following error is thrown:
jq: error (at :44): Cannot iterate over null (null)
This is caused by the missing any key inside the match object.
We can 'catch' that error using a ? (docs):
(.spec.rules[0].match.any[]?.resources.kinds[] / "/")
^
But due to the missing key, the filter does not find anything and the output is empty.
Updated jqPlay
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Philippe |
| Solution 2 | 0stone0 |
