Chapter 15. Using Webhooks

A webhook is a way for a web page or web application to provide other applications with information in real time. Webhooks are only triggered after an event occurs. The request usually contains details of the event. An event triggers callbacks, such as sending an e-mail confirming a host has been provisioned. Webhooks enable you to define a call to an external API based on Satellite internal event using a fire-and-forget message exchange pattern. The application sending the request does not wait for the response, or ignores it.

Payload of a webhook is created from webhook templates. Webhook templates use the same ERB syntax as Provisioning templates. Available variables:

  • @event_name: Name of an event.
  • @webhook_id: Unique event ID.
  • @payload: Payload data, different for each event type. To access individual fields, use @payload[:key_name] Ruby hash syntax.
  • @payload[:object]: Database object for events triggered by database actions (create, update, delete). Not available for custom events.
  • @payload[:context]: Additional information as hash like request and session UUID, remote IP address, user, organization and location.

Because webhooks use HTTP, no new infrastructure needs be added to existing web services.

The typical use case for webhooks in Satellite is making a call to a monitoring system when a host is created or deleted.

Webhooks are useful where the action you want to perform in the external system can be achieved through its API. Where it is necessary to run additional commands or edit files, the shellhooks plugin for Capsules is available. The shellhooks plugin enables you to define a shell script on the Capsule that can be executed through the API.

You can use webhooks successfully without installing the shellhooks plugin.

For a list of available events, see Available webhook events.

15.1. Migrating to Webhooks

The legacy foreman_hooks plugin provided full access to model objects that the webhooks plugin does not intentionally provide.

The scope of what is available is limited by the safemode and all objects and macros are both subject to an API stability promise and are fully documented.

The number of events triggered by webhooks is substantially fewer than with foreman_hooks.

Webhooks are processed asynchronously so there is minimal risk of tampering with internals of the system. It is not possible to migrate from foreman_hooks without creating payloads for each individual webhook script. However, the webhooks plugin comes with several example payload templates. You can also use the example payloads with shellhooks to simplify migration.

Both script and payload templates must be customized to achieve similar results.

15.2. Installing Webhooks

Use the following procedure to install webhooks. After installing webhooks, you can configure Satellite Server to send webhook requests.

Procedure

  • Install webhooks using the following command:

    # satellite-installer --enable-foreman-plugin-webhooks
  • Optionally, you can install the CLI plugin using the following command:

    # yum install tfm-rubygem-hammer_cli_foreman_webhooks

15.3. Creating a Webhook Template

Use the following procedure to create a webhook template in the Satellite web UI.

Procedure

  1. In the Satellite web UI, navigate to Administer > Webhooks Templates.
  2. Click Clone an existing template or Create Template.
  3. Enter a name for the template.
  4. Use the editor to make changes to the template payload.

    A webhook HTTP payload must be created using Satellite template syntax. The webhook template can use a special variable called @object that can represent the main object of the event.

    For more information, see Template Writing Reference in Managing Hosts and for available template macros and methods, visit /templates_doc on Satellite Server.

  5. Optional: Enter the description and audit comment.
  6. Assign organizations and locations.
  7. Click Submit.

15.4. Creating a Webhook

You can customize events, payloads, HTTP authentication, content type, and headers through the Satellite web UI.

Use the following procedure to create a webhook in the Satellite web UI.

Procedure

  1. In the Satellite web UI, click Administer > Webhooks.
  2. Click Create Webhook.
  3. Click Subscribe to to select an event.
  4. Enter a name.
  5. Enter a target URL. Webhooks make HTTP requests to pre-configured URLs. The target URL can be a dynamic URL. When using the shellhooks plugin, the URL should be in the form https://capsule.example.com:9090/shellhook/my_script.
  6. Click Template to select a template.
  7. Enter an HTTP method.
  8. Check the Enabled flag if you want to create an active webhook.
  9. Click the Credentials tab.
  10. Optional: If HTTP authentication is required, enter the username and password.
  11. Select Verify SSL if the server certificate should be verified against the system certificate store or Satellite CA.
  12. Select Proxy Authorization when using shellhooks, otherwise clear this box.
  13. On the Additional tab, enter the HTTP Content Type. For example, application/json, application/xml or text/plain on the payload you define. The application does not attempt to convert the content to match the specified content type.
  14. Optional: Provide HTTP headers as JSON. ERB is also allowed.

When configuring webhooks with endpoints with non-standard HTTP or HTTPS ports, an SELinux port must be assigned, see Configuring SELinux to Ensure Access to Satellite on Custom Ports in Installing Satellite Server from a Connected Network.

15.5. Available Webhook Events

The following table contains a list of webhook events that are available from the Satellite web UI. Action events trigger webhooks only on success, so if an action fails, a webhook is not triggered.

For more information about payload, go to Administer > About > Support > Templates DSL. A list of available types is provided in the following table. Some events are marked as custom, in that case, the payload is an object object but a Ruby hash (key-value data structure) so syntax is different.

Event nameDescriptionPayload

Actions Katello Content View Promote Succeeded

A content view was successfully promoted.

Actions::Katello::ContentView::Promote

Actions Katello Content View Publish Succeeded

A repository was successfully synchronized.

Actions::Katello::ContentView::Publish

Actions Remote Execution Run Host Job Succeeded

A generic remote execution job succeeded for a host. This event is emitted for all Remote Execution jobs, when complete.

Actions::RemoteExecution::RunHostJob

Actions Remote Execution Run Host Job Katello Errata Install Succeeded

Install errata using the Katello interface.

Actions::RemoteExecution::RunHostJob

Actions Remote Execution Run Host Job Katello Group Install Succeeded

