Ansible:读取 JSON 时出错:传递到“循环”的数据无效,它需要一个列表,改为获取此列表

发布于 2025-01-15 21:31:12 字数 3612 浏览 0 评论 0原文

这是我的 JSON,

[
  {
    "?xml": {
      "attributes": {
        "encoding": "UTF_8",
        "version": "1.0"
      }
    }
  },
  {
    "jdbc_data_source": [
      {
        "attributes": {
          "xmlns": "http://xmlns.oracle.com/weblogic/jdbc_data_source"
        }
      },
      {
        "name": "canwebds"
      },
      {
        "jdbc_driver_params": [
          {
            "url": "jdbc:oracle:thin:@//myhost.mrshmc.com:1521/OLTT206"
          },
          {
            "driver_name": "oracle.jdbc.OracleDriver"
          },
          {
            "properties": {
              "property": [
                {
                  "name": "user"
                },
                {
                  "value": "WEB_USER"
                }
              ]
            }
          },
          {
            "password_encrypted": "{AES}BcqmURyYoCkLvC5MmREXsfpRMO93KPIubqUAbb95+nE="
          }
        ]
      },
      {
        "jdbc_connection_pool_params": [
          {
            "initial_capacity": "1"
          },
          {
            "statement_cache_type": "LRU"
          }
        ]
      },
      {
        "jdbc_data_source_params": {
          "jndi_name": "canwebds"
        }
      }
    ]
  },
  {
    "?xml": {
      "attributes": {
        "encoding": "UTF_8",
        "version": "1.0"
      }
    }
  },
  {
    "jdbc_data_source": [
      {
        "attributes": {
          "xmlns": "http://xmlns.oracle.com/weblogic/jdbc_data_source"
        }
      },
      {
        "name": "dsARSVelocity"
      },
      {
        "jdbc_driver_params": [
          {
            "url": "jdbc:oracle:thin:@myhost:1521:DB01"
          },
          {
            "driver_name": "oracle.jdbc.OracleDriver"
          },
          {
            "properties": {
              "property": [
                {
                  "name": "user"
                },
                {
                  "value": "AP05"
                }
              ]
            }
          },
          {
            "password_encrypted": "{AES}wP5Se+OQdR21hKiC2fDw1WPEaTMU5Sc17Ax0+rmjmPI="
          }
        ]
      },
      {
        "jdbc_connection_pool_params": [
          {
            "initial_capacity": "1"
          },
                    {
            "statement_cache_type": "LRU"
          }
        ]
      },
      {
        "jdbc_data_source_params": [
          {
            "jndi_name": "dsARSVel"
          },
          {
            "global_transactions_protocol": "OnePhaseCommit"
          }
        ]
      }
    ]
  }
]

我需要为任何 jdbc_data_source 找到的

预期输出打印以下内容:

jdbc_data_source name is has username and jndi name;

这将翻译为:

jdbc_data_source name is cwds has username CAN_USER and jndi name cwdsjndi

下面是我尝试过的方法,但它不起作用:

  - name: create YML for server name with DB
    debug:
      msg: "{{ dsname.0.name }} has jndi {{ dsurl[0]['jdbc_driver_params'][2]['properties][0]['property'][1]['value'] }}"
    loop: "{{ jsondata[1] }}"
    vars:
      dsname: "{{ item.jdbc_data_source| selectattr('name', 'defined') | list }}"
      dsurl: "{{ item.jdbc_data_source| selectattr('jdbc_driver_params', 'defined') | list }}"

但是,它没有给我想要的输出。下面是我得到的错误:

