#registering and reporting on variables

1 messages · Page 1 of 1 (latest)

urban crag
#

So I'm most definitely misunderstanding things.

I'm trying to grab every vserver name on a cluster, I've got the below playbook for learning purposes.

But every time I try and drill down past svm/svms and snag just the name. It vomits with the bottom error - I know I'm doing something wrong but I don't know what.


  • name: Gather Vserver names
    netapp.ontap.na_ontap_rest_info:
    hostname: "{{ datacenter['nas']['hostname'] }}"
    username: "{{ datacenter['nas']['username'] }}"
    password: "{{ datacenter['nas']['pass'] }}"
    gather_subset:
    - "vserver_info"
    validate_certs: false
    register: results
  • debug:
    msg: "{{ results['ontap_info']['svm/svms']['records']['name'] }}"

ASK [debug] *******************************************************************
task path: /tmp/rundeck/ansible-runner1511451917696604844playbook:25
ok: [HOST] => {
"msg": [
{
"_links": {
"self": {
"href": "/api/svm/svms/13c0daf1-a993-11ea-91c7-00a098fd51a6"
}
},
"name": "vserver1",
"uuid": "13c0daf1-a993-11ea-91c7-00a098fd51a6"
},
{
"_links": {
"self": {
"href": "/api/svm/svms/172de4df-bbc0-11ea-91c7-00a098fd51a6"
}
},
"name": "vserver2,
"uuid": "172de4df-bbc0-11ea-91c7-00a098fd51a6"
},
{
"_links": {
"self": {
"href": "/api/svm/svms/5171e6da-c6b5-11ea-91c7-00a098fd51a6"
}
},
"name": "vserver3",
"uuid": "5171e6da-c6b5-11ea-91c7-00a098fd51a6"
},

fatal: [HOST]: FAILED! => {"msg": "The task includes an option with an undefined variable. The error was: 'list object' has no attribute 'name'. 'list object' has no attribute 'name'\n\nThe error appears to be in '/tmp/rundeck/ansible-runner7276113403921335480playbook': line 25, column 5, but may\nbe elsewhere in the file depending on the exact syntax problem.\n\nThe offending line appears to be:\n\n register: results\n - debug:\n ^ here\n"}

ripe hearth
#

First, you might want to add 'use_python_keys: true' to the rest_info - it will convert all the '/' chars to an '_' and then you can use dot notation - not necessary but I think it makes it a little easier to read.

If you look at the full result set (debug: var: results) you'll see that when you reach the 'records' level it is an array of records (records[]) so you need to reference the index to each record. If you insert a [0] between 'records' and 'name' you should get the first vserver name as output. You can also loop through the result set using with_items: "{{ results.ontap_info.svm_svms.records }}"

ripe hearth
urban crag
#

Aaaaah ok, it wants an index before it can access them

#
.0.name

For first

#

How would I snag ones that meet certain names. Like include certain strings?

#

Or would I build conditionals into the play?
Have it perform a loop if the variable doesn't include test or some other nonsense

buoyant oyster
#

If you have a list that you have registarted as a variable, you can use the loop key word to make a loop and then when keyword for if statements.

- name: Loop over the list and process items starting with 'netapp'
  debug:
    msg: "Processing {{ item }}"
  loop: "{{ item_list }}"
  when: item.startswith('netapp')

Ansible has a detailed pay on Conditionals here
https://docs.ansible.com/ansible/latest/playbook_guide/playbooks_conditionals.html

And different loop you can do here
https://docs.ansible.com/ansible/latest/playbook_guide/playbooks_loops.html

urban crag
#

Solved.
I appreciate the help folks 🙂

urban crag
#

Versus creating a separate thread. Using the above methodology... What am I doing wrong with the below?

The error

TASK [ansible.builtin.set_fact] ************************************************
task path: /tmp/rundeck/ansible-runner13958148239047360092playbook:159
fatal: [H1PLSECPRXY01]: FAILED! => {"msg": "'dict object' has no attribute 'storage/volumes/snapshots'. 'dict object' has no attribute 'storage/volumes/snapshots'"}

#

The play(s)

- name: Gather Snapshot_Volume nonsense
        netapp.ontap.na_ontap_rest_info:
          hostname: "{{ g_hostname }}"
          username: "{{ g_username }}"
          password: "{{ g_password }}"
          gather_subset:
          https: true
          validate_certs: false
          use_rest: Always
          gather_subset:
            - storage/volumes/snapshots
          owning_resource:
            volume_name: "{{ parent_volume }}"
            svm_name: "{{ parent_vserver }}"
          validate_certs: false
        register: results_snapshot1
        no_log: false

      - name: "debug results_snapshot"
        debug:
          msg: "{{ results_snapshot1['ontap_info'] }}"
          
      - ansible.builtin.set_fact:
          daily_snapshots: "{{daily_snapshots + [item.name] }}"
        loop: "{{ results_snapshot1['storage/volumes/snapshots'] }}"

#

The dict I'm trying read

[prxy01] => {
    "msg": {
        "storage/volumes/snapshots": {
            "_links": {
                "self": {
                    "href": "/api/storage/volumes/eae96ac3-1d00-11ef-9468-00a098fe4958/snapshots?max_records=1024&fields="
                }
            },
            "num_records": 8,
            "records": [
                {
                    "_links": {
                        "self": {
                            "href": "/api/storage/volumes/eae96ac3-1d00-11ef-9468-00a098fe4958/snapshots/67a46d44-2e32-463e-91af-32f33123d7a3"
                        }
                    },
                    "name": "daily.2024-07-12_0010",
                    "uuid": "67a46d44-2e32-463e-91af-32f33123d7a3"
                },
                {
                    "_links": {
                        "self": {
                            "href": "/api/storage/volumes/eae96ac3-1d00-11ef-9468-00a098fe4958/snapshots/c4b84e06-8ba1-473f-b466-80d297c915d2"
                        }
                    },
                    "name": "daily.2024-07-13_0010",
                    "uuid": "c4b84e06-8ba1-473f-b466-80d297c915d2"
                },
                {
                    "_links": {
                        "self": {
                            "href": "/api/storage/volumes/eae96ac3-1d00-11ef-9468-00a098fe4958/snapshots/43b14327-5752-49d0-9f58-5fac89e1c9ef"
                        }
                    },
                    "name": "daily.2024-07-14_0010",
                    "uuid": "43b14327-5752-49d0-9f58-5fac89e1c9ef"
                },
                {
                    "_links": {
                        "self": {
                            "href": "/api/storage/volumes/eae96ac3-1d00-11ef-9468-00a098fe4958/snapshots/eae376ae-d5ef-4aba-a42d-dbeefff9102f"
                        }
                    },
                    "name": "daily.2024-07-15_0010",
                    "uuid": "eae376ae-d5ef-4aba-a42d-dbeefff9102f"
                },
                {
                    "_links": {
                        "self": {
                            "href": "/api/storage/volumes/eae96ac3-1d00-11ef-9468-00a098fe4958/snapshots/5721391c-cbff-4b00-abab-e258da40e16b"
                        }
                    },
                    "name": "daily.2024-07-16_0010",
                    "uuid": "5721391c-cbff-4b00-abab-e258da40e16b"
                },
                {
                    "_links": {
                        "self": {
                            "href": "/api/storage/volumes/eae96ac3-1d00-11ef-9468-00a098fe4958/snapshots/0060ce49-0948-4a7f-a5dd-a59d00c1e977"
                        }
                    },
                    "name": "daily.2024-07-17_0010",
                    "uuid": "0060ce49-0948-4a7f-a5dd-a59d00c1e977"
                },
                {
                    "_links": {
                        "self": {
                            "href": "/api/storage/volumes/eae96ac3-1d00-11ef-9468-00a098fe4958/snapshots/4092294d-09a8-4ee6-836b-2f64ffdfc6f2"
                        }
                    },
                    "name": "daily.2024-07-18_0010",
                    "uuid": "4092294d-09a8-4ee6-836b-2f64ffdfc6f2"
                },
                {
                    "_links": {
                        "self": {
                            "href": "/api/storage/volumes/eae96ac3-1d00-11ef-9468-00a098fe4958/snapshots/0fe44f3f-4622-452d-b79d-580f67348050"
                        }
                    },
                    "name": "snapmirror.488a7ee5-762f-11e8-a2c2-00a098daa2f9_2152116301.2024-07-18_093000",
                    "uuid": "0fe44f3f-4622-452d-b79d-580f67348050"
                }
            ]
        }
    }
}

ripe hearth
#

Your loop isn't deep enough - you need to go down to the 'records' level

#

Start with how you state it in the debug:msg section (results_snapshot1.ontap_info) then add the storage/volumes/snapshots and finally 'records' at the end - that will become the [item]

#

{{ results_snapshot1['ontap_info']['storage/volumes/snapshots']['records'] }}

#

Less typing if you tell it to use python keys in the result

#

results_snapshots1.ontap_info.storage_volumes_snapshots.records

urban crag
buoyant oyster
#

Ya use rest_python_keys will make it easier to use.

https://docs.ansible.com/ansible/devel/collections/netapp/ontap/na_ontap_rest_info_module.html#parameter-use_python_keys
`If true, / in the returned dictionary keys are translated to _.

It makes it possible to use a . notation when processing the output.

For instance ontap_info[“svm/svms”] can be accessed as ontap_info.svm_svms.`

Because we didn't wnat to break existing user playbook we didn't enable this by default when it was add (even though it would make user lives easier)

urban crag
#

Converting to Python keys is in progress, I wanted to get the whole mess functional and then make the changes (began before I learned about it) but I respect the advice.

That said,

    - name: Gather Snapshot_Volume nonsense
        netapp.ontap.na_ontap_rest_info:
          hostname: "{{ g_hostname }}"
          username: "{{ g_username }}"
          password: "{{ g_password }}"
          gather_subset:
          https: true
          validate_certs: false
          use_rest: Always
          gather_subset:
            - storage/volumes/snapshots
          owning_resource:
            volume_name: "{{ parent_volume }}"
            svm_name: "{{ parent_vserver }}"
          validate_certs: false
        register: results_snapshot
        no_log: false

      - name: "debug results_snapshot"
        debug:
          msg: "{{ results_snapshot.ontap_info.storage_volumes_snapshots.records }}"```

Nets extremely similar results.

ASK [debug results_snapshot] **************************************************
[prxy]: FAILED! => {"msg": "The task includes an option with an undefined variable. The error was: 'dict object' has no attribute 'storage_volumes_snapshots'. 'dict object' has no attribute 'storage_volumes_snapshots'\n\nThe error appears to be in '/tmp/rundeck/ansible-runner7024950185485190580playbook': line 155, column 9, but may\nbe elsewhere in the file depending on the exact syntax problem.\n\nThe offending line appears to be:\n\n\n - name: "debug results_snapshot"\n ^ here\n"}

ripe hearth
#

You need to add “use_python_keys: true” to the rest_info request to use the dot notation.

urban crag
#

I know, it's set at the global level in the playbook, right after hard defining my python interpreter to 3.11
Use_python_keys: true
hal_linking: false
🙂

#

I'd be more than happy to send more of the book, but it's going to take a bit to anonamize it for semi-public consumption

#

Actually, I lied.

#

It's just yuge

ripe hearth
#

Put it in the module directly at the same level as use_rest: always

#

It's not an implicit setting - it has to be specified with the module or use module_defaults for the ontap collection

urban crag
#

Mmmmm that is good to know and would explain some odd results I got earlier

#

That's the ticket