gpt4 book ai didi

loops - Ansible - 遍历列表并写入其中

转载 作者:行者123 更新时间:2023-12-05 04:32:42 24 4
gpt4 key购买 nike

我是 ansible 初学者,我对 ansible playbook 有疑问,它应该从多个服务器收集有关系统版本的信息。

第一步是收集有关服务器的信息(如果它使用 Jboss 或 Tomcat 以及它在哪里)- 我能够做到并将其存储在列表中,如下所示:

"server_list": [
{
"hostname": "tst-24.ph.koop.cz",
"path": "/srv/ais/test/knz-batch/eap",
"pid": "14660",
"type": "wildfly/jboss",
"version": "",
"version_cmd": "/srv/ais/test/knz-batch/eap/bin/standalone.sh --version"
},
{
"hostname": "tst-24.ph.koop.cz",
"path": "/srv/ais/test/knz-eap/eap",
"pid": "20153",
"type": "wildfly/jboss",
"version": "",
"version_cmd": "/srv/ais/test/knz-eap/eap/bin/standalone.sh --version"
},
{
"hostname": "tst-24.ph.koop.cz",
"path": "/srv/ais/skoleni/knz-ws-int/eap",
"pid": "24861",
"type": "wildfly/jboss",
"version": "",
"version_cmd": "/srv/ais/skoleni/knz-ws-int/eap/bin/standalone.sh --version"
},
{
"hostname": "tst-24.ph.koop.cz",
"path": "/srv/ais/skoleni/knz-ws/wildfly",
"pid": "25195",
"type": "wildfly/jboss",
"version": "",
"version_cmd": "/srv/ais/skoleni/knz-ws/wildfly/bin/standalone.sh --version"
},
{
"hostname": "tst-24.ph.koop.cz",
"path": "/srv/ais/skoleni/knz-ws/undertow",
"pid": "25667",
"type": "tomcat",
"version": "",
"version_cmd": "/srv/ais/skoleni/knz-ws/undertow/bin/version.sh --version"
},
{
"hostname": "tst-24.ph.koop.cz",
"path": "/srv/ais/skoleni/knz/wildfly",
"pid": "26446",
"type": "wildfly/jboss",
"version": "",
"version_cmd": "/srv/ais/skoleni/knz/wildfly/bin/standalone.sh --version"
}
]

现在我需要运行其他 shell 命令(将使用 version_cmd)来获取该版本(使用 GREP)。

但是我不知道循环时如何写入列表。第二个问题是如何制定更多条件(为 wildfly/jboss 使用其他正则表达式)

    - name: Get server version
shell: "{{item.version_cmd}}| grep -Po {{ regexp_tomcat_version }}"
loop: "{{ server_list }}"
loop_control:
label: "Check version for {{ item.path }}"
when: item.type == "tomcat"
register: server_list.version
vars:
regexp_tomcat_version: 'Server version:\s*([^(\n)]*)'
ignore_errors: yes

这在 Ansible 中甚至可能吗?

最佳答案

例如,给出下面的列表进行测试

server_list:
- hostname: srv1
path: /usr/bin/cc
type: prod
version_cmd: cc --version
version_parse: awk 'FNR == 1 {print $4}'
- hostname: srv1
path: /usr/local/bin/python
type: devel
version_cmd: python --version
version_parse: awk 'FNR == 1 {print $2}'
- hostname: srv2
path: /usr/bin/cc
type: prod
version_cmd: cc --version
version_parse: awk 'FNR == 1 {print $4}'
- hostname: srv2
path: /usr/local/bin/python
type: devel
version_cmd: python --version
version_parse: awk 'FNR == 1 {print $2}'

在第一个 play 中创建一个动态的主机名组并在第二个 play 中运行它。在第二步中,将版本注册到变量 server_list_versions 中。然后迭代 ansible_play_hosts 并创建字典 versions

- name: Create group server_group
hosts: localhost
tasks:
- add_host:
name: "{{ item }}"
groups: server_group
server_list: "{{ server_list }}"
loop: "{{ server_list|map(attribute='hostname')|unique }}"

- name: Collect versions
hosts: server_group
gather_facts: false
tasks:
- shell: "{{ item.version_cmd }}|{{ item.version_parse }}"
loop: "{{ server_list|selectattr('hostname', 'eq', inventory_hostname) }}"
loop_control:
label: "Check version for {{ item.path }}"
# when: item.type == "devel"
register: server_list_versions
- set_fact:
versions: "{{ versions|d({})|
combine({item: hostvars[item].server_list_versions.results|
json_query('[].{path: item.path,
version: stdout,
stderr: stderr}')}) }}"
loop: "{{ ansible_play_hosts }}"
run_once: true

给予

versions:
srv1:
- path: /usr/bin/cc
stderr: ''
version: 11.0.1
- path: /usr/local/bin/python
stderr: ''
version: 3.8.12
srv2:
- path: /usr/bin/cc
stderr: ''
version: 11.0.1
- path: /usr/local/bin/python
stderr: '/bin/sh: python: not found'
version: ''

如果你想更新 server_list 中的属性 version 创建一个字典

    - set_fact:
vers_dict: "{{ vers_dict|d({})|
combine({item: hostvars[item].server_list_versions.results|
json_query('[].{path: item.path,
version: stdout}')|
items2dict(key_name='path',
value_name='version')}) }}"
loop: "{{ ansible_play_hosts }}"
run_once: true

给予

vers_dict:
srv1:
/usr/bin/cc: 11.0.1
/usr/local/bin/python: 3.8.12
srv2:
/usr/bin/cc: 11.0.1
/usr/local/bin/python: ''

然后,使用这个字典来更新属性version

    - set_fact:
server_list_new: "{{ server_list_new|d([]) +
[item|combine({'version': version})] }}"
loop: "{{ server_list }}"
vars:
version: "{{ vers_dict[item.hostname][item.path] }}"
run_once: true

给予

server_list_new:
- hostname: srv1
path: /usr/bin/cc
type: prod
version: 11.0.1
version_cmd: cc --version
version_parse: awk 'FNR == 1 {print $4}'
- hostname: srv1
path: /usr/local/bin/python
type: devel
version: 3.8.12
version_cmd: python --version
version_parse: awk 'FNR == 1 {print $2}'
- hostname: srv2
path: /usr/bin/cc
type: prod
version: 11.0.1
version_cmd: cc --version
version_parse: awk 'FNR == 1 {print $4}'
- hostname: srv2
path: /usr/local/bin/python
type: devel
version: ''
version_cmd: python --version
version_parse: awk 'FNR == 1 {print $2}'

关于loops - Ansible - 遍历列表并写入其中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71604503/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com