Install package group using the Katello interface.

Actions::RemoteExecution::RunHostJob

Actions Remote Execution Run Host Job Katello Package Install Succeeded

Install package using the Katello interface.

Actions::RemoteExecution::RunHostJob

Actions Remote Execution Run Host Job Katello Group Remove

Remove package group using the Katello interface.

Actions::RemoteExecution::RunHostJob

Actions Remote Execution Run Host Job Katello Package Remove Succeeded

Remove package using the Katello interface.

Actions::RemoteExecution::RunHostJob

Actions Remote Execution Run Host Job Katello Service Restart Succeeded

Restart Services using the Katello interface.

Actions::RemoteExecution::RunHostJob

Actions Remote Execution Run Host Job Katello Group Update Succeeded

Update package group using the Katello interface.

Actions::RemoteExecution::RunHostJob

Actions Remote Execution Run Host Job Katello Package Update Succeeded

Update package using the Katello interface.

Actions::RemoteExecution::RunHostJob

Actions Remote Execution Run Host Job Foreman OpenSCAP Run Scans Succeeded

Run OpenSCAP scan.

Actions::RemoteExecution::RunHostJob

Actions Remote Execution Run Host Job Ansible Run Host Succeeded

Runs an Ansible playbook containing all the roles defined for a host.

Actions::RemoteExecution::RunHostJob

Actions Remote Execution Run Host Job Ansible Run Capsule Upgrade Succeeded

Upgrade Capsules on given Capsule server hosts.

Actions::RemoteExecution::RunHostJob

Actions Remote Execution Run Host Job Ansible Configure Cloud Connector Succeeded

Configure Cloud Connector on given hosts.

Actions::RemoteExecution::RunHostJob

Actions Remote Execution Run Host Job Ansible Run Insights Plan Succeeded

Runs a given maintenance plan from Red Hat Access Insights given an ID.

Actions::RemoteExecution::RunHostJob

Actions Remote Execution Run Host Job Ansible Run Playbook Succeeded

Run an Ansible playbook against given hosts.

Actions::RemoteExecution::RunHostJob

Actions Remote Execution Run Host Job Ansible Enable Web Console Succeeded

Run an Ansible playbook to enable the web console on given hosts.

Actions::RemoteExecution::RunHostJob

Actions Remote Execution Run Host Job Puppet Run Host Succeeded

Perform a single Puppet run.

Actions::RemoteExecution::RunHostJob

Actions Remote Execution Run Host Job Katello Module Stream Action Succeeded

Perform a module stream action using the Katello interface.

Actions::RemoteExecution::RunHostJob

Actions Remote Execution Run Host Job Leapp Pre-upgrade Succeeded

Upgradeability check for RHEL 7 host.

Actions::RemoteExecution::RunHostJob

Actions Remote Execution Run Host Job Leapp Remediation Plan Succeeded

Run Remediation plan with Leapp.

Actions::RemoteExecution::RunHostJob

Actions Remote Execution Run Host Job Leapp Upgrade Succeeded

Run Leapp upgrade job for RHEL 7 host.

Actions::RemoteExecution::RunHostJob

Build Entered

A host entered the build mode.

Custom event: @payload[:id] (host id), @payload[:hostname] (host name).

Build Exited

A host build mode was canceled, either it was successfully provisioned or the user canceled the build manually.

Custom event: @payload[:id] (host id), @payload[:hostname] (host name).

Content View Created/Updated/Destroyed

Common database operations on a content view.

Katello::ContentView

Domain Created/Updated/Destroyed

Common database operations on a domain.

Domain

Host Created/Updated/Destroyed

Common database operations on a host.

Host

Hostgroup Created/Updated/Destroyed

Common database operations on a hostgroup.

Hostgroup

Model Created/Updated/Destroyed

Common database operations on a model.

Model

Status Changed

Global host status of a host changed.

Custom event: @payload[:id] (host id), @payload[:hostname], @payload[:global_status] (hash)

Subnet Created/Updated/Destroyed

Common database operations on a subnet.

Subnet

Template Render Performed

A report template was rendered.

Template

User Created/Updated/Destroyed

Common database operations on a user.

User

15.6. Shellhooks

With webhooks, one Satellite event can only be mapped to one API call. For advanced integrations, where a single shell script can contain multiple commands, you can install a Capsule shellhooks plugin that exposes executables using a REST HTTP API.

A webhook can then be configured to reach out to a Capsule API to run a predefined shellhook, which, for example, can contain commands or edit files.

Scripts must be placed in /var/lib/foreman-proxy/shellhooks as executables with only alphanumeric characters and underscores in the name.

The HTTPS payload is passed using standard input, optional command line arguments can be provided using X-Shellhook-Arg-1 to N.

The HTTP method must be POST. An example URL would be: https://capsule.example.com:9090/shellhook/my_script.

You must enable Proxy Authorization for each webhook that is connected to a shellhook, to enable it to authorize a call.

Standard output and error are redirected to the Capsule log as messages with debug or warning levels respectively.

There is no return value from shellhook HTTPS calls.

15.7. Installing the Shellhooks Plugin

Optionally, you can install and enable the shellhooks plugin on each Capsule used for shellhooks, using the following command:

# satellite-installer --enable-foreman-proxy-plugin-shellhooks

15.8. Using Shellhook Arguments

Procedure

To pass arguments into a shellhook script, create the following HTTP headers:

{
  "X-Shellhook-Arg-1": "<%= @object.content_view_version_id %>,
  "X-Shellhook-Arg-2": "<%= @object.content_view_name %>
}

Ensure the content renders to a valid JSON. Also, only pass safe fields like database ID, name, or labels which do not include new lines or quote characters.