Accessing Host Facts in Webhook Templates

Hi everyone,

I’m wondering if it’s possible to access host facts from a webhook template on host_update or build_entered events?

Using the default payload, I was able to query @object , but I’m unsure how to access detailed facts for the host in these events.

Problem:
How can I include or query host facts in the webhook template for these specific events?

Expected outcome:
Ability to access and include host facts in the webhook payload when host_update or build_entered events are triggered.

Foreman and Proxy versions:

foreman 3.13.0-1+ubuntu2204
foreman-cli 3.13.0-1+ubuntu2204
foreman-debug 3.13.0-1+ubuntu2204
foreman-dynflow-sidekiq 3.13.0-1+ubuntu2204
foreman-postgresql 3.13.0-1+ubuntu2204
foreman-proxy 3.13.0-1+ubuntu2204
foreman-redis 3.13.0-1+ubuntu2204
foreman-service 3.13.0-1+ubuntu2204
foreman-telemetry 3.13.0-1+ubuntu2204
ruby-foreman-discovery 25.0.0-1
ruby-foreman-webhooks 4.0.0-1
ruby-hammer-cli-foreman 3.13.0-1

Other relevant data:

Hi @skyfox14,

sorry for late reply, but something like this can be used for your case:

<% host_info = {} -%>
<% if @event_name == "build_entered.event.foreman" -%>
<% load_hosts(search: "id = #{@payload[:id]}").each_record do |host|
  host_info.update(hostname: host.name)
  host_info.update(facts: host.facts)
end -%>
<% else -%>
<% host_info = { hostname: @object.name, facts: @object.facts } -%>
<% end -%>
<%= payload(host_info, with_defaults: false) -%>

This webhook template can be assigned to both webhooks/events, the result will depend on the actual event.

The first part of if clause is evaluated on build_entered event. Since this event has a custom payload, the host must be found first via load_hosts macro, then you can grab its facts.

The second part of if clause is for host_updated event, which has more “general” payload (i.e. @object variable), so you can grab facts right away.

The template will generate a JSON-like response, something like:

{
    "hostname": "lucy.ofedoren.com",
    "facts": {
        "ansible_all_ipv4_addresses": "[\"192.168.73.89\"]",
        "ansible_all_ipv6_addresses": "[\"fe80::5054:ff:fe0b:8dab\"]",
        "ansible_apparmor": null,
        "ansible_apparmor::status": "disabled",
        "ansible_architecture": "x86_64",
        ...
}

Tell me if this helps. Even though the template should just work, it’s just an example, feel free to modify as needed.