【问题标题】:Merge/Combine top level of dictionary合并/合并顶级字典
【发布时间】:2021-12-19 13:22:04
【问题描述】:

我正在尝试从存储在 ansible 中不同环境变量中的服务器创建字典。

我目前拥有的是:

env_loadbalancer_vservers2: "{{ hostvars[inventory_hostname] | dict2items | selectattr('key', 'match', 'env_.*_loadbalancer_vservers(?![_.])') | list | items2dict }} "

哪个会:

  1. 获取特定主机的 ansible 中的所有变量,
  2. 将字典更改为项目类型
  3. 因为我们现在可以轻松访问键值,所以我将只匹配我想要使用正则表达式的键
  4. 改回列表
  5. 返回字典

问题是输出看起来像这样:

{
     "env_decision_manager_loadbalancer_vservers": {
         "decision_central": {
             "ip_or_dns": "ip",
             "port": "port",
             "protocol": "SSL",
             "ssl": true,
             "timeout": 600,
         }
     },
     "env_ftp_loadbalancer_vservers": {
         "ftp_1": {
             "ip_or_dns": "ip",
             "port": "port",
             "protocol": "FTP",
             "ssl": false,
             "timeout": 9010,
         }
     },
     "env_jboss_loadbalancer_vservers": {
         "jboss": {
             "ip_or_dns": "ip",
             "port": "port",
             "protocol": "SSL",
             "ssl": true,
             "timeout": 600,
         }
         "jboss_adm": {
             "ip_or_dns": "som_other_ip",
             "port": "rando_number",
             "protocol": "SSL",
             "ssl": true,
             "timeout": 86410,
         }
     }

而我想要的输出应该是这样的:

{
         "decision_central": {
             "ip_or_dns": "ip",
             "port": "port",
             "protocol": "SSL",
             "ssl": true,
             "timeout": 600,
         },
         "ftp_1": {
             "ip_or_dns": "ip",
             "port": "port",
             "protocol": "FTP",
             "ssl": false,
             "timeout": 9010,
         },
         "jboss": {
             "ip_or_dns": "ip",
             "port": "port",
             "protocol": "SSL",
             "ssl": true,
             "timeout": 600,
         },
         "jboss_adm": {
             "ip_or_dns": "som_other_ip",
             "port": "rando_number",
             "protocol": "SSL",
             "ssl": true,
             "timeout": 86410,
         }

所以实际上我需要删除“顶级关键层”并合并它们的值。我在这个解决方案上花了很长时间没有任何好的进展,我很乐意提供任何建议:)

PS。解决方案应该是“干净的”,没有任何自定义模块或实际任务,最好的办法是在上面提到的过滤器管道中添加一些函数,这将导致正确的 dict 格式

谢谢你:)

【问题讨论】:

  • 你的json有问题,"timeout": number,都应该是"timeout": number,是不是错字?
  • 是的,对不起,这是错字,我在从 json 发布问题时删除了一些东西,我错过了一些细节 :)

标签: dictionary ansible jinja2 flatten ansible-filter


【解决方案1】:

选择属性值

  regexp: 'env_.*_loadbalancer_vservers(?![_.])'
  l1: "{{ hostvars[inventory_hostname]|
          dict2items|
          selectattr('key', 'match', regexp)|
          map(attribute='value')|
          list }}"

给出列表

  l1:
  - decision_central:
      ip_or_dns: ip
      port: port
      protocol: SSL
      ssl: true
      timeout: 600
  - ftp_1: null
      ip_or_dns: IP
      port: port
      protocol: FTP
      ssl: false
      timeout: 9010
  - jboss:
      ip_or_dns: ip
      port: port
      protocol: SSL
      ssl: true
      timeout: 600
    jboss_adm:
      ip_or_dns: som_other_ip
      port: rando_number
      protocol: SSL
      ssl: true
      timeout: 86410

组合列表中的项目

  d1: "{{ {}|combine(l1) }}"

提供您要查找的字典

  d1:
    decision_central:
      ip_or_dns: ip
      port: port
      protocol: SSL
      ssl: true
      timeout: 600
    ftp_1:
      ip_or_dns: ip
      port: port
      protocol: FTP
      ssl: false
      timeout: 9010
    jboss:
      ip_or_dns: ip
      port: port
      protocol: SSL
      ssl: true
      timeout: 600
    jboss_adm:
      ip_or_dns: som_other_ip
      port: rando_number
      protocol: SSL
      ssl: true
      timeout: 86410

【讨论】:

  • 谢谢! :) 您的解决方案适用于预期结果。我需要为此使用 2 个变量有点不方便,但它仍然比我可以完成的要多得多:D
  • 根本不需要变量。为了便于理解,我将它们放入示例中。如果需要,您可以将 l1 替换为表达式 env_loadbalancer_vservers2: "{{ {}|combine(l1) }}"。不客气! :)
  • 是的,我的意思是我需要先创建 l1,然后我可以创建所需的变量。理想情况是: env_loadbalancer_vservers2: "{{ hostvars[inventory_hostname]| dict2items| selectattr('key', 'match', regexp)| map(attribute='value')| list | combine(??????)) }} " 或类似的东西
猜你喜欢
  • 2018-10-07
  • 2010-12-28
  • 1970-01-01
  • 1970-01-01
  • 2011-01-22
  • 2020-12-28
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多