使用Ansible从一行文本中提取两个字符串



我从shell输出中得到了这个列表。

- 192.168.20.76:3260,1054 iqn.1992-08.com.netapp:sn.f4bc76f43e2611e883e200a098d2174a:vs.6
- 192.168.21.126:3260,1056 iqn.1992-08.com.netapp:sn.f4bc76f43e2611e883e200a098d2174a:vs.6
- 192.168.21.125:3260,1055 iqn.1992-08.com.netapp:sn.f4bc76f43e2611e883e200a098d2174a:vs.6
- 192.168.20.75:3260,1053 iqn.1992-08.com.netapp:sn.f4bc76f43e2611e883e200a098d2174a:vs.6
- 192.168.22.20:3260,1052 iqn.1992-08.com.netapp:sn.f4bc76f43e2611e883e200a098d2174a:vs.6
- 192.168.22.19:3260,1051 iqn.1992-08.com.netapp:sn.f4bc76f43e2611e883e200a098d2174a:vs.6

我想同时得到IP和iqn。

当IP地址与主机在同一vlan时,从列表中删除。我能够创建正确的IP列表,但无法弄清楚如何也获得相应的iqn。

代码:

- hosts: test_server
gather_facts: yes 
tasks: 
- name:
set_facts:
iscsi_vlan: '192.168.20.64/28'
- name: iscsiadm discovery
command: /usr/sbin/iscsiadm iscsiadm --mode discovery --type sendtargets --portal {{ storage_fqdn }}
register: iscsiadm_out
- name: facts
set_fact:
target_list: "{{ target_list + item | regex_findall('(^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})') | ipaddr( iscsi_vlan ) }}"
loop: "{{ iscsiadm_out.stdout_lines }}"
- name: target_list
debug: 
var: target_list

target_list包含这个。使用ip_addr函数匹配正确的子网。

ok: [test-server] => 
target_list:
- 192.168.20.76
- 192.168.20.75

基本上,我最终尝试在一个列表中搜索另一个列表的内容。

  • 我已经尝试过with_subbelements,但它需要一个字符串和一个列表
  • 我试着弄清楚如何用正则表达式一次从iscsiadm_out中提取正确的IP和iqn,但不能。
  • 我考虑把iscsiadm_out变成json对象,然后使用json_query,但我不知道如何做到这一点。

我如何使用这个列表从iscsiadm_out或可能以完全不同的方式提取iqn ?

我知道我可以在命令模块中使用像grep和awk这样的命令,但是我不喜欢这个选项。

在我的测试中,我在这里和互联网上的其他地方搜索了几个小时。我是Ansible的新手,也是python和jinja2的新手,但我也尝试过调查这些路径,但无济于事。

还有其他方法可以实现相同的结果,但您可以在以下概念的基础上进行构建。我只是在一个字典列表(每个字典包含一个ip/iqn对)中立即提取您期望的信息,并在其上循环以过滤出期望的元素。

演示剧本:

---
- name: Extract IP and IQN
hosts: localhost
gather_facts: false
vars:
# This is what you get from your command
iscsiadm:
stdout_lines:
- 192.168.20.76:3260,1054 iqn.1992-08.com.netapp:sn.f4bc76f43e2611e883e200a098d2174a:vs.6
- 192.168.21.126:3260,1056 iqn.1992-08.com.netapp:sn.f4bc76f43e2611e883e200a098d2174a:vs.6
- 192.168.21.125:3260,1055 iqn.1992-08.com.netapp:sn.f4bc76f43e2611e883e200a098d2174a:vs.6
- 192.168.20.75:3260,1053 iqn.1992-08.com.netapp:sn.f4bc76f43e2611e883e200a098d2174a:vs.6
- 192.168.22.20:3260,1052 iqn.1992-08.com.netapp:sn.f4bc76f43e2611e883e200a098d2174a:vs.6
- 192.168.22.19:3260,1051 iqn.1992-08.com.netapp:sn.f4bc76f43e2611e883e200a098d2174a:vs.6
iscsi_vlan: '192.168.20.64/28'
tasks:
- name: "Create a list of {ip: x, iqn: y} dicts from the command result"
vars:
current_entry:
- ip: >-
{{ item | regex_replace('(^(d{1,3}.){3}d{1,3}).*$', 'g<1>') }}
iqn: >-
{{ item | regex_replace('^.* (iqn.d*-d*.com.netapp).*$', 'g<1>') }}
set_fact:
ipqn_list: "{{ ipqn_list | default([]) + current_entry }}"
loop: "{{ iscsiadm.stdout_lines }}"
- name: Debug element when ip is in our subnet (change to whatever is relevant)
debug:
msg: "IP {{ item.ip }} with IQN {{ item.iqn }} is in our subnet"
loop: "{{ ipqn_list }}"
when: item.ip | ipaddr(iscsi_vlan)

给出结果:

