json 使用Ansible比较两个字典列表,并使用两者的元素创建新结构的更有效方法

kmynzznz  于 2023-10-21  发布在  其他
关注(0)|答案(2)|浏览(119)

我有一个Ansible剧本,负责使用API创建项目。为了检查我刚刚创建的东西是否工作正常,我从另一个API端点提取了状态信息(创建后)。然后,我需要根据刚刚创建的内容检查状态信息,以确保一切正常工作。
收集的有关状态的信息存储在另一个字典列表中,该列表包含来自两个列表的信息。然后检查生成的信息,以查看是否一切正常。我有一些代码,部分解决了这个问题,但它充满了循环,不是很有效。
所以我想知道是否有人可以帮助我解决上面的问题。
关于我正在创建的东西的信息已经从一个.csv文件中读取,结果列表看起来像这样(为了隐私,数据已经被故意混淆和截断,但结构是正确的)输出是按照community.general.read_csv读取的csv文件内容存储在变量csv_test_data上的ansible.builtin.debug输出:

ok: [...] => {
  "csv_test_data" : {
    "changed": false,
    "dict": {},
    "failed": false,
    "list": [
      {
        "Service GroupWebservice": "SERVICE_GROUP_01",
        "ServiceGroupWebsite": "SITE_GROUP_01",
        "ServiceIP1": "1.1.1.1",
        "Service1ServerName": "SERVER0101",
        "ServiceIP2": "2.2.2.2",
        "Service2ServerName": "SERVER0102",
        "WebServiceIP1": "10.10.10.10",
        "WebService1ServerName": "WEBSERVER0101",
        "WebServiceIP2": "11.11.11.11",
        "WebService2ServerName": "WEBSERVER0102",
        "EnvironmentName": "TEST",
        "CustomerName": "CUSTOMER01",
        "WebserviceMonitorName": "MON_WEBSERVICE_01",
        "WebsiteMonitorName": "MON_WEBSITE_01"
      },
      {
        "Service GroupWebservice": "SERVICE_GROUP_02",
        "ServiceGroupWebsite": "SITE_GROUP_02",
        "ServiceIP1": "5.5.5.5",
        "Service1ServerName": "SERVER0201",
        "ServiceIP2": "6.6.6.6",
        "Service2ServerName": "SERVER0202",
        "WebServiceIP1": "15.15.15.15",
        "WebService1ServerName": "WEBSERVER0201",
        "WebServiceIP2": "16.16.16.16",
        "WebService2ServerName": "WEBSERVER0202",
        "EnvironmentName": "TEST",
        "CustomerName": "CUSTOMER02",
        "WebserviceMonitorName": "MON_WEBSERVICE_02",
        "WebsiteMonitorName": "MON_WEBSITE_02"
      },
      ...
    ]
  }
}

我正在检查的状态信息包含在从API端点提取的另一个字典列表中。这包含有关运行状况监视器的所有示例的状态信息;也就是说,比我刚才创建的要多,所以我需要与这些信息的子集进行比较。同样,结构是正确的,直接从变量get_reponse_operansible.builtin.debug输出中获取,但数据被混淆和截断。

ok: [...] => {
  "get_response_oper": {
    ...
    "changed": false,
    "failed": false,
    "json": {
      "health-stat": {
        ...
        "oper": {
          "health-check-list" [
            {
              ...
              "down-cause": 101,
              "down-state": 10,
              "health-monitor": "default",
              "ip-address": "200.200.200.200",
              "server": "SOMESERVER",
              "status": "DOWN"
            },
            {
              ...
              "down-cause": 7,
              "down-state": 8,
              "health-monitor": "MON_WEBSERVICE_01",
              "ip-address": "1.1.1.1",
              "server": "SERVER0101",
              "status": "UP"
            },
            {
              ...
              "down-cause": 7,
              "down-state": 8,
              "health-monitor": "MON_WEBSERVICE_01",
              "ip-address": "2.2.2.2",
              "server": "SERVER0102",
              "status": "UP"
            },
            {
              ...
              "down-cause": 41,
              "down-state": 10,
              "health-monitor": "MON_WEBSITE_02",
              "ip-address": "15.15.15.15",
              "server": "WEBSERVER0201",
              "status": "DOWN"
            },
            ...
          ]
        }
      }
    }
  }
}

就我正在生成的内容而言,我想创建一个字典列表,这样我就可以查看/检查每个创建项目的状态。
在此列表中,每个客户将有一个条目,即初始创建.csv文件中的每一行对应一个IP地址(每个客户有四个IP地址,两个用于服务器,两个用于Web服务器)。
每个监视器的状态取自第二个列表(存储在health-check-list中),使用取自第一个列表的"ip-address"和/或"server"进行交叉引用。

{
  "health_monitor_statuses": [
    {
      "customer": "CUSTOMER01",
      "serviceIp1": "UP",
      "serviceIP2": "UP",
      "site1IP1": "UP",
      "site2IP2": "UP"
    },
    {
      "customer": "CUSTOMER02",
      "serviceIp1": "DOWN",
      "serviceIP2": "DOWN",
      "site1IP1": "DOWN",
      "site2IP2": "DOWN"
    }
  ]
}

最后,我将遍历创建的health_monitor_statuses列表,如果看到任何"DOWN""UNKN"条目,则会失败。
我相信这在Ansible中是可能的/合理的。任何帮助/指导将不胜感激。
我尝试了许多不同的方法来解决这个问题。
最新的由任务文件组成,每个客户在循环中调用。任务文件的代码如下:
我真的不喜欢代码,因为有太多的循环,它并没有给我留下非常快/高效的印象。这让我觉得一定有更好的办法。

