How to filter and retrieve data from MySQL query result with ansible modules

Viewed 395

So, Im trying to filter two dataframes into a same structure as a type host:user, in order to make an host:user comparison. The first one is from my ansible server and the second one is from MySQL server. But I got any issues to filter json data from MySQL query result with Ansible modules.

Firstly, I tried to retrieve MySQL informations with concat as a JSON:

## Compte MySQL
- name: "Get all MySQL accounts"
  community.mysql.mysql_query:
    login_db: mysql
    query: 
    - SELECT user,JSON_ARRAYAGG(concat(host)) as host from user group by user
  register: sql
  tags: [never,test]

- name: Show all MySQL accounts
  debug:
    var: sql
  tags: [never,test] 

Here is the output:

ok: [staging1-sql0] => {
    "sql": {
        "changed": false,
        "executed_queries": [
            "SELECT user,JSON_ARRAYAGG(concat(host)) as host from user group by user"
        ],
        "failed": false,
        "query_result": [
            [
                {
                    "host": "[\"x.xxx.xx.xxx\"]",
                    "user": "username1"
                },
                {
                    "host": "[\"x.xxx.xx.xxx\"]",
                    "user": "username2"
                },
                {
                    "host": "[\"x.xxx.xx.xxx\"]",
                    "user": "username3"
                },
                {
                    "host": "[\"xx.xxx.xx.xxx\", \"xx.x.x.xxx\"]",
                    "user": "username4"
                },
                {
                    "host": "[\"xx.x.x.xxx\"]",
                    "user": "username5"

Secondly, I converted the output of MySQL into an item, and select the query_result.

- name: Set the MySQL result as an item.
  debug:
    var: item
  loop: "{{ sql | dict2items(key_name='key') }}"
  register: sql_items
  no_log: False
  tags: [never,test]

- name: "Set the dataframe in the same structure host:user"
  set_fact:
    new_sql: "{{ sql_items | community.general.json_query('results[3].{resultats: item.value[0]}') }}"
  tags: [never,test]

- name: Affichage de new_sql
  debug:
    var: new_sql
  tags: [never,test]

Here is the output:

ok: [staging1-sql0] => {
    "new_sql": {
        "resultats": [
            {
                "host": "[\"x.xxx.xx.xxx\"]",
                "user": "username1"
            },
            {
                "host": "[\"x.xxx.xx.xxx\"]",
                "user": "username2"
            },
            {
                "host": "[\"x.xxx.xx.xxx\"]",
                "user": "username3"
            },
            {
                "host": "[\"xx.xxx.xx.xxx\", \"xx.x.x.xxx\"]",
                "user": "username4"
            },
            {
                "host": "[\"xx.x.x.xxx\"]",
                "user": "username5"
            },

Finally, after fitered, I had some problems trying to display data from my resultats dataframe with ansible modules. For example, in order to display only hosts of each user, I tried this :

- name: Display all host names
  debug:
    var: item
  loop: "{{ new_sql | community.general.json_query('resultats[*].host') }}"
  register: query
  tags: [never,test]

But it doesnt work, here is the error result :

fatal: [staging1-sql0]: FAILED! => {"msg": "Invalid data passed to 'loop', it requires a list, got this instead: . Hint: If you passed a list/dict of just one element, try adding wantlist=True to your lookup invocation or use q/query instead of lookup."}

Does anyone of have any idea of how to display those datas with another ansible modules ?

UPDATE :

I finally tried this with map filter :

    - name: New filter with mapping
  debug:
    msg: "{{ new_sql | map(attribute='host') | list }}"
  register: query
  tags: [never,test]

But, I got this output :

ok: [staging1-sql0] => {
    "msg": "[AnsibleUndefined, AnsibleUndefined, AnsibleUndefined,  AnsibleUndefined, AnsibleUndefined, AnsibleUndefined, AnsibleUndefined....

Anyone can help me fix it?

0 Answers
Related