我试图让Ansible读取文件并选择我的搜索参数的第一个匹配,以及删除不需要的文本。
例如,我有
下面的文件<Proxy balancer://${balancerNameEAPI}>
# BalancerMember https://server1.domain.com:port hctemplate=tcp
BalancerMember https://server2.domain.com:port hctemplate=tcp
ProxySet lbmethod=bybusyness
</Proxy>
<Proxy balancer://${balancerNamePAPI}>
# BalancerMember https://server1.domain.com:port hctemplate=tcp
BalancerMember https://server2.domain.com:port hctemplate=tcp
ProxySet lbmethod=bybusyness
</Proxy>
<Proxy balancer://${balancerNameSAPI}>
# BalancerMember https://server1.domain.com:port hctemplate=tcp
BalancerMember https://server2.domain.com:port hctemplate=tcp
ProxySet lbmethod=bybusyness
</Proxy>
我需要对注释掉的备用主机采取行动,在这种情况下是server1
。
我使用下面的脚本读取这个配置文件,并取出包含正确主机的行。
---
- name: test read file
hosts: localhost
gather_facts: false
vars:
source_file: /files/test/test.cfg
host_to_patch: []
tasks:
- set_fact:
host_to_patch: "{{ host_to_patch + [ item ] }}"
with_lines: "cat {{ source_file }}"
when: item is search('^# BalancerMember https://server')
- debug:
var: host_to_patch
这当然给了我整行三次的输出,我只对该行的server1.domain.com
部分感兴趣,此时我只需要第一个匹配。我想告诉Ansible这是剧本中另一个游戏的目标主机名。这样做的原因是,文件中的服务器是一对活动的备用服务器,我需要从备用主机开始,每次执行一个,每个月可能不同。
下面是当前的输出
ok: [localhost] => {
"host_to_patch": [
"# BalancerMember https://server1.domain.com:port hctemplate=tcp",
"# BalancerMember https://server1.domain.com:port hctemplate=tcp",
"# BalancerMember https://server1.domain.com:port hctemplate=tcp"
]
}
如果有任何进一步的信息会有帮助,请让我知道,并提前感谢!
用例
我正试图让Ansible读取文件并选择我的搜索参数的第一个匹配,以及删除不需要的文本。
假设您的配置示例文件中的结构保持原样,并且您正在寻找一个完整的Ansible等效于我如何在匹配后grep一个单词?
- name: Gather standby hostname
shell:
cmd: grep -Po 'https://K.*' test.cfg | head -1 | cut -d ':' -f 1
register: standby_hostname
解决方案您可以查看slurp
模块-从远程节点和最小示例playbook中Slurps文件
---
- hosts: localhost
become: false
gather_facts: false
tasks:
- name: Read config file
slurp:
src: test.cfg
register: config
- name: Show config file
debug:
msg: "{{ config['content'] | b64decode }}"
- name: Show first result
debug:
msg: "{{ config['content'] | b64decode | regex_findall('https://(.+)') | first | split(':') | first }}"
,结果是输出
TASK [Show first result] ******
ok: [localhost] =>
msg: server1.domain.com
使用slurp
模块
…用于获取包含远程文件中数据的base64编码blob。
因此b64decode
过滤器-解码base64字符串是进一步处理所必需的。
regex_findall
过滤器-从字符串中提取https://
和(.+)
匹配后的所有regex匹配。
因为它将提供一个列表,Jinja2 Filterfirst
将只给出第一个结果。
split
过滤器-将字符串与first
过滤器一起拆分为列表,然后用于获得:
分隔结果集的左侧。
类似Q&
- 如何从文件中读取一行到Ansible变量?
slurp
可以直接替代lookup
吗?
进一步文档
- 使用过滤器操作数据
- Jinja2模板设计器文档-过滤器和内置过滤器列表
给定文件
shell> cat /tmp/config.xml
<Proxy balancer://${balancerNameEAPI}>
# BalancerMember https://server1.domain.com:65535 hctemplate=tcp
BalancerMember https://server2.domain.com:65535 hctemplate=tcp
ProxySet lbmethod=bybusyness
</Proxy>
<Proxy balancer://${balancerNamePAPI}>
# BalancerMember https://server1.domain.com:65535 hctemplate=tcp
BalancerMember https://server2.domain.com:65535 hctemplate=tcp
ProxySet lbmethod=bybusyness
</Proxy>
<Proxy balancer://${balancerNameSAPI}>
# BalancerMember https://server1.domain.com:65535 hctemplate=tcp
BalancerMember https://server2.domain.com:65535 hctemplate=tcp
ProxySet lbmethod=bybusyness
</Proxy>
读取文件
- name: Read config file
slurp:
src: /tmp/config.xml
register: config
和声明变量
_regex1: '^s*#s*BalancerMember https://server.*$'
_regex2: 'bhttpsS*'
hosts_to_patch: "{{ (config.content|b64decode).splitlines()|
select('regex', _regex1)|
map('regex_search', _regex2)|
map('urlsplit', 'hostname')|
unique }}"
为
hosts_to_patch:
- server1.domain.com
用于测试的完整剧本示例
- hosts: localhost
vars:
_regex1: '^s*#s*BalancerMember https://server.*$'
_regex2: 'bhttpsS*'
hosts_to_patch: "{{ (config.content|b64decode).splitlines()|
select('regex', _regex1)|
map('regex_search', _regex2)|
map('urlsplit', 'hostname')|
unique }}"
tasks:
- name: Read config file
slurp:
src: /tmp/config.xml
register: config
- debug:
var: hosts_to_patch