Refactor #37667
closedProvide meaingful error message after webhook template fails to render due to organization/location mismatch
Description
Concrete example:
After creating a webhook and subscribing it to actions.remote_execution.run_host_job_succeeded event, Even though remote execution jobs are running fine on the hosts, The webhook execution fails with the error:
~~
Failed to run hook 'emit_event' for action 'Actions::RemoteExecution::RunHostJob'
~~
This happens when the Location assigned with the Webhook Template and the Location of the REX Job, do not match each other.
How reproducible:
Always
Steps to Reproduce:
1. Have an instance of Foreman with Organization Name "Foreman" and Location "Global"
2. Create a basic ansible role and import it to the Foreman server.
3. Register a system with Foreman and ensure that it's associated with "Foreman" org and "Global" location. Assign the ansible role with the host ( imported in step 3).
4. Now be on "Foreman" Organization and "Any Location" context in Foreman UI and
--> Create a webhook template with the following content, by the name "Show All" and only assign the Foreman organization to it. Don't assign any location.
<%= payload({
object: @object
}) %>
--> Create a webhook called "Test Hook" using that "Show All" template, and subscribe it to the "Actions Remote Execution Run Host Job Succeeded" event.
5. While in the "Any Location" context, Go to Hosts --> All Hosts --> Click open the client host --> hit on "Run Ansible Roles" from the dropdown and monitor /var/log/foreman/production.log file
6. Switch to the "Global" location now and repeat Step 5 and monitor /var/log/foreman/production.log file as well.
Actual results:
Step 5:
--> Job and Hook both will be executed successfully.
--> If we open the job from Monitor --> Jobs page, we will see that the Location of the JOB is set to "Any Location".
Step 6:
--> Job runs successfully.
--> Hook fails to run with the following error:
~~
2022-12-16T14:40:41 [E|dyn|3b8c19bb] Failed to run hook 'emit_event' for action 'Actions::RemoteExecution::RunHostJob'
2022-12-16T14:40:41 [E|dyn|3b8c19bb] undefined method `render' for nil:NilClass (NoMethodError)
3b8c19bb | /usr/share/gems/gems/foreman_webhooks-2.0.3/app/models/webhook.rb:118:in `rendered_payload'
3b8c19bb | /usr/share/gems/gems/foreman_webhooks-2.0.3/app/models/webhook.rb:68:in `deliver'
3b8c19bb | /usr/share/gems/gems/foreman_webhooks-2.0.3/app/models/webhook.rb:46:in `block in deliver'
3b8c19bb | /usr/share/gems/gems/activerecord-6.0.4.7/lib/active_record/relation/delegation.rb:88:in `each'
3b8c19bb | /usr/share/gems/gems/foreman_webhooks-2.0.3/app/models/webhook.rb:45:in `deliver'
3b8c19bb | /usr/share/gems/gems/foreman_webhooks-2.0.3/app/subscribers/foreman_webhooks/event_subscriber.rb:6:in `call'
3b8c19bb | /usr/share/foreman/app/subscribers/foreman/base_subscriber.rb:6:in `call'
3b8c19bb | /usr/share/gems/gems/activesupport-6.0.4.7/lib/active_support/notifications/fanout.rb:189:in `finish'
3b8c19bb | /usr/share/gems/gems/activesupport-6.0.4.7/lib/active_support/notifications/fanout.rb:62:in `block in finish'
3b8c19bb | /usr/share/gems/gems/activesupport-6.0.4.7/lib/active_support/notifications/fanout.rb:62:in `each'
3b8c19bb | /usr/share/gems/gems/activesupport-6.0.4.7/lib/active_support/notifications/fanout.rb:62:in `finish'
3b8c19bb | /usr/share/gems/gems/activesupport-6.0.4.7/lib/active_support/notifications/instrumenter.rb:45:in `finish_with_state'
3b8c19bb | /usr/share/gems/gems/activesupport-6.0.4.7/lib/active_support/notifications/instrumenter.rb:30:in `instrument'
3b8c19bb | /usr/share/gems/gems/activesupport-6.0.4.7/lib/active_support/notifications.rb:180:in `instrument'
3b8c19bb | /usr/share/foreman/lib/foreman/observable.rb:10:in `trigger_hook'
3b8c19bb | /usr/share/gems/gems/foreman-tasks-5.2.3/app/lib/actions/observable_action.rb:60:in `emit_event'
~~
--> If we open the related job from Monitor --> Jobs page, we will see that the Location of the JOB is set to "Global".
So the hook fails to run at step 6 since the location context for the job is "Global" but the "Show All" webhook template has no locations assigned ( or wrong location assigned ).
It works on Step 5, as the "Any Location" context of the job, can work with a Webhook template that has no locations assigned ( as expected ).
Expected results:
Rather than showing this misleading error:
~~
2022-12-16T14:40:41 [E|dyn|3b8c19bb] Failed to run hook 'emit_event' for action 'Actions::RemoteExecution::RunHostJob'
2022-12-16T14:40:41 [E|dyn|3b8c19bb] undefined method `render' for nil:NilClass (NoMethodError)
~~
Some meaningful message needs to be printed so that users can quickly fix the issue with location or Organization association on their own.
Additional info:
In a Multi-Location environment, There is a possibility of users working in the "Any Location" context and forgetting to assign the right location to Webhook templates. But when they will execute\schedule remote jobs using any playbook\api\hammer they might have specified an Org and Location for the job. So scenarios like that could lead to issues like what is described in this BZ.
Updated by Adam Lazik about 1 month ago
- Pull request https://github.com/theforeman/foreman_webhooks/pull/78 added
Updated by Adam Ruzicka 25 days ago
- Fixed in Releases foreman_webhooks-3.2.3 added