validation command privilege issue

Hi all, I’ve a very simple role to copy and validate a monit configuration file

cat roles/monit_install/tasks/main.yml

  • name: copy configuration file
    template:
    mode: 0600
    dest: /etc/monitrc
    src: monitrc.j2

validate: /usr/bin/sudo /usr/bin/monit -c %s -t

now if I validate the configuration on the target server works like a charm:

[root@server2 ~]# monit -c /etc/monitrc -t
Control file syntax OK

and so if I launch the playbook with the user root (after having removed the configuration file on the target server)

$ ansible-playbook monit_install.yml -u root -k
SSH password:

PLAY [server2] ****************************************************************************************************************************************************************************************************************************************************************

TASK [Gathering Facts] ********************************************************************************************************************************************************************************************************************************************************
ok: [server2]

TASK [monit_install : copy configuration file] ********************************************************************************************************************************************************************************************************************************
changed: [server2]

TASK [monit_install : debug variable] *****************************************************************************************************************************************************************************************************************************************
ok: [server2] => {

}

PLAY RECAP ********************************************************************************************************************************************************************************************************************************************************************
server2 : ok=3 changed=1 unreachable=0 failed=0

but it fails when I try to launch it with sudo/become as follows:
(after having removed the file monitrc on server2)

$ ansible-playbook monit_install.yml --become --ask-become-pass
SUDO password:

PLAY [server2] ****************************************************************************************************************************************************************************************************************************************************************

TASK [Gathering Facts] ********************************************************************************************************************************************************************************************************************************************************
ok: [server2]

TASK [monit_install : copy configuration file] ********************************************************************************************************************************************************************************************************************************
fatal: [server2]: FAILED! => {“changed”: false, “checksum”: “435dbc73eaa2ccd4efd4c442e75e59e080088c02”, “exit_status”: 1, “msg”: “failed to validate”, “stderr”: “The control file ‘/home/fusillator/.ansible/tmp/ansible-tmp-1551782364.37-11770304984221/source’ must be owned by you.\n”, “stderr_lines”: [“The control file ‘/home/fusillator/.ansible/tmp/ansible-tmp-1551782364.37-11770304984221/source’ must be owned by you.”], “stdout”: “”, “stdout_lines”: }
to retry, use: --limit @/home/fusillator/Code/ansible/monit_install.retry

PLAY RECAP ********************************************************************************************************************************************************************************************************************************************************************
server2 : ok=1 changed=0 unreachable=0 failed=1

I tried to add fusillator user in sudo configuration to allow the execution of /usr/bin/monit without password but it fails anyway.

fusillator ALL=(ALL) NOPASSWD: /usr/bin/monit

So I miss something… isn’t the validation program run as the become user?

Any idea to resolve the issue?

regards

Luca

I solved in a stupid way:

  • name: copy configuration file
    template:
    mode: 0600
    dest: /etc/monitrc
    src: monitrc.j2

validate: /usr/bin/sudo /usr/bin/monit -c %s -t

  • name: validate configuration file
    command: /usr/bin/monit -c /etc/monitrc -t

but I’d like to figure out what goes wrong with the validate attribute and the sudo authentication,
so if so could enlighten it it would be appreciated

Workaround improved:

$ cat roles/monit_install/tasks/main.yml

  • name: copy configuration file
    template:
    mode: 0600
    dest: /etc/monitrc
    src: monitrc.j2

validate: /usr/bin/sudo /usr/bin/monit -c %s -t

  • name: validate configuration file
    command: /usr/bin/monit -c /etc/monitrc -t
    register: validate_result
    ignore_errors: true

  • name: remove monit configuration file if validation fails
    file:
    path: /etc/monitrc
    state: absent
    when: validate_result.rc > 0

  • name: exit when monit validation fails
    fail:
    msg: monit validation failed
    when: validate_result.rc > 0

Hi all, I've a very simple role to copy and validate a monit configuration
file

cat roles/monit_install/tasks/main.yml
- name: copy configuration file
   template:
     mode: 0600
     dest: /etc/monitrc
     src: monitrc.j2
     validate: /usr/bin/sudo /usr/bin/monit -c %s -t

<snip />

but it fails when I try to launch it with sudo/become as follows:
(after having removed the file monitrc on server2)

$ ansible-playbook monit_install.yml --become --ask-become-pass
SUDO password:

Since you are running the whole playbook with become/sudo there is no need to have sudo in the validate.

Unfortunately this morning I was in a hurry, and I posted the latest test with the useless sudo

