Removing a deep nested element from dict (json structure)

Hi,

i’ve been at this for several hours and i’m going in circles so I would like to see if someone can help me get it right.

Given a dict structure which is a json array, I am looking to modify only the deeply nested users[*].perms object to remove the “delete” list item…

The result I am looking for is the following :

{
“id”: “209”,
“ownerUserId”: “2”,
“resource”: “https://cloudcenter.cp.intactfc.com/v1/acls?id=209&resourceName=ACI_EXTENSION”,
“resourceName”: “ACI_EXTENSION”,
“role”: null,
“tenantAndSubtenantUsers”: [
{
“id”: “1”,
“perms”: [
“read”
]
},
{
“id”: “108”,
“perms”: [
“read”
]
}
],
“tenantUsers”: [
{
“id”: “1”,
“name”: “cloudcenter.cp.intactfc.com”,
“parentTenantId”: null,
“perms”: [
“read”,
“access”
],
“resource”: “https://cloudcenter.cp.intactfc.com/v1/acls/1?id=209&resourceName=ACI_EXTENSION”,
“shortName”: “ifc-cp”,
“userId”: “2”
}
],
“userGroups”: ,
“users”: [
{
“emailAddr”: “admin@cliqrtech.com”,
“enabled”: true,
“firstName”: “Cliqr”,
“id”: “2”,
“lastName”: “Admin”,
“perms”: [
“administration”,
“write”,
“read”,
“access”

],
“resource”: “https://cloudcenter.cp.intactfc.com/v1/acls/2?id=209&resourceName=ACI_EXTENSION”,
“tenantId”: “1”,
“type”: “TENANT”,
“username”: “cliqradmin”
},
{
“emailAddr”: “admin2@cliqrtech.com”,
“enabled”: true,
“firstName”: “Cliqr”,
“id”: “3”,
“lastName”: “Admin2”,
“perms”: [
“write”,
“read”,
],

“resource”: “https://cloudcenter.cp.intactfc.com/v1/acls/2?id=209&resourceName=ACI_EXTENSION”,
“tenantId”: “1”,
“type”: “TENANT”,
“username”: “cliqradmin2”
}
]
}

tested the json in jq, had errors in it… here is the updated json

{
“id”: “209”,
“ownerUserId”: “2”,
“resource”: “https://abc.inet/v1/acls?id=209&resourceName=ACI_EXTENSION”,
“resourceName”: “ACI_EXTENSION”,
“role”: null,
“tenantAndSubtenantUsers”: [
{
“id”: “1”,
“perms”: [
“read”
]
},
{
“id”: “108”,
“perms”: [
“read”
]
}
],
“tenantUsers”: [
{
“id”: “1”,
“name”: “abc.inet”,
“parentTenantId”: null,
“perms”: [
“read”,
“access”
],
“resource”: “https://abc.inet/v1/acls/1?id=209&resourceName=ACI_EXTENSION”,
“shortName”: “cp”,
“userId”: “2”
}
],
“userGroups”: ,
“users”: [
{
“emailAddr”: “admin@cliqrtech.com”,
“enabled”: true,
“firstName”: “Cliqr”,
“id”: “2”,
“lastName”: “Admin”,
“perms”: [
“administration”,
“write”,
“read”,
“delete”,
“access”
],
“resource”: “abc.inet/v1/acls/2?id=209&resourceName=ACI_EXTENSION”,
“tenantId”: “1”,
“type”: “TENANT”,
“username”: “cliqradmin”
},
{
“emailAddr”: “admin2@cliqrtech.com”,
“enabled”: true,
“firstName”: “Cliqr”,
“id”: “3”,
“lastName”: “Admin2”,
“perms”: [
“write”,
“read”,
“delete”
],
“resource”: “abc.inet/v1/acls/2?id=209&resourceName=ACI_EXTENSION”,
“tenantId”: “1”,
“type”: “TENANT”,
“username”: “cliqradmin2”
}
]

}

I would combine this dict with another Dict that what you want.

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

Hi Dick,

i’ve been trying, but the issue is that I am receiving this structre back from a call to an api / rest using uri module,

then I need to post back the updated structure but after many hours i’m not getting the combine to work as it should…

i’m probably turning arround the solution just not figuring it out…

each user has existing perms… then i need only to remove the “delete” from each perms array, individually for each user without removing the rest of the entries. (delete is not a valid option when posting back to the API… it’S a bug on the vendor side i have to work arround…)

i’m still at it… trying to get it to work… I started looking into calling shell with JQ to try and achieve it…

Also the combine examples seem to allways refer to key / value pairs… in the perms list i only have values… the keys are not present …

This should work:

  tasks:

    - set_fact:
        filtered_users: "{{ filtered_users|default() | union( [
item | combine( {'perms': item.perms|difference(['delete']) } )] ) }}"
      loop: "{{ my_body|json_query('users') }}"

    - set_fact:
        new_body: "{{ my_body | combine({'users': filtered_users}) }}"

    - debug: var=new_body

TASK [debug] ***********************************************************************************************************
ok: [localhost] =>
  new_body:
    id: '209'
    ownerUserId: '2'
    resource: https://abc.inet/v1/acls?id=209&resourceName=ACI_EXTENSION
    resourceName: ACI_EXTENSION
    role: null
    tenantAndSubtenantUsers:
    - id: '1'
      perms:
      - read
    - id: '108'
      perms:
      - read
    tenantUsers:
    - id: '1'
      name: abc.inet
      parentTenantId: null
      perms:
      - read
      - access
      resource: https://abc.inet/v1/acls/1?id=209&resourceName=ACI_EXTENSION
      shortName: cp
      userId: '2'
    userGroups:
    users:
    - emailAddr: admin@cliqrtech.com
      enabled: true
      firstName: Cliqr
      id: '2'
      lastName: Admin
      perms:
      - administration
      - write
      - read
      - access
      resource: abc.inet/v1/acls/2?id=209&resourceName=ACI_EXTENSION
      tenantId: '1'
      type: TENANT
      username: cliqradmin
    - emailAddr: admin2@cliqrtech.com
      enabled: true
      firstName: Cliqr
      id: '3'
      lastName: Admin2
      perms:
      - write
      - read
      resource: abc.inet/v1/acls/2?id=209&resourceName=ACI_EXTENSION
      tenantId: '1'
      type: TENANT
      username: cliqradmin2

wow! it works perfectly!!!

I was going about it the wrong way… I was decomposing the whole structure to pieces, to update those and then reconstruct… i was ending up getting into nested loop issues because I needed to iterate over both the number of perms and the number of items in the array…

anyways… suffice it to say you solution is much more concise and elegant!

thanks so much!