PLAY [Extract IP and IQN] **************************************************************************************************************************************************************************************************************
TASK [Create a list of {ip: x, iqn: y} dicts from the command result] ******************************************************************************************************************************************************************
ok: [localhost] => (item=192.168.20.76:3260,1054 iqn.1992-08.com.netapp:sn.f4bc76f43e2611e883e200a098d2174a:vs.6)
ok: [localhost] => (item=192.168.21.126:3260,1056 iqn.1992-08.com.netapp:sn.f4bc76f43e2611e883e200a098d2174a:vs.6)
ok: [localhost] => (item=192.168.21.125:3260,1055 iqn.1992-08.com.netapp:sn.f4bc76f43e2611e883e200a098d2174a:vs.6)
ok: [localhost] => (item=192.168.20.75:3260,1053 iqn.1992-08.com.netapp:sn.f4bc76f43e2611e883e200a098d2174a:vs.6)
ok: [localhost] => (item=192.168.22.20:3260,1052 iqn.1992-08.com.netapp:sn.f4bc76f43e2611e883e200a098d2174a:vs.6)
ok: [localhost] => (item=192.168.22.19:3260,1051 iqn.1992-08.com.netapp:sn.f4bc76f43e2611e883e200a098d2174a:vs.6)
TASK [Debug element when ip is in our subnet (change to whatever is relevant)] *********************************************************************************************************************************************************
ok: [localhost] => (item={'ip': '192.168.20.76', 'iqn': 'iqn.1992-08.com.netapp'}) => {
"msg": "IP 192.168.20.76 with IQN iqn.1992-08.com.netapp is in our subnet"
}
skipping: [localhost] => (item={'ip': '192.168.21.126', 'iqn': 'iqn.1992-08.com.netapp'}) 
skipping: [localhost] => (item={'ip': '192.168.21.125', 'iqn': 'iqn.1992-08.com.netapp'}) 
ok: [localhost] => (item={'ip': '192.168.20.75', 'iqn': 'iqn.1992-08.com.netapp'}) => {
"msg": "IP 192.168.20.75 with IQN iqn.1992-08.com.netapp is in our subnet"
}
skipping: [localhost] => (item={'ip': '192.168.22.20', 'iqn': 'iqn.1992-08.com.netapp'}) 
skipping: [localhost] => (item={'ip': '192.168.22.19', 'iqn': 'iqn.1992-08.com.netapp'}) 
PLAY RECAP *****************************************************************************************************************************************************************************************************************************
localhost                  : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

解析列表中的项并创建字典,例如

- set_fact:
ipqn_dict: "{{ ipqn_dict|default({})|
combine({index: {'ip': ip,
'port': port,
'iqn': iqn,
'code': code,
'vs': vs}}) }}"
loop: "{{ iscsiadm_out.stdout_lines }}"
vars:
a: "{{ item.split(',') }}"
ip: "{{ a.0.split(':').0 }}"
port: "{{ a.0.split(':').1 }}"
b: "{{ a.1.split(' ') }}"
index: "{{ b.0 }}"
iqn: "{{ b.1.split(':').0 }}"
code: "{{ b.1.split(':').1 }}"
vs: "{{ b.1.split(':').2 }}"

ipqn_dict:
'1051':
code: sn.f4bc76f43e2611e883e200a098d2174a
ip: 192.168.22.19
iqn: iqn.1992-08.com.netapp
port: '3260'
vs: vs.6
'1052':
code: sn.f4bc76f43e2611e883e200a098d2174a
ip: 192.168.22.20
iqn: iqn.1992-08.com.netapp
port: '3260'
vs: vs.6
'1053':
code: sn.f4bc76f43e2611e883e200a098d2174a
ip: 192.168.20.75
iqn: iqn.1992-08.com.netapp
port: '3260'
vs: vs.6
'1054':
code: sn.f4bc76f43e2611e883e200a098d2174a
ip: 192.168.20.76
iqn: iqn.1992-08.com.netapp
port: '3260'
vs: vs.6
'1055':
code: sn.f4bc76f43e2611e883e200a098d2174a
ip: 192.168.21.125
iqn: iqn.1992-08.com.netapp
port: '3260'
vs: vs.6
'1056':
code: sn.f4bc76f43e2611e883e200a098d2174a
ip: 192.168.21.126
iqn: iqn.1992-08.com.netapp
port: '3260'
vs: vs.6

这应该简化所需数据的选择,例如

- debug:
msg: "{{ ipqn_dict|json_query('*.[ip,iqn]') }}"

- - 192.168.20.76
- iqn.1992-08.com.netapp
- - 192.168.21.126
- iqn.1992-08.com.netapp
- - 192.168.21.125
- iqn.1992-08.com.netapp
- - 192.168.20.75
- iqn.1992-08.com.netapp
- - 192.168.22.20
- iqn.1992-08.com.netapp
- - 192.168.22.19
- iqn.1992-08.com.netapp

最新更新