format url module output

I've just made a pull request to add a 'capture' filter:

    https://github.com/ansible/ansible/pull/4981

The idea is that you would be able to do something like

    {{ foo_string | capture('Error="(\d+)"') }}

to get the error number buried in the string.

If this is accepted, I might even add some documentation :slight_smile:

K

Kahlil (Kal) Hodgson GPG: C9A02289
Head of Technology (m) +61 (0) 4 2573 0382
DealMax Pty Ltd (w) +61 (0) 3 9008 5281

Suite 1415
401 Docklands Drive
Docklands VIC 3008 Australia

"All parts should go together without forcing. You must remember that
the parts you are reassembling were disassembled by you. Therefore,
if you can't get them together again, there must be a reason. By all
means, do not use a hammer." -- IBM maintenance manual, 1925

I’m basically having the same issue I need to get from this :

{
“httpStatus” : 201,
“detail” : “Request accepted.”,
“estimatedSeconds” : 420,
“purgeId” : “95b5a092-043f-4af0-843f-aaf0043faaf0”,
“progressUri” : “/ccu/v2/purges/95b5a092-043f-4af0-843f-aaf0043faaf0”,
“pingAfterSeconds” : 420,
“supportId” : “17PY1321286429616716-211907680”,
}

the pingAfterSeconds to use it in a wait_for task and the purgeid but this is a JSON so dunno if the process is similar to a string parsing?

Thanks.

If the web service returns a Content-type header set as "application/json"
and the response you get is valid json then the uri module will parse the
JSON and make it available via the key.

See https://github.com/ansible/ansible/pull/2119 for more details.

So you should be able to do something like {{
register_var.content.pingAfterSeconds }} to get the value. (Not tested, but
you get the idea.)

Once you get it, it would be good to send a pull request better documenting
this :slight_smile:

This is what I get from the API :

HTTP/1.1 201 Created
Server: Apache
Content-Length: 268
Content-Location: /ccu/v2/purges/e771b867-52d6-11e3-bcaf-2a98bcaf2a98
Allow: GET, HEAD, POST
Vary: Authorization
Content-Type: application/json

{“estimatedSeconds”: 420, “progressUri”: “/ccu/v2/purges/e771b867-52d6-11e3-bcaf-2a98bcaf2a98”, “purgeId”: “e771b867-52d6-11e3-bcaf-2a98bcaf2a98”, “supportId”: “17PY1385056868737216-189879392”, “httpStatus”: 201, “detail”: “Request accepted.”, “pingAfterSeconds”: 420}⏎

my uri request from the playbook :

tasks:

  • name: Flushing Akamai cache
    action: uri url=https://api.ccu.akamai.com/ccu/v2/queues/default
    method=POST user=aaaa password=aaaa
    HEADER_Content-Type=“application/json”
    body=‘{“objects”:[“{{urllist}}”]}’
    status_code=201
    return_content=yes
    register: akamairesponse
  • debug: msg=“value of {{akamairesponse.content.purgeId}}”
  • name: Notifing
    action: hipchat token=aaa room=Akamai msg=“Purged {{urllist}}”
    action: hipchat token=aaa room=Akamai msg=“{{akamairesponse.content.purgerId}}”

I get in hipchat this {{akamairesponse.content.purgerId}} like a string is not actually parsing the data.

the debug :

PLAY [localhost] **************************************************************

TASK: [Flushing Akamai cache] *************************************************
EXEC [‘/bin/sh’, ‘-c’, ‘mkdir -p $HOME/.ansible/tmp/ansible-1385033255.71-37626758703564 && chmod a+rx $HOME/.ansible/tmp/ansible-1385033255.71-37626758703564 && echo $HOME/.ansible/tmp/ansible-1385033255.71-37626758703564’]
REMOTE_MODULE uri url=https://api.ccu.akamai.com/ccu/v2/queues/default method=POST user=xxxxxx password=xxxxx HEADER_Content-Type=“application/json” body=‘{“objects”:[“http://xxxx/images/flags/uk.png”]}’ status_code=201 return_content=yes
PUT /tmp/tmpR6pSOQ TO /usr/home/jamengual/.ansible/tmp/ansible-1385033255.71-37626758703564/uri
EXEC [‘/bin/sh’, ‘-c’, ‘/usr/local/bin/python /usr/home/jamengual/.ansible/tmp/ansible-1385033255.71-37626758703564/uri; rm -rf /usr/home/jamengual/.ansible/tmp/ansible-1385033255.71-37626758703564/ >/dev/null 2>&1’]
ok: [localhost] => {“allow”: “GET, HEAD, POST”, “changed”: false, “content”: “{"estimatedSeconds": 420, "progressUri": "/ccu/v2/purges/bcb3d980-52da-11e3-b16b-21bd716b21bd", "purgeId": "bcb3d980-52da-11e3-b16b-21bd716b21bd", "supportId": "17PY1385058515823533-206664800", "httpStatus": 201, "detail": "Request accepted.", "pingAfterSeconds": 420}”, “content_length”: “268”, “content_location”: “/ccu/v2/purges/bcb3d980-52da-11e3-b16b-21bd716b21bd”, “content_type”: “application/json”, “date”: “Thu, 21 Nov 2013 18:28:35 GMT”, “json”: {“detail”: “Request accepted.”, “estimatedSeconds”: 420, “httpStatus”: 201, “pingAfterSeconds”: 420, “progressUri”: “/ccu/v2/purges/bcb3d980-52da-11e3-b16b-21bd716b21bd”, “purgeId”: “bcb3d980-52da-11e3-b16b-21bd716b21bd”, “supportId”: “17PY1385058515823533-206664800”}, “redirected”: false, “server”: “Apache”, “status”: “201”, “vary”: “Authorization”}

