theforeman / foreman-ansible-modules

Ansible modules for interacting with the Foreman API and various plugin APIs such as Katello
GNU General Public License v3.0
149 stars 166 forks source link

job_invocation module seems not to be properly idempotent #1723

Open mhjacks opened 7 months ago

mhjacks commented 7 months ago
SUMMARY

The job invocation module, when used to schedule recurring jobs, should be idempotent based on recurrence.purpose. At present (in FAM 4.0.0 against upstream foreman 1.10/Katello 4.12) it fails.

ISSUE TYPE
ANSIBLE VERSION
ansible [core 2.16.5]
  config file = /etc/ansible/ansible.cfg
  configured module search path = ['/home/mjackson/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/lib/python3.12/site-packages/ansible
  ansible collection location = /home/mjackson/.ansible/collections:/usr/share/ansible/collections
  executable location = /usr/bin/ansible
  python version = 3.12.2 (main, Feb 21 2024, 00:00:00) [GCC 14.0.1 20240217 (Red Hat 14.0.1-0)] (/usr/bin/python3)
  jinja version = 3.1.3
  libyaml = True
COLLECTION VERSION
theforeman.foreman                       4.0.0
KATELLO/FOREMAN VERSION
package tfm-rubygem-katello is not installed
foreman-3.10.0-1.el8.noarch
STEPS TO REPRODUCE
---
- name: Katello job test
  hosts: localhost
  connection: local
  become: false
  gather_facts: false
  vars:
    organization: 'Default Organization'
    katello_username: admin
    katello_password: changeme
    server_url: https://foreman.example.com
    validate_certs: false
  tasks:
    - name: "Set up programmatic job invocations (failures ok)"
      theforeman.foreman.job_invocation:
        username: '{{ katello_username }}'
        password: '{{ katello_password }}'
        server_url: '{{ server_url }}'
        validate_certs: '{{ katello_validate_certs }}'
        command: 'dnf upgrade -y'
        job_template: 'Run Command - Ansible Default'
        recurrence:
          cron_line: '05 12 * * *'
          purpose: 'System update'
        search_query: 'name ~ .'
        targeting_type: dynamic_query
EXPECTED RESULTS

When running this playbook twice, the second run should return OK and not change anything. If the parameters of the job have changed, it should change them and report changed.

ACTUAL RESULTS

The first fun of the playbook creates the job as expected. That part is fine.

Subsequent runs error out, with messages like this:

TASK [Set up programmatic job invocations (failures ok)] *******************************************
fatal: [localhost]: FAILED! => {"changed": false, "error": {"message": "Validation failed: Triggering: Purpose Active or disabled recurring logic with purpose System update already exists"}, "msg": "Error while performing create on job_invocations: 500 Server Error: Internal Server Error for url: https://srv-katello.imladris.lan/api/job_invocations"}
afeefghannam89 commented 7 months ago

We have the same issue while using Red Hat Satellite 6.13 ansible [core 2.15.9] python version = 3.11.5

afeefghannam89 commented 7 months ago

This behavior is related to the API not to this module. When hammer CLI is used, you will get the same output or error. The developer of this module could maybe, as a solution, handle the API return code or its results in a better way without braking the playbook or Ansible run.

mhjacks commented 7 months ago

At present, it seems the job_invocations module does not support removal of jobs (e.g. via state: absent, Maybe that should be a separate issue, but in some ways I think it's related...foreman does treat recurring logics as a somewhat separate entity