To whom it may concern, here are our shellhook examples as promised. These scripts were recently tidied up and tested successfully in our pre-production environment.
Prerequisites:
We trigger all of our shellhooks with Foreman webhooks that are subscribed to the Host Created/User Created event, using the Empty Payload template and @object.name/@object.login as X-Shellhook-Arg-1. As we rely on hammer to do the heavy lifting, the user foreman-proxy is allowed to execute hammer without a password via sudoers on the Foreman server. The scripts themselves sit in a git repository that is automatically synched to the shellhooks path.
Use case:
Again, please note that our Foreman instance is part of a larger setup in which we do not control all of the infrastructure. Therefore we use shellhooks to manipulate hosts after they have been created externally. Setting custom host parameters, and using them inside Foreman templates subsequently, has proven to be a reliable solution for us. This might be a niche case, but we hope that it serves as an inspiration to others. And thanks again to @ofedoren, @lzap and @Dirk for helping us migrate from hooks to shellhooks.
$ cat /var/lib/foreman-proxy/shellhooks/host_join_path.sh
#!/usr/bin/env bash
# Transform the host's LDAP path as received from Orchestrator into the OU path required by 'net ads' for joining.
# Save the result as a host parameter for use inside the deployment template's post install section.
vro_ldap_path="$(sudo -n hammer --output 'base' host info --name "${1}" --fields 'Parameters' | awk '$1~/vro_ldap_path/ {print $3}')"
tfm_join_path="$(echo "${vro_ldap_path}" | sed -r 's:CN=[^,]+,:: ; s:,DC=.*$:: ; s:OU=::g' | awk -F ',' '{ for (i=NF;i>0;i--) if (i!=1) printf $i"/"; else print $i; }')"
sudo -n hammer host set-parameter --host "${1}" --parameter-type 'string' --name 'tfm_join_path' --value "${tfm_join_path}"
exit 0
$ cat /var/lib/foreman-proxy/shellhooks/host_machine_type.sh
#!/usr/bin/env bash
# Check whether the host's MAC address is within the vendor range for VMware.
# Save the result as a host parameter for virtual/physical conditionals inside deployment templates.
host_mac="$(sudo -n hammer --output 'csv' host info --name "${1}" --fields 'Network/MAC' | tail -n 1)"
if [[ "${host_mac}" =~ 00:50:56(:[0-9a-fA-F]{2}){3} ]] ; then
tfm_virtual="true"
else
tfm_virtual="false"
fi
sudo -n hammer host set-parameter --host "${1}" --parameter-type 'boolean' --name 'tfm_virtual' --value "${tfm_virtual}"
exit 0
$ cat /var/lib/foreman-proxy/shellhooks/host_puppet_environment.sh
#!/usr/bin/env bash
# Define the host's Puppet environment based on the hostname's 3rd letter, or fall back to 'empty' environment.
envletter="$(sudo -n hammer --output 'csv' host info --name "${1}" --fields 'Name' | tail -n 1 | cut -b 3)"
case "${envletter}" in
t) host_env='testing' ;;
s) host_env='staging' ;;
p) host_env='production' ;;
*) host_env='empty' ;;
esac
sudo -n hammer host update --name "${1}" --environment "${host_env}"
exit 0
$ cat /var/lib/foreman-proxy/shellhooks/host_subnet.sh
#!/usr/bin/env bash
# Define the host's subnet based on the first two octets of its IP address, as assigned by Orchestrator.
host_ipaddr="$(sudo -n hammer --output 'csv' host info --name "${1}" --fields 'Network interfaces/IPv4 address' | tail -n 1 | cut -d '.' -f 1-2)"
host_subnet="$(sudo -n hammer --output 'csv' subnet list --fields 'Id,Network Addr' | grep "${host_ipaddr}" | cut -d ',' -f 1)"
sudo -n hammer host update --name "${1}" --subnet-id "${host_subnet}"
exit 0
$ cat /var/lib/foreman-proxy/shellhooks/user_default_settings.sh
#!/usr/bin/env bash
# Set common defaults for new users.
sudo -n hammer user update --login "${1}" --organization 'SNMP' --default-organization 'SNMP' --locations 'Springfield,Shelbyville' --locale 'en' --timezone 'Berlin'
exit 0