TASK: [debug msg=“value of {{akamairesponse.content.purgeId}}”] ***************
fatal: [localhost] => One or more undefined variables: ‘unicode object’ has no attribute ‘purgeId’

FATAL: all hosts have already failed – aborting

PLAY RECAP ********************************************************************
to retry, use: --limit @/usr/home/jamengual/akamai.retry

localhost : ok=1 changed=0 unreachable=1 failed=0

I tried with : {{akamairesponse.content.purgeId}} and {{akamairesponse.content.[purgeId]}}, {{akamairesponse.content.[“purgeId”]}} and {{akamairesponse.content.“purgeId”}} and it doesn’t work.

am I doing something wrong ?

Thanks.

What is the debug output of just {{akamairesponse}} and {{akamairesponse.content}} ? Just trying to narrow down…

this :

{u’status’: u’201’, u’content_length’: u’268’, u’content_type’: u’application/json’, u’changed’: False, u’vary’: u’Authorization’, u’server’: u’Apache’, u’content’: u’{estimatedSeconds: 420, progressUri: /ccu/v2/purges/41224eec-52df-11e3-8be1-212a0be1212a, purgeId: 41224eec-52df-11e3-8be1-212a0be1212a, supportId: 17PY1385060455982392-223450208, httpStatus: 201, detail: Request"}

I’m assuming that’s the output from just {{akamairesponse}} ? If so what do you get when you take it to the next level of {{akamairesponse.content}}?

Not sure if it’s a copy/paste issue but it looks like the response is missing a trailing ‘}’ as well, which could be an issue.

Romeo

that is the output from debug :

TASK: [debug msg=“value of {{akamairesponse}}”] *******************************
ok: [localhost] => {“msg”: “value of {u’status’: u’201’, u’content_length’: u’268’, u’content_type’: u’application/json’, u’changed’: False, u’vary’: u’Authorization’, u’server’: u’Apache’, u’content’: u’{estimatedSeconds: 420, progressUri: /ccu/v2/purges/26f55aaf-5311-11e3-a7ec-8286a7ec8286, purgeId: 26f55aaf-5311-11e3-a7ec-8286a7ec8286, supportId: 17PY1385081886910598-252707936, httpStatus: 201, detail: Request”}

akamairesponse.content is :

ok: [localhost] => {“msg”: “value of {estimatedSeconds: 420, progressUri: /ccu/v2/purges/7ce8c4c2-5311-11e3-8bb2-22460bb22246, purgeId: 7ce8c4c2-5311-11e3-8bb2-22460bb22246, supportId: 17PY1385082031067768-252707936, httpStatus: 201, detail: Request”}

it looks correct to me.

Ok, so looked at the code again and the way it should work if the JSON was getting parsed correctly would be:

{{akamairesponse.json.purgeId}}

but since we’re not seeing the json subkey I’m guessing the code that loads the json is having an exception on loading the data (i.e. invalid json)


    if 'content_type' in uresp:
        if uresp['content_type'].startswith('application/json'):

            try:

                js = json.loads(content)
                uresp['json'] = js

            except:

                pass

I'm not quite sure why it doesn't think it's valid json though. You'll have to debug that a bit more. It looks like it should work though....

Romeo

One more thing, make sure you have the python json module installed and not just the simplejson module. It seems that the json module is needed to do the json.loads.

This got sorted on IRC.

The value of registered variable foo was in fact available in “foo.json” and things like “foo.json.subValue” got accessible.

For some reason it was being debugged weird or didn’t come back valid in content type and later started working?

Great. I’ll see about submitting a pull request to the docs about the json subkey if the returned content is JSON. That way I don’t have to look at the code next time to remember :slight_smile: