带有正则表达式的 Ansible lineine 文件在不应该添加新行时

Ansible lineine file with regex is adding new line when it shouldn't

我目前有这个配置 nagios nrpe 的文件:

/etc/xinetd.d/nrpe:

# default: on
# description: NRPE (Nagios Remote Plugin Executor)
service nrpe
{
        flags           = REUSE
        socket_type     = stream    
        port            = 5666    
        wait            = no
        user            = nagios
        group           = nagios
        server          = /usr/local/nagios/bin/nrpe
        server_args     = -c /usr/local/nagios/etc/nrpe.cfg --inetd
        log_on_failure  += USERID
        disable         = no
        only_from       = 192.168.1.1 
}

(请注意,only_from 是一个假 IP,但我正在尝试编写 ansible 命令以使其工作,而不管提供的 IP 是什么)

我正在尝试使用 ansible 的 lineinfile 模块来允许我向以 only_from

开头的行添加另一个变量

目前我有:

---
- name: Edit Existing | Edit xinetd.d/nrpe file
  vars: 
    - nagios_ip: 194.54.46.12
  lineinefile:
    backrefs: yes
    backup: yes
    dest: /etc/xinetd.d/nrpe
    line: 'only_from =  {{ nagios_ip }}'
    regexp: '\s*only_from\s+=\s*(((\d{1,3}\.){3}\d{1,3}\s*)*)'

这在大多数情况下都有效。我更改了行,但是 {{ nagios_ip }} 变量被发送到换行符,文件最终看起来像这样,新的 IP 地址在新行上,而不是在同一行上:

# default: on
# description: NRPE (Nagios Remote Plugin Executor)
service nrpe
{
        flags           = REUSE
        socket_type     = stream    
        port            = 5666    
        wait            = no
        user            = nagios
        group           = nagios
        server          = /usr/local/nagios/bin/nrpe
        server_args     = -c /usr/local/nagios/etc/nrpe.cfg --inetd
        log_on_failure  += USERID
        disable         = no
        only_from       = 192.168.1.1 
127.0.0.1
}

因为 ansible/lineinfile 使用 python 的正则表达式引擎,所以我在 python:

中对其进行了测试
>>> s = '      only_from        = 127.0.0.1'
>>> r = '\s*only_from\s+=\s*(((\d{1,3}\.){3}\d{1,3}\s*)*)'
>>> import re
>>> re.match(r,s).group(1)
'127.0.0.1'
>>> re.match(r,s).group(1) + ' 192.168.1.1'
'127.0.0.1 192.168.1.1'
>>> 

它按预期工作。我如何摆脱 ansible 插入的新行?

问题是你也在匹配换行符。不要在你的比赛中包括换行符。这应该有效:

regexp: '\s*only_from\s+=\s*((\d{1,3}\.){3}\d{1,3})\s*'

现在,为什么您的普通 python 有效?因为您在测试中方便地省略了换行符。您的测试字符串应该是:

s = '      only_from        = 127.0.0.1\n'

您更正的示例是:

>>> s = '      only_from        = 127.0.0.1\n'
>>> r = '\s*only_from\s+=\s*(((\d{1,3}\.){3}\d{1,3}\s*)*)'
>>> import re
>>> print re.match(r,s).group(1) + ' 192.168.1.1'
127.0.0.1
 192.168.1.1
>>> r = '\s*only_from\s+=\s*((\d{1,3}\.){3}\d{1,3})\s*'
>>> print re.match(r,s).group(1) + ' 192.168.1.1'
127.0.0.1 192.168.1.1
>>>