2

One of my ansible tasks executes a Mongo command using the Shell module but the output returns escaped strings. I've tried using some ansible filters but not getting any luck.

this is what the ansible play and output look like:

- name: get ops
  shell:
    cmd: mongo --eval  "printjsononeline(db.currentOp())"
  register: currentOp

- debug:
    msg: "{{ currentOp.stdout_lines[2] }}"

current output with escaped strings:

ok: [db1] => {
    "msg": "{  \"inprog\" : [ { \"desc\" : \"conn24359\", \"threadId\" : \"139883322984192\", \"connectionId\" : 24359, \"client\" : \"127.0.0.1:51259\", \"active\" : true, \"opid\" : 959820, \"secs_running\" : 0, \"microsecs_running\" : NumberLong(21), \"op\" : \"command\", \"ns\" : \"admin.$cmd\", \"query\" : { \"currentOp\" : 1 }, \"numYields\" : 0, \"locks\" : {  }, \"waitingForLock\" : false, \"lockStats\" : {  } }, { \"desc\" : \"WT RecordStoreThread: local.oplog.rs\", \"threadId\" : \"139883394451200\", \"active\" : true, \"opid\" : 2, \"secs_running\" : 65833, \"microsecs_running\" : NumberLong(\"65833826945\"), \"op\" : \"none\", \"ns\" : \"local.oplog.rs\", \"query\" : {  }, \"numYields\" : 0, \"locks\" : {  }, \"waitingForLock\" : false, \"lockStats\" : { \"Global\" : { \"acquireCount\" : { \"r\" : NumberLong(1), \"w\" : NumberLong(1) }, \"acquireWaitCount\" : { \"w\" : NumberLong(1) }, \"timeAcquiringMicros\" : { \"w\" : NumberLong(1813778) } }, \"Database\" : { \"acquireCount\" : { \"w\" : NumberLong(1) } }, \"oplog\" : { \"acquireCount\" : { \"w\" : NumberLong(1) } } } } ],  \"ok\" : 1 }"
}

I'd like the outcome to be in actual JSON without escapes. any pointers? I've tried the following ansible filters | to_json | from_json but no luck

ezeagwulae
  • 289
  • 7
  • 22

1 Answers1

2

The output of your shell is not json. It's mongo extended json which contains functions that will produce errors when parsed by a regular json parser.

My XP with mongo is just above nothing so there might definitelly be smarter ways to do this. But based on an other answer I found, here is what I came up with and successfully tested against a mongo docker container:

- hosts: mongo
  gather_facts: false

  tasks:

    - shell: mongo --quiet --eval  'print(JSON.stringify(db.currentOp()))'
      register: mocmd

    - debug:
        msg: "{{ mocmd.stdout | from_json }}"
Zeitounator
  • 38,476
  • 7
  • 53
  • 66
  • 1
    clever. forgot its a javascript interactive shell. `JSON.stringify` is what I was missing. thanks a bunch – ezeagwulae May 13 '20 at 23:44