Anyway I tried again getting the same error:

$ cat roles/monit_install/tasks/main.yml

  • name: copy configuration file
    template:
    mode: 0600
    dest: /etc/monitrc
    src: monitrc.j2
    validate: /usr/bin/monit -c %s -t
    $ ansible-playbook monit_install.yml --become --ask-become-pass
    SUDO password:

PLAY [server2] ****************************************************************************************************************************************************************************************************************************************************************

TASK [Gathering Facts] ********************************************************************************************************************************************************************************************************************************************************
ok: [server2]

TASK [monit_install : copy configuration file] ********************************************************************************************************************************************************************************************************************************
fatal: [server2]: FAILED! => {“changed”: false, “checksum”: “435dbc73eaa2ccd4efd4c442e75e59e080088c02”, “exit_status”: 1, “msg”: “failed to validate”, “stderr”: “The control file ‘/home/fusillator/.ansible/tmp/ansible-tmp-1551826763.1-47158502331153/source’ must be owned by you.\n”, “stderr_lines”: [“The control file ‘/home/fusillator/.ansible/tmp/ansible-tmp-1551826763.1-47158502331153/source’ must be owned by you.”], “stdout”: “”, “stdout_lines”: }
to retry, use: --limit @/home/fusillator/Code/ansible/monit_install.retry

PLAY RECAP ********************************************************************************************************************************************************************************************************************************************************************
server2 : ok=1 changed=0 unreachable=0 failed=1

whereas the validation of the same file succeded using the user root:

$ ansible-playbook monit_install.yml -u root -k
SSH password:

PLAY [server2] ****************************************************************************************************************************************************************************************************************************************************************

TASK [Gathering Facts] ********************************************************************************************************************************************************************************************************************************************************
ok: [server2]

TASK [monit_install : copy configuration file] ********************************************************************************************************************************************************************************************************************************
changed: [server2]

PLAY RECAP ********************************************************************************************************************************************************************************************************************************************************************
server2 : ok=2 changed=1 unreachable=0 failed=0

Should I open a bug?
Do I miss something?

Thanks

Luca

I also made a new version of the workaround to restore the not validated files

- name: validates the monit configuration
  command: /usr/bin/monit -c /etc/monitrc -t
  register: validate_result
  ignore_errors: true

- name: restores the old version of the configuration files in the validation fails
  command: /usr/bin/mv {{ item.backup_file }} {{ item.dest }}
  with_items: "{{
template_result.results|selectattr('changed')|selectattr('backup_file',
'defined')|list }}"
  when: validate_result.rc > 0

- name: removes the new files for the restore of the old version because of the validation failure
  file:
    path: "{{ item.dest }}"
    state: absent
  with_items: "{{
template_result.results|selectattr('changed')|selectattr('backup_file',
'undefined')|list }}"
  when: validate_result.rc > 0

- name: removes backup files
  file:
    path: "{{ item.backup_file }}"
    state: absent
  with_items: "{{
template_result.results|selectattr('changed')|selectattr('backup_file',
'defined')|list }}"

- name: exits if the monit validation fails 
  fail:
    msg: monit validation failure
  when: validate_result.rc > 0

Sorry I miss the first two tasks…

I also made a new version of the workaround to restore the not validated files

  • name: copy configuration file
    template:
    mode: 0600

dest: “/etc/{{ item }}”
src: “{{ item }}.j2”

  with_items: "{{ monitrc.files }}"  

register: template_result

- name: monit validation 
  command: /usr/bin/monit -c /etc/monitrc -t
  register: validate_result
  ignore_errors: true

solved… I missed to specify the owner for the new file…

$ cat roles/monit_install/tasks/main.yml | grep -v ‘^$|^#’

  • name: copy configuration file
    template:
    owner: root
    group: root
    mode: 0600
    dest: /etc/monitrc
    src: monitrc.j2
    validate: /usr/bin/monit -c %s -t

$ ansible-playbook monit_install.yml -b --ask-become-pass
SUDO password:

PLAY [server2] ****************************************************************************************************************************************************************************************************************************************************************

TASK [Gathering Facts] ********************************************************************************************************************************************************************************************************************************************************
ok: [server2]

TASK [monit_install : copy configuration file] ********************************************************************************************************************************************************************************************************************************
changed: [server2]

PLAY RECAP ********************************************************************************************************************************************************************************************************************************************************************
server2 : ok=2 changed=1 unreachable=0 failed=0

what a gap :(((

Regards

Luca