Extending the easy way
with foreman_hooks
Dominic Cleal
dcleal@redhat.com
3rd February 2014
Agenda
●

Orchestration today

●

ActiveRecord callbacks

●

Where to hook

●

Data in hooks

●

Troubleshooting

●

Cool examples

foreman_hooks | 2 | Dominic Cleal
Orchestration today
●

What does orchestration mean?
–
–

●

●

or·ches·trate (verb)
to arrange or manipulate, especially by means of clever or
thorough planning or maneuvering: to orchestrate a
profitable trade agreement (source: dictionary.com)

Namely: DNS, DHCP, TFTP, Puppet CA,
compute resources
Implemented in hosts and network interfaces,
on creation, update and destroy

foreman_hooks | 3 | Dominic Cleal
ActiveRecord callbacks
●

●

ActiveRecord is a database persistence layer in Ruby on
Rails
While mapping objects to tables, it provides a lifecycle of
events:
–

validation (before, after)

–

before_save

–

before_create

–

after_create

–

after_save

–

after_commit

foreman_hooks | 4 | Dominic Cleal
Where should you hook?
●

Orchestration hooks have benefits: ordering,
rollbacks and UI visibility

●

ActiveRecord works on nearly any object

●

Hooks are written into
~foreman/config/hooks/<object>/<event>

●

●

Each is a directory of executable files, called with the
event name, then the string representation of the
object
~foreman/config/hooks/host/managed/create/50_register_syste
m.sh create foo.example.com

foreman_hooks | 5 | Dominic Cleal
Data in hooks
●

$1 is the event name, e.g. create or destroy

●

$2 is the object's label, e.g. foo.example.com

●

