Chapter 16. 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 . 16.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. 16.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: Optional: you can install the CLI plugin using the following command: 16.3. Creating a Webhook Template Webhook templates are used to generate the body of HTTP request to a configured target when a webhook is triggered. Use the following procedure to create a webhook template in the Satellite web UI. Procedure In the Satellite web UI, navigate to Administer > Webhook Templates . Click Clone an existing template or Create Template . Enter a name for the template. 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. @object can be missing in case of certain events. You can determine what data are actually available with the @payload variable. For more information, see Template Writing Reference in Managing Hosts and for available template macros and methods, visit /templates_doc on Satellite Server. Optional: Enter the description and audit comment. Assign organizations and locations. Click Submit . 16.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 In the Satellite web UI, navigate to Administer > Webhooks . Click Create new . From the Subscribe to list, select an event. Enter a Name for your webhook. Enter a Target URL . Webhooks make HTTP requests to pre-configured URLs. The target URL can be a dynamic URL. Click Template to select a template. Webhook templates are used to generate the body of the HTTP request to Satellite Server when a webhook is triggered. Enter an HTTP method. Optional: If you do not want activate the webhook when you create it, uncheck the Enabled flag. Click the Credentials tab. Optional: If HTTP authentication is required, enter User and Password . Optional: Uncheck Verify SSL if you do not want to verify the server certificate against the system certificate store or Satellite CA. 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. 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 in a Connected Network Environment . 16.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 name Description Payload 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 16.6. Shellhooks With webhooks, you can only map one Satellite event 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. You can then configure a webhook to reach out to a Capsule API to run a predefined shellhook. A shellhook is an executable script that can be written in any language as long as it can be executed. The shellhook can for example contain commands or edit files. You must place your executable scripts in /var/lib/foreman-proxy/shellhooks with only alphanumeric characters and underscores in their name. You can pass input to shellhook script through the webhook payload. This input is redirected to standard input of the shellhook script. You can pass arguments to shellhook script using HTTP headers in format X-Shellhook-Arg-1 to X-Shellhook-Arg-99 . For more information on passing arguments to shellhook script, see: Section 16.8, "Passing Arguments to Shellhook Script Using Webhooks" Section 16.9, "Passing Arguments to Shellhook Script Using Curl" The HTTP method must be POST. An example URL would be: https://capsule.example.com:9090/shellhook/My_Script . Note Unlike the shellhooks directory, the URL must contain /shellhook/ in singular to be valid. You must enable Capsule Authorization for each webhook connected to a shellhook to enable it to authorize a call. Standard output and standard error output are redirected to the Capsule logs as messages with debug or warning levels respectively. The shellhook HTTPS calls do not return a value. For an example on creating a shellhook script, see Section 16.10, "Creating a Shellhook to Print Arguments" . 16.7. Installing the Shellhooks Plugin Optionally, you can install and enable the shellhooks plugin on each Capsule used for shellhooks, using the following command: 16.8. Passing Arguments to Shellhook Script Using Webhooks Use this procedure to pass arguments to a shellhook script using webhooks. Procedure When creating a webhook, on the Additional tab, create HTTP headers in the following format: Ensure that the headers have a valid JSON or ERB format. Only pass safe fields like database ID, name, or labels that do not include new lines or quote characters. For more information, see Section 16.4, "Creating a Webhook" . Example 16.9. Passing Arguments to Shellhook Script Using Curl Use this procedure to pass arguments to a shellhook script using curl. Procedure When executing a shellhook script using curl , create HTTP headers in the following format: Example 16.10. Creating a Shellhook to Print Arguments Create a simple shellhook script that prints "Hello World!" when you run a remote execution job. Prerequisite You have the webhooks and shellhooks plug-ins installed. For more information, see: Section 16.2, "Installing Webhooks" Section 16.7, "Installing the Shellhooks Plugin" Procedure Modify the /var/lib/foreman-proxy/shellhooks/print_args script to print arguments to standard error output so you can see them in the Capsule logs: In the Satellite web UI, navigate to Administer > Webhooks . Click Create new . From the Subscribe to list, select Actions Remote Execution Run Host Job Succeeded . Enter a Name for your webhook. In the Target URL field, enter the URL of your Capsule Server followed by :9090/shellhook/print_args : Note that shellhook in the URL is singular, unlike the shellhooks directory. From the Template list, select Empty Payload . On the Credentials tab, check Capsule Authorization . On the Additional tab, enter the following text in the Optional HTTP headers field: Click Submit . You now have successfully created a shellhook that prints "Hello World!" to Capsule logs every time you a remote execution job succeeds. Verification Run a remote execution job on any host. You can use time as a command. For more information, see Executing a Remote Job in Managing Hosts . Verify that the shellhook script was triggered and printed "Hello World!" to Capsule Server logs: You should find the following lines at the end of the log:

Commands:
satellite-installer --enable-foreman-plugin-webhooks
satellite-installer --enable-foreman-cli-webhooks
satellite-installer --enable-foreman-proxy-plugin-shellhooks
X-Shellhook-Arg-1:  VALUE 
X-Shellhook-Arg-2:  VALUE 
X-Shellhook-Arg-1: <%= @object.content_view_version_id %>
X-Shellhook-Arg-2: <%= @object.content_view_name %>
"X-Shellhook-Arg-1: VALUE " "X-Shellhook-Arg-2: VALUE "
curl -sX POST -H 'Content-Type: text/plain' -H "X-Shellhook-Arg-1: Version 1.0" -H "X-Shellhook-Arg-2: My Content View" --data "" https://capsule.example.com:9090/shellhook/My_Script
#!/bin/sh # Prints all arguments to stderr # echo "USD@" >&2
https:// capsule.example.com :9090/shellhook/print_args
X-Shellhook-Arg-1: Hello
X-Shellhook-Arg-2: World!
tail /var/log/foreman-proxy/proxy.log
[I] Started POST /shellhook/print_args [I] Finished POST /shellhook/print_args with 200 (0.33 ms) [I] [3520] Started task /var/lib/foreman-proxy/shellhooks/print_args\ Hello\ World\! [W] [3520] Hello World!