Put request to update only one attribute from API GET

Hello,

I’m trying to update an attribute from a GET API JSON result and do a PUT request along with the entire API data with only one attribute change. Please advice on the format for PUT Req Task ?

  1. Get Request for a given API call
  2. From the above json data in step1, I need to update only one attribute: mipUser (From "false To "true) and do a PUT request along with the other data unchanged in the json.

`

  • name: GET Request for CLUSTERS
    uri:
    url: https://zsapi.com/BETA/{{ item }}
    method: GET
    validate_certs: no
    return_content: yes
    status_code: 200
    headers:
    Content-Type: application/json
    Cookie: “{{ login.set_cookie.split(‘;’)[0] }}”
    body_format: json
    with_items: “{{ cluster }}”
    register: cluster_result

`

`

ok: [localhost] => {
“msg”: [
{
“bandwidthControlApp”: true,
“cloud”: “BETA”,
“createTime”: 1550875210,
“datacenter”: {
“id”: 526,
“name”: “FMT1”
},
“description”: “cluster with VIP 169.254.1.100”,
“disabled”: false,
“id”: 2334,
“lastModifiedTime”: 1560896398,
“lastModifiedUser”: {
“id”: 1009,
“name”: “adev@xyz.com
},
“mipUser”: false,
“mtsInstances”: ,
“name”: “fmt1”,
“rateLimit”: true,

}
]
}

`

The combine filter should allow you to do this:

https://docs.ansible.com/ansible/latest/user_guide/playbooks_filters.html#combining-hashes-dictionaries

So you can use something like this for the PUT request:

"{{ firstresult | combine({'mipUser': true}) }}"

Hi Dick,

For this to work, I need to convert the output to a dictionary. Hw can I do that ?

fatal: [localhost]: FAILED! => {“msg”: "|combine expects dictionaries, got [{u’bandwidthControlApp’: F

You need to use that in a loop as the results variable is a list of dicts.

Or drop the loop if you only use it once so the result will be a dict.

Dick

Hi Dick,

I was able to use combine filter and save the updated json content to a variable using set_fact. Now, when I try to do PUT request using this variable in the body I get error. Can you help me with the body syntax using a set_fact variable ?

`

  • set_fact:
    updated_flag: “{{ cluster_result | combine({‘traceSyncApp’: true}) }}”

  • debug:
    msg: “{{ updated_flag }}”

  • name: Enable Tracesync
    uri:
    url:
    method: PUT
    validate_certs: no
    return_content: yes
    status_code: 200
    headers:
    Content-Type: application/json
    Cookie: “{{ login.set_cookie.split(‘;’)[0] }}”
    body_format: json
    body : “{{ updated_flag }}”
    register: cluster_result
    `

`
fatal: [localhost]: FAILED! => {“changed”: false, “connection”: “close”, “content”: “Request body is invalid.”, “content_length”: “24”, “content_type”: “text/plain”, “date”: “Mon, 24 Jun 2019 06:58:51 GMT”, “failed”: true, “msg”: "Status code was not [200]: HTTP Error 400: "}

`

That error is specific to the API you're calling.
To debug, compare and look for difference between the data that you
send in this request, and the data in a task that does succeed.

Dick