stdin is the JSON representation of the object
{

"host": {
"name": "puppet.example.com",
"id": 82,
"ip": "192.168.30.10",
"environment_id": 1,
"environment_name": "production",
"last_report": "2014-01-27T22:25:34Z",
"mac": "52:54:00:2c:93:07",
"sp_mac": null,
"sp_ip": null,
"sp_name": null,
"domain_id": 6,
"domain_name": "example.com",
.....
foreman_hooks | 6 | Dominic Cleal
Troubleshooting
●

Do enable Foreman's debug logging
–

config.log_level = :debug in
~foreman/config/environments/production.rb

Found hook to Host::Managed#update, filename 01_debug_log
Finished registering 4 hooks for Host::Managed#update
Observed update hook on test.example.com
Queueing 1 hooks for Host::Managed#update
Queuing hook 01_debug_log for Host::Managed#update at
priority 01
Running hook:
/home/dcleal/code/foreman/foreman/config/hooks/host/managed
/update/01_debug_log update test.example.com

foreman_hooks | 7 | Dominic Cleal
Hook examples (1/3)
●

Extending Foreman quickly with hook scripts
–

http://bit.ly/1f8zVUZ

# cat << EOF >
~foreman/config/hooks/host/destroy/70_deactivate_puppetdb
#!/bin/bash
# We can only deactivate data in PuppetDB, not add it
[ "x$1" = xdestroy ] || exit 0
# Remove data in PuppetDB, supplying the FQDN
#
# assumes sudo rules set up as this runs as 'foreman':
#
foreman ALL = NOPASSWD : /usr/bin/puppet node deactivate *
#
Defaults:foreman !requiretty
#
sudo puppet node deactivate $2
EOF
foreman_hooks | 8 | Dominic Cleal
Hook examples (2/3)
●

FreeIPA Integration Guide (Stephen Benjamin)
–

●

http://bit.ly/19YBQhv

Uses a “create” hook to run “ipa host-add”, then
an after-commit hook to add the OTP
parameter via the API

foreman_hooks | 9 | Dominic Cleal
foreman_hooks | 10 | Dominic Cleal
Hook examples (3/3)
●

AWS VPC rDNS creation (Brian Galura)
–

●

●

●

http://bit.ly/1e47F9J

Uses “create” and “destroy” hook to run nsupdate,
creating a PTR record in his local name server
From the stdin data, the IP address and host
name can be retrieved with $(hook_data
host.ip)
Works around bug #3166

foreman_hooks | 11 | Dominic Cleal
Questions?
●

https://github.com/theforeman/foreman_hooks

●

RPM users:
–

●

yum install foreman-plugin-hooks

Debian users:
–

aptitude install ruby-foreman-hooks

foreman_hooks | 12 | Dominic Cleal

Extending Foreman the easy way with foreman_hooks

  • 1.
    Extending the easyway with foreman_hooks Dominic Cleal dcleal@redhat.com 3rd February 2014
  • 2.
    Agenda ● Orchestration today ● ActiveRecord callbacks ● Whereto hook ● Data in hooks ● Troubleshooting ● Cool examples foreman_hooks | 2 | Dominic Cleal
  • 3.
    Orchestration today ● What doesorchestration mean? – – ● ● or·ches·trate (verb) to arrange or manipulate, especially by means of clever or thorough planning or maneuvering: to orchestrate a profitable trade agreement (source: dictionary.com) Namely: DNS, DHCP, TFTP, Puppet CA, compute resources Implemented in hosts and network interfaces, on creation, update and destroy foreman_hooks | 3 | Dominic Cleal
  • 4.
    ActiveRecord callbacks ● ● ActiveRecord isa database persistence layer in Ruby on Rails While mapping objects to tables, it provides a lifecycle of events: – validation (before, after) – before_save – before_create – after_create – after_save – after_commit foreman_hooks | 4 | Dominic Cleal
  • 5.
    Where should youhook? ● Orchestration hooks have benefits: ordering, rollbacks and UI visibility ● ActiveRecord works on nearly any object ● Hooks are written into ~foreman/config/hooks/<object>/<event> ● ● Each is a directory of executable files, called with the event name, then the string representation of the object ~foreman/config/hooks/host/managed/create/50_register_syste m.sh create foo.example.com foreman_hooks | 5 | Dominic Cleal
  • 6.
    Data in hooks ● $1is the event name, e.g. create or destroy ● $2 is the object's label, e.g. foo.example.com ● stdin is the JSON representation of the object { "host": { "name": "puppet.example.com", "id": 82, "ip": "192.168.30.10", "environment_id": 1, "environment_name": "production", "last_report": "2014-01-27T22:25:34Z", "mac": "52:54:00:2c:93:07", "sp_mac": null, "sp_ip": null, "sp_name": null, "domain_id": 6, "domain_name": "example.com", ..... foreman_hooks | 6 | Dominic Cleal
  • 7.
    Troubleshooting ● Do enable Foreman'sdebug logging – config.log_level = :debug in ~foreman/config/environments/production.rb Found hook to Host::Managed#update, filename 01_debug_log Finished registering 4 hooks for Host::Managed#update Observed update hook on test.example.com Queueing 1 hooks for Host::Managed#update Queuing hook 01_debug_log for Host::Managed#update at priority 01 Running hook: /home/dcleal/code/foreman/foreman/config/hooks/host/managed /update/01_debug_log update test.example.com foreman_hooks | 7 | Dominic Cleal
  • 8.
    Hook examples (1/3) ● ExtendingForeman quickly with hook scripts – http://bit.ly/1f8zVUZ # cat << EOF > ~foreman/config/hooks/host/destroy/70_deactivate_puppetdb #!/bin/bash # We can only deactivate data in PuppetDB, not add it [ "x$1" = xdestroy ] || exit 0 # Remove data in PuppetDB, supplying the FQDN # # assumes sudo rules set up as this runs as 'foreman': # foreman ALL = NOPASSWD : /usr/bin/puppet node deactivate * # Defaults:foreman !requiretty # sudo puppet node deactivate $2 EOF foreman_hooks | 8 | Dominic Cleal
  • 9.
    Hook examples (2/3) ● FreeIPAIntegration Guide (Stephen Benjamin) – ● http://bit.ly/19YBQhv Uses a “create” hook to run “ipa host-add”, then an after-commit hook to add the OTP parameter via the API foreman_hooks | 9 | Dominic Cleal
  • 10.
    foreman_hooks | 10| Dominic Cleal
  • 11.
    Hook examples (3/3) ● AWSVPC rDNS creation (Brian Galura) – ● ● ● http://bit.ly/1e47F9J Uses “create” and “destroy” hook to run nsupdate, creating a PTR record in his local name server From the stdin data, the IP address and host name can be retrieved with $(hook_data host.ip) Works around bug #3166 foreman_hooks | 11 | Dominic Cleal
  • 12.
    Questions? ● https://github.com/theforeman/foreman_hooks ● RPM users: – ● yum installforeman-plugin-hooks Debian users: – aptitude install ruby-foreman-hooks foreman_hooks | 12 | Dominic Cleal