1

I currently have this file for configuring 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 
}

(Note that the only_from is a fake IP, but I'm attempting to write the ansible command to work regardless of the IP provided)

I'm attempting to use ansible's lineinfile module to allow me to add another variable to the line starting with only_from

Currently I have the following:

---
- 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 = \1 {{ nagios_ip }}'
    regexp: '\s*only_from\s+=\s*(((\d{1,3}\.){3}\d{1,3}\s*)*)'

This works, mostly. I get the line changed, but the {{ nagios_ip }} variable is sent to a newline and the file ends up looking like so with the new IP address on a new line, as opposed to on the same line:

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

Because ansible/lineinfile uses python's regex engine I tested it in plain 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'
>>> 

And it works as expected. How do I get rid of the new line that ansible is putting in?

Mitch
  • 1,604
  • 4
  • 20
  • 36
  • The string is most likely `192.168.1.1\n`. See if there is any way to strip new lines and append it to the overall end of your string. You probably still want a newline at the end of all this but not in the middle. Something like `192.168.1.1 127.0.0.1\n` I'm assuming? – idjaw Jun 07 '16 at 14:54
  • @idjaw you're correct in that I do want the new line at the end. Do you have any thoughts on what is adding the `\n` to the backref (my regex, ansible, python)? – Mitch Jun 07 '16 at 14:56
  • Unfortunately, I have not played with this ansible module yet. I would have to experiment as much as you at this point. – idjaw Jun 07 '16 at 14:56

1 Answers1

3

The problem is you are matching the newline too. Don't include the newline in your match. This should work:

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

Now why did your plain python work? Because you conveniently omitted the newline in your test. Your test string should be:

s = '      only_from        = 127.0.0.1\n'

Your corrected example is:

>>> 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
>>>
helloV
  • 50,176
  • 7
  • 137
  • 145