Ansible-循环浏览列表并写入其中



我是易解析的初学者,我对易解析的剧本有问题,该剧本应该从多个服务器收集有关系统版本的信息。

第一步是收集关于服务器的信息(如果它使用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}'

在第一次播放中创建一组动态主机名,并在第二次播放中运行。在第二次播放中,将版本注册到变量server_list_versions中。然后迭代ansible_play_hosts并创建字典版本

- 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中的属性版本,请创建一个字典

- 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: ''

然后,使用此字典更新属性版本

- 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}'

最新更新