致命:[localhost]:失败! => {“msg”:“传递给‘循环’的数据无效, 它需要一个列表,得到这个:{'jdbc_data_source': [{'属性':{'xmlns': 'http://xmlns.oracle.com/weblogic/jdbc_data_source', 'xml

如果我循环 循环:“{{ jsondata }}”,那么它可以工作,但仍然无法打印所需的值。

请建议。

Here is my JSON

[
  {
    "?xml": {
      "attributes": {
        "encoding": "UTF_8",
        "version": "1.0"
      }
    }
  },
  {
    "jdbc_data_source": [
      {
        "attributes": {
          "xmlns": "http://xmlns.oracle.com/weblogic/jdbc_data_source"
        }
      },
      {
        "name": "canwebds"
      },
      {
        "jdbc_driver_params": [
          {
            "url": "jdbc:oracle:thin:@//myhost.mrshmc.com:1521/OLTT206"
          },
          {
            "driver_name": "oracle.jdbc.OracleDriver"
          },
          {
            "properties": {
              "property": [
                {
                  "name": "user"
                },
                {
                  "value": "WEB_USER"
                }
              ]
            }
          },
          {
            "password_encrypted": "{AES}BcqmURyYoCkLvC5MmREXsfpRMO93KPIubqUAbb95+nE="
          }
        ]
      },
      {
        "jdbc_connection_pool_params": [
          {
            "initial_capacity": "1"
          },
          {
            "statement_cache_type": "LRU"
          }
        ]
      },
      {
        "jdbc_data_source_params": {
          "jndi_name": "canwebds"
        }
      }
    ]
  },
  {
    "?xml": {
      "attributes": {
        "encoding": "UTF_8",
        "version": "1.0"
      }
    }
  },
  {
    "jdbc_data_source": [
      {
        "attributes": {
          "xmlns": "http://xmlns.oracle.com/weblogic/jdbc_data_source"
        }
      },
      {
        "name": "dsARSVelocity"
      },
      {
        "jdbc_driver_params": [
          {
            "url": "jdbc:oracle:thin:@myhost:1521:DB01"
          },
          {
            "driver_name": "oracle.jdbc.OracleDriver"
          },
          {
            "properties": {
              "property": [
                {
                  "name": "user"
                },
                {
                  "value": "AP05"
                }
              ]
            }
          },
          {
            "password_encrypted": "{AES}wP5Se+OQdR21hKiC2fDw1WPEaTMU5Sc17Ax0+rmjmPI="
          }
        ]
      },
      {
        "jdbc_connection_pool_params": [
          {
            "initial_capacity": "1"
          },
                    {
            "statement_cache_type": "LRU"
          }
        ]
      },
      {
        "jdbc_data_source_params": [
          {
            "jndi_name": "dsARSVel"
          },
          {
            "global_transactions_protocol": "OnePhaseCommit"
          }
        ]
      }
    ]
  }
]

I need to print the below for any jdbc_data_source found

expected output:

jdbc_data_source name is has username and jndi name <jndi_name>

which will translate as:

jdbc_data_source name is cwds has username CAN_USER and jndi name cwdsjndi

Below is something i tried but it does not work:

  - name: create YML for server name with DB
    debug:
      msg: "{{ dsname.0.name }} has jndi {{ dsurl[0]['jdbc_driver_params'][2]['properties][0]['property'][1]['value'] }}"
    loop: "{{ jsondata[1] }}"
    vars:
      dsname: "{{ item.jdbc_data_source| selectattr('name', 'defined') | list }}"
      dsurl: "{{ item.jdbc_data_source| selectattr('jdbc_driver_params', 'defined') | list }}"

However, it does not get me the desired output. Below is the error i get:

fatal: [localhost]: FAILED! => {"msg": "Invalid data passed to 'loop',
it requires a list, got this instead: {'jdbc_data_source':
[{'attributes': {'xmlns':
'http://xmlns.oracle.com/weblogic/jdbc_data_source', 'xml

If I loop loop: "{{ jsondata }}", then it works but the desired values still do not get printed.

Kindly suggest.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

流绪微梦 2025-01-22 21:31:12

这个剧本的工作:

- hosts: localhost
  gather_facts: no
  vars:
    json: "{{ lookup('file', 'file.json') | from_json }}"
  tasks:
    - name: display datas
      debug:
        msg: "jdbc_data_source name is {{ name }} has username: {{ user }} and jndi name: {{ jndiname }}"
      loop: "{{ json }}" 
      when: item.jdbc_data_source is defined
      vars:
        datasource1: "{{ item.jdbc_data_source | selectattr('jdbc_driver_params', 'defined') }}"
        properties: "{{ (datasource1.0.jdbc_driver_params | selectattr('properties', 'defined')).0.properties }}"

        name: "{{ (item.jdbc_data_source | selectattr('jdbc_data_source_params', 'defined')).0.jdbc_data_source_params.jndi_name }}"
        user: "{{ (properties.property |  selectattr('value', 'defined')).0.value }}"
        jndiname: "{{ (item.jdbc_data_source | selectattr('name', 'defined') ).0.name}}"

结果:

skipping: [localhost] => (item={'?xml': {'attributes': {'encoding': 'UTF_8', 'version': '1.0'}}}) 
ok: [localhost] => "msg": "jdbc_data_source name is cwds has username: CAN_USER and jndi name: cwdsjndi"
}
skipping: [localhost] => (item={'?xml': {'attributes': {'encoding': 'UTF_8', 'version': '1.0'}}}) 
ok: [localhost] => "msg": "jdbc_data_source name is dsvelcw has username: WEB_USER and jndi name: dsvelcw"

如果你有列表和字典的混合,改变:

  vars:
    datasource1: "{{ item.jdbc_data_source | selectattr('jdbc_driver_params', 'defined') }}"
    properties: "{{ (datasource1.0.jdbc_driver_params | selectattr('properties', 'defined')).0.properties }}"
    params: "{{ (item.jdbc_data_source | selectattr('jdbc_data_source_params', 'defined')).0.jdbc_data_source_params }}"

    name: "{{ params.jndi_name if params is mapping else (params | selectattr('jndi_name', 'defined')).0.jndi_name }}"           
    user: "{{ (properties.property |  selectattr('value', 'defined')).0.value }}"
    jndiname: "{{ (item.jdbc_data_source | selectattr('name', 'defined') ).0.name}}"

我测试它是否是一个字典,否则它是一个列表..

结果与新的json:

skipping: [localhost] => (item={'?xml': {'attributes': {'encoding': 'UTF_8', 'version': '1.0'}}}) 
    "msg": "jdbc_data_source name is canwebds has username: WEB_USER and jndi name: canwebds"
}
skipping: [localhost] => (item={'?xml': {'attributes': {'encoding': 'UTF_8', 'version': '1.0'}}}) 
    "msg": "jdbc_data_source name is dsARSVel has username: AP05 and jndi name: dsARSVelocity"
}

一些解释:

(item.jdbc_data_source | selectattr('jdbc_data_source_params', 'define')) selectattr 创建一个包含所有键的列表 jdbc_data_source_params列表中存在jdbc_data_source,这里只有一个键jdbc_data_source_params,因此0.jdbc_data_source_params选择第一个键。

然后我们检查 params 是否是一个字典,否则它是一个列表

,如果你想理解,我建议你分解很多动作并显示调试结果。

仅供参考 selectattr 与 json_query 等效

selectattr('something', 'define') = json_query("[?something]")

this playbook does the job:

- hosts: localhost
  gather_facts: no
  vars:
    json: "{{ lookup('file', 'file.json') | from_json }}"
  tasks:
    - name: display datas
      debug:
        msg: "jdbc_data_source name is {{ name }} has username: {{ user }} and jndi name: {{ jndiname }}"
      loop: "{{ json }}" 
      when: item.jdbc_data_source is defined
      vars:
        datasource1: "{{ item.jdbc_data_source | selectattr('jdbc_driver_params', 'defined') }}"
        properties: "{{ (datasource1.0.jdbc_driver_params | selectattr('properties', 'defined')).0.properties }}"

        name: "{{ (item.jdbc_data_source | selectattr('jdbc_data_source_params', 'defined')).0.jdbc_data_source_params.jndi_name }}"
        user: "{{ (properties.property |  selectattr('value', 'defined')).0.value }}"
        jndiname: "{{ (item.jdbc_data_source | selectattr('name', 'defined') ).0.name}}"

result:

skipping: [localhost] => (item={'?xml': {'attributes': {'encoding': 'UTF_8', 'version': '1.0'}}}) 
ok: [localhost] => "msg": "jdbc_data_source name is cwds has username: CAN_USER and jndi name: cwdsjndi"
}
skipping: [localhost] => (item={'?xml': {'attributes': {'encoding': 'UTF_8', 'version': '1.0'}}}) 
ok: [localhost] => "msg": "jdbc_data_source name is dsvelcw has username: WEB_USER and jndi name: dsvelcw"

if you have a mixed of list and dictionary, change:

  vars:
    datasource1: "{{ item.jdbc_data_source | selectattr('jdbc_driver_params', 'defined') }}"
    properties: "{{ (datasource1.0.jdbc_driver_params | selectattr('properties', 'defined')).0.properties }}"
    params: "{{ (item.jdbc_data_source | selectattr('jdbc_data_source_params', 'defined')).0.jdbc_data_source_params }}"

    name: "{{ params.jndi_name if params is mapping else (params | selectattr('jndi_name', 'defined')).0.jndi_name }}"           
    user: "{{ (properties.property |  selectattr('value', 'defined')).0.value }}"
    jndiname: "{{ (item.jdbc_data_source | selectattr('name', 'defined') ).0.name}}"

i test if its a dict else its a list..

result with new json:

skipping: [localhost] => (item={'?xml': {'attributes': {'encoding': 'UTF_8', 'version': '1.0'}}}) 
    "msg": "jdbc_data_source name is canwebds has username: WEB_USER and jndi name: canwebds"
}
skipping: [localhost] => (item={'?xml': {'attributes': {'encoding': 'UTF_8', 'version': '1.0'}}}) 
    "msg": "jdbc_data_source name is dsARSVel has username: AP05 and jndi name: dsARSVelocity"
}

some explanations:

(item.jdbc_data_source | selectattr('jdbc_data_source_params', 'defined')) selectattr create a list with all keys jdbc_data_source_params present in the list jdbc_data_source, here there are only one key jdbc_data_source_params, so the 0.jdbc_data_source_params selects the first key.

then we check if params is a dict else its a list

if you want to understand, i suggest you to decompose in lot of actions and display with debug the result.

FYI selectattr equivalent with json_query

selectattr('something', 'defined') = json_query("[?something]")

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文