-1

I'm facing some issue related to format my json in ansible code.

Here is some example of my json:


{
  "POC": {
    "Endpoint:dest:one_1": {
      "1_key": "bla1",
      "2_key": "bla2",
      "3_key": "bla3",
      "4_key": "bla4"
    },
    "Endpoint:dest:two_2": {
      "1_key": "bla1",
      "2_key": "bla2",
      "3_key": "bla3",
      "4_key": "bla4"
    },
    "some_value": "something",
    "some_target": "destination",
    "type": "cool",
    "verify": false
  }

My problem is that this format is not correct, and I need params "some_value", "some_target", "type", "verify" to have at beginning of my json config.

Expected json:

{
  "POC": {
    "some_value": "something",
    "some_target": "destination",
    "type": "cool",
    "verify": false,
    "Endpoint:dest:one_1": {
      "1_key": "bla1",
      "2_key": "bla2",
      "3_key": "bla3",
      "4_key": "bla4"
    },
    "Endpoint:dest:two_2": {
      "1_key": "bla1",
      "2_key": "bla2",
      "3_key": "bla3",
      "4_key": "bla4"
    }
  }
}

Do you know some method or do you have any idea how I can achieve that?

Zeitounator
  • 38,476
  • 7
  • 53
  • 66
v124
  • 9
  • 2
  • 1
    In a dictionary or a JSON object the position of key/value have no meaning whatsoever. Why do you want that to achieve this? – β.εηοιτ.βε Mar 08 '23 at 15:25
  • Api which will consume this JSON, complaining about order of params in my JSON file, that's why I need to keep some params on the top of the file. – v124 Mar 08 '23 at 15:27
  • 3
    That's the wrong way to go: you need to fix (or have someone to fix) the API since there is absolutely no acceptable justification to rely on the order of keys in a dict. `my_dict.my_key` has the same value whether you declare it at top or bottom of your dict. I you really need this, you will have to rewrite the entire json in a template to simply make a totally non-sense move of keys. And even with that, you're not entirely sure this json will not be rewritten in whatever order at some later point. This is definitely a bug in the API you call. – Zeitounator Mar 08 '23 at 16:48
  • I'm not able to made any kind of upgrade for my API, because it's external product from vendor. So changes in that case are impossible. I know, I know... I fully aware how my situation at this moment looks. That's why I'm asking for help because i don't see any "good" way to resolve that issue. And I'm trying to find some solution to handle with that but at this moment I'm think that easiest way it's just to add some simple python script which will reformat my json into the format which I need... Because templating using for example jinja it's not good way, in my case... – v124 Mar 08 '23 at 17:21

2 Answers2

2

This is based on a clarifying comment you made.

Suffice to say, this isn't a problem with Ansible.

In practice, the order in which your JSON values appear do not matter, but if you have an implementation which expects a more rigid ordering, then that is an issue with the implementation and not the service which produces the JSON.

You will need to address this with your upstream API.

Makoto
  • 104,088
  • 27
  • 192
  • 230
  • I'm unable to do that, API is legacy product from our external vendor and nobody before notice that api is wrong written... So I need deal with it... Also developers probably were aware of this "bug" when they write that API, because output is not standard it's very verbose ;] – v124 Mar 08 '23 at 17:16
  • You'll have to put something between Ansible and the API then. Ansible's correctly generating JSON. The API is incorrectly consuming JSON. Ansible doesn't have a lot of sway to "fix" someone's bad JSON implementation, so you would have to do that on your own. – Makoto Mar 08 '23 at 17:17
  • Yeah, this is what I feared... But you're probably right i was thinking about some simple python formatter... Anyway, thanks for your opinion! – v124 Mar 08 '23 at 17:25
0

As explained in comments and in answer from @Makoto, this is actually not a problem with ansible. Now, without any warranty this will not move back to a lexical ordering of keys at some point, you can try to reorder with some jinja a templating and spiting out a json string from that new variables

Example playbook:

---
- name: Useless example when you have a working api
  hosts: localhost
  gather_facts: false

  vars:
    # this would be the json you get...
    "POC": {
      "Endpoint:dest:one_1": {
        "1_key": "bla1",
        "2_key": "bla2",
        "3_key": "bla3",
        "4_key": "bla4"
      },
      "Endpoint:dest:two_2": {
        "1_key": "bla1",
        "2_key": "bla2",
        "3_key": "bla3",
        "4_key": "bla4"
      },
      "some_value": "something",
      "some_target": "destination",
      "type": "cool",
      "verify": false
    }

    # ... and the one you want
    my_poc_reordered:
      some_value: "{{ POC.some_value }}"
      some_target: "{{ POC.some_target }}"
      type: "{{ POC.type }}"
      verify: "{{ POC.verify }}"
      "Endpoint:dest:one_1": "{{ POC['Endpoint:dest:one_1'] }}"
      "Endpoint:dest:two_2": "{{ POC['Endpoint:dest:two_2'] }}"

  tasks:

    - name: Spit out json string representation for reordered data
      ansible.builtin.debug:
        msg: "{{ my_poc_reordered | to_json }}"

Which gives:

PLAY [Useless example when you have a working api] ****************************************************************************************************************************************************************

TASK [Spit out json string representation for reordered data] *****************************************************************************************************************************************************
ok: [localhost] => {
    "msg": "{\"some_value\": \"something\", \"some_target\": \"destination\", \"type\": \"cool\", \"verify\": false, \"Endpoint:dest:one_1\": {\"1_key\": \"bla1\", \"2_key\": \"bla2\", \"3_key\": \"bla3\", \"4_key\": \"bla4\"}, \"Endpoint:dest:two_2\": {\"1_key\": \"bla1\", \"2_key\": \"bla2\", \"3_key\": \"bla3\", \"4_key\": \"bla4\"}}"
}

PLAY RECAP ********************************************************************************************************************************************************************************************************
localhost                  : ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
Zeitounator
  • 38,476
  • 7
  • 53
  • 66