Amit
Amit

Reputation: 397

JQ | Updating array element selected by `select`

In a JSON array, I want to select an array element on basis of a node's value, then update a different node in the same array element. E.g. in the JSON below:

{
"apiVersion": "vlabs",
"properties": {
    "orchestratorProfile": {
    "orchestratorType": "Kubernetes",
    "orchestratorRelease": "1.7",
    "orchestratorVersion": "1.7.10",
    "kubernetesConfig": {
        "kubernetesImageBase": "gcrio.azureedge.net/google_containers/",
        "clusterSubnet": "10.105.208.0/20",
        "networkPolicy": "calico",
        "nonMasqueradeCidr": "10.0.0.0/8",
        "maxPods": 110,
        "dockerBridgeSubnet": "172.17.0.1/16"
        "addons": [
        {
            "name": "tiller",
            "enabled": true
        },
        {
            "name": "aci-connector",
            "enabled": true
        },
        {
            "name": "kubernetes-dashboard",
            "enabled": true
        },
        {
            "name": "rescheduler",
            "enabled": true
        }
        ]
    }
    }
}
}

I want to disable all addons which are not "rescheduler", i.e. set .enabled = false for elements of array .properties.orchestratorProfile.kubernetesConfig.addons[] where .name != "rescheduler". Closest I could work out was

jq -r '.properties.orchestratorProfile.kubernetesConfig.addons[] |
  select (.name != "rescheduler" ) | .enabled =  false'

but this, or any other ways I tried, I always lose the data outside of the array.

The expected outcome is:

{
"apiVersion": "vlabs",
"properties": {
    "orchestratorProfile": {
    "orchestratorType": "Kubernetes",
    "orchestratorRelease": "1.7",
    "orchestratorVersion": "1.7.10",
    "kubernetesConfig": {
        "kubernetesImageBase": "gcrio.azureedge.net/google_containers/",
        "clusterSubnet": "10.105.208.0/20",
        "networkPolicy": "calico",
        "nonMasqueradeCidr": "10.0.0.0/8",
        "maxPods": 110,
        "dockerBridgeSubnet": "172.17.0.1/16"
        "addons": [
        {
            "name": "tiller",
            "enabled": false
        },
        {
            "name": "aci-connector",
            "enabled": false
        },
        {
            "name": "kubernetes-dashboard",
            "enabled": false
        },
        {
            "name": "rescheduler",
            "enabled": true
        }
        ]
    }
    }
}
}

How do I go about doing this? Any idea or help or guidance is appreciated in advance.

Upvotes: 3

Views: 997

Answers (2)

peak
peak

Reputation: 116750

Your jq query is spot-on except essentially for a missing pair of parentheses:

(.properties.orchestratorProfile.kubernetesConfig.addons[]
 | select (.name != "rescheduler" ).enabled) = false

That is, on the LHS of the assignment, you need to specify the paths of the values that need to be updated.

Upvotes: 7

RomanPerekhrest
RomanPerekhrest

Reputation: 92854

jq solution:

jq '.properties.orchestratorProfile.kubernetesConfig.addons = 
     [.[] | if .name != "rescheduler" then .enabled = false else . end]' file

Upvotes: 1

Related Questions