---

- name: "Find the status for the first service IP address {{ health_monitor_test.ServiceIP1 }}."
  no_log: true
  ansible.builtin.set_fact:
    health_check_service1_status: "{{ checking_service1.status }}"
  loop:
    "{{ health_monitor_status_list }}"
  loop_control:
    loop_var: checking_service1
  when: checking_service1['ip-address'] == health_monitor_test.ServiceIP1

- name: "Find the status for the second service IP address {{ health_monitor_test.ServiceIP2 }}."
  no_log: true
  ansible.builtin.set_fact:
    health_check_service2_status: "{{ checking_service2.status }}"
  loop:
    "{{ health_monitor_status_list }}"
  loop_control:
    loop_var: checking_service2
  when: checking_service2['ip-address'] == health_monitor_test.ServiceIP2

- name: "Find the status for the first web site IP address {{ health_monitor_test.WebServiceIP1 }}."
  no_log: true
  ansible.builtin.set_fact:
    health_check_site1_status: "{{ checking_site1.status }}"
  loop:
    "{{ health_monitor_status_list }}"
  loop_control:
    loop_var: checking_site1
  when: checking_site1['ip-address'] == health_monitor_test.WebServiceIP1

- name: "Find the status for the second web site IP address {{ health_monitor_test.WebServiceIP2 }}."
  no_log: true
  ansible.builtin.set_fact:
    health_check_site2_status: "{{ checking_site2.status }}"
  loop:
    "{{ health_monitor_status_list }}"
  loop_control:
    loop_var: checking_site2
  when: checking_site2['ip-address'] == health_monitor_test.WebServiceIP2

- name: "Create the basic structure that will store the health monitor statuses."
  ansible.builtin.set_fact:
    temp: "{
      'customer' : {{ health_monitor_test.CustomerName }},
      'serviceIp1' : {{ health_check_service1_status | default('undefined') }},
      'service2Ip' : {{ health_check_service2_status | default('undefined') }},
      'site1Ip' : {{ health_check_site1_status | default('undefined') }},
      'site2Ip' : {{ health_check_site2_status | default('undefined') }}
    }"

- name: "Add the heartbeat statuses for customer {{ health_monitor_test.TMC_Manifest_CustomerName }} to the main structure."
  no_log: true
  ansible.builtin.set_fact:
    health_monitor_statuses: "{{ health_monitor_statuses + [temp] }}"
7cjasjjr

7cjasjjr1#

创建IP及其状态的字典

hcd: "{{ health_check_list|
           items2dict(key_name='ip-address', value_name='status') }}"

hcd:
    1.1.1.1: UP
    10.10.10.10: UP
    11.11.11.11: UP
    15.15.15.15: DOWN
    16.16.16.16: DOWN
    2.2.2.2: UP
    5.5.5.5: DOWN
    6.6.6.6: DOWN

然后,使用Jinja并创建您想要的内容

health_monitor_statuses: |
    {% filter from_yaml %}
    {% for i in csv_test_data.list %}
    - customer: {{ i.CustomerName }}
      serviceIP1: {{ hcd[i.ServiceIP1] }}
      serviceIP2: {{ hcd[i.ServiceIP2] }}
      siteIP1: {{ hcd[i.WebServiceIP1] }}
      siteIP2: {{ hcd[i.WebServiceIP2] }}
    {% endfor %}
    {% endfilter %}

health_monitor_statuses:
  - customer: CUSTOMER01
    serviceIP1: UP
    serviceIP2: UP
    siteIP1: UP
    siteIP2: UP
  - customer: CUSTOMER02
    serviceIP1: DOWN
    serviceIP2: DOWN
    siteIP1: DOWN
    siteIP2: DOWN

mre测试手册示例

- hosts: all

  vars:

    csv_test_data:
      list:
        - CustomerName: CUSTOMER01
          ServiceIP1: 1.1.1.1
          ServiceIP2: 2.2.2.2
          WebServiceIP1: 10.10.10.10
          WebServiceIP2: 11.11.11.11
        - CustomerName: CUSTOMER02
          ServiceIP1: 5.5.5.5
          ServiceIP2: 6.6.6.6
          WebServiceIP1: 15.15.15.15
          WebServiceIP2: 16.16.16.16

    health_check_list:
      - {ip-address: 1.1.1.1, status: UP}
      - {ip-address: 2.2.2.2, status: UP}
      - {ip-address: 5.5.5.5, status: DOWN}
      - {ip-address: 6.6.6.6, status: DOWN}
      - {ip-address: 10.10.10.10, status: UP}
      - {ip-address: 11.11.11.11, status: UP}
      - {ip-address: 15.15.15.15, status: DOWN}
      - {ip-address: 16.16.16.16, status: DOWN}

    hcd: "{{ health_check_list|
             items2dict(key_name='ip-address', value_name='status') }}"

    health_monitor_statuses: |
      {% filter from_yaml %}
      {% for i in csv_test_data.list %}
      - customer: {{ i.CustomerName }}
        serviceIP1: {{ hcd[i.ServiceIP1] }}
        serviceIP2: {{ hcd[i.ServiceIP2] }}
        siteIP1: {{ hcd[i.WebServiceIP1] }}
        siteIP2: {{ hcd[i.WebServiceIP2] }}
      {% endfor %}
      {% endfilter %}

  tasks:

    - debug:
        var: csv_test_data
    - debug:
        var: health_check_list
    - debug:
        var: hcd
    - debug:
        var: health_monitor_statuses
kxxlusnw

kxxlusnw2#

这个解决方案很好,谢谢。

相关问题