Sl4dy
Sl4dy

Reputation: 172

Use jq to select objects not containing nested objects

I have following JSON:

{
"apiVersion": "v1",
"items": [
    {
        "apiVersion": "v1",
        "kind": "Node",
        "metadata": {
            "annotations": {
                "node.alpha.kubernetes.io/ttl": "0",
                "volumes.kubernetes.io/controller-managed-attach-detach": "true"
            },
            "creationTimestamp": "2017-09-14T11:53:07Z",
            "labels": {
                "beta.kubernetes.io/arch": "amd64",
                "beta.kubernetes.io/os": "linux",
                "kubernetes.io/hostname": "msl-kub01.int.na.myapp.com",
                "node-role.kubernetes.io/master": ""
            },
            "name": "msl-kub01.int.na.myapp.com",
            "namespace": "",
            "resourceVersion": "123154",
            "selfLink": "/api/v1/nodes/msl-kub01.int.na.myapp.com",
            "uid": "45e3b430-9943-11e7-bf0b-fa163e6604fc"
        },
        "spec": {
            "externalID": "msl-kub01.int.na.myapp.com",
            "taints": [
                {
                    "effect": "NoSchedule",
                    "key": "node-role.kubernetes.io/master",
                    "timeAdded": null
                }
            ]
        }
    },    
    {
        "apiVersion": "v1",
        "kind": "Node",
        "metadata": {
            "annotations": {
                "node.alpha.kubernetes.io/ttl": "0",
                "volumes.kubernetes.io/controller-managed-attach-detach": "true"
            },
            "creationTimestamp": "2017-09-14T12:05:42Z",
            "labels": {
                "beta.kubernetes.io/arch": "amd64",
                "beta.kubernetes.io/os": "linux",
                "kubernetes.io/hostname": "msl-kub02.int.na.myapp.com"
            },
            "name": "msl-kub02.int.na.myapp.com",
            "namespace": "",
            "resourceVersion": "123156",
            "selfLink": "/api/v1/nodes/msl-kub02.int.na.myapp.com",
            "uid": "084f439e-9945-11e7-bf0b-fa163e6604fc"
        },
        "spec": {
            "externalID": "msl-kub02.int.na.myapp.com"
        }
    }
],
"kind": "List",
"metadata": {
    "resourceVersion": "",
    "selfLink": ""
}}

I need to select all entries of "items" list which do not have "spec.taints[].effect == "NoSchedule".

The thing is that presence of taints list and effect key is not mandatory in source JSON so I cannot do:

select (.spec.taints[].effect != "NoSchedule")

I was hoping to use something like:

select (has(".spec.taints[].effect") | not)

But it is not allowed.

Thx for tips.

Upvotes: 1

Views: 1146

Answers (3)

jq170727
jq170727

Reputation: 14665

Here is a filter which should work.

   .items[]
 | select(.spec.taints | (.==null) or (any(.effect=="NoSchedule")|not))

Upvotes: 1

Jeff Mercado
Jeff Mercado

Reputation: 134861

You could use ? to ignore any errors if a given property or array doesn't exist. So with that in mind, go through the items where none of them contain a taint effect of "NoSchedule".

.items[] | select(all(.spec.taints[]?; .effect != "NoSchedule"))

Upvotes: 0

RomanPerekhrest
RomanPerekhrest

Reputation: 92854

jq solution:

jq '[.items[] | if (.spec | has("taints") | not) 
    or (.spec.taints[] | select(.effect!="NoSchedule")) then . else empty end]' your.json

The output:

[
  {
    "apiVersion": "v1",
    "kind": "Node",
    "metadata": {
      "annotations": {
        "node.alpha.kubernetes.io/ttl": "0",
        "volumes.kubernetes.io/controller-managed-attach-detach": "true"
      },
      "creationTimestamp": "2017-09-14T12:05:42Z",
      "labels": {
        "beta.kubernetes.io/arch": "amd64",
        "beta.kubernetes.io/os": "linux",
        "kubernetes.io/hostname": "msl-kub02.int.na.myapp.com"
      },
      "name": "msl-kub02.int.na.myapp.com",
      "namespace": "",
      "resourceVersion": "123156",
      "selfLink": "/api/v1/nodes/msl-kub02.int.na.myapp.com",
      "uid": "084f439e-9945-11e7-bf0b-fa163e6604fc"
    },
    "spec": {
      "externalID": "msl-kub02.int.na.myapp.com"
    }
  }
]

Upvotes: 1

Related Questions