foreman_hooks 0.3.9 → 0.3.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +43 -19
- data/lib/foreman_hooks.rb +11 -4
- data/lib/foreman_hooks/callback_hooks.rb +1 -0
- data/lib/foreman_hooks/engine.rb +1 -1
- data/lib/foreman_hooks/util.rb +10 -3
- data/lib/tasks/hooks.rake +19 -0
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a89ac7b975601cb22c02b50fe94047bb880e6989
|
4
|
+
data.tar.gz: 7c631de38f23086fedbc7936acef69b5f365d15a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6fb5a5d108bc7ada61a789127f7fab55aed8e8a5ee1b40b6a7c42f342f02bbd60db681fbcfe026a51252f7105a7be7a33b0106cb91ae8bd23047dc905a888ebf
|
7
|
+
data.tar.gz: efba9aa79b1355ad157613b249c7c84e35dfce71f2317b40edb9b9749deee2d1d9ecee7125d10ef3d94a6aa4fc5d34fab84e7ff9e4b235f4bd0a0c5bef14c0e7
|
data/README.md
CHANGED
@@ -24,7 +24,7 @@ RPM users can install the "ruby193-rubygem-foreman_hooks" or
|
|
24
24
|
Hooks are stored in `/usr/share/foreman/config/hooks` (`~foreman/config/hooks`)
|
25
25
|
with a subdirectory for the object, then a subdirectory for the event name.
|
26
26
|
|
27
|
-
~foreman/config/hooks
|
27
|
+
~foreman/config/hooks/[OBJECT]/[EVENT]/[HOOK_SCRIPT]
|
28
28
|
|
29
29
|
Examples:
|
30
30
|
|
@@ -33,19 +33,6 @@ Examples:
|
|
33
33
|
~foreman/config/hooks/smart_proxy/after_create/01_email_operations.sh
|
34
34
|
~foreman/config/hooks/audited/adapters/active_record/audit/after_create/01_syslog.sh
|
35
35
|
|
36
|
-
## SELinux notes
|
37
|
-
|
38
|
-
When using official installation on Red Hat and Fedora system, note that
|
39
|
-
SELinux is turned on by default and Foreman is running in confined mode. Make
|
40
|
-
sure that hook scripts has the correct context (`foreman_hook_t` on
|
41
|
-
RHEL7+/Fedora 19+ or `bin_t` on RHEL6):
|
42
|
-
|
43
|
-
restorecon -RvF /usr/share/foreman/config/hooks
|
44
|
-
|
45
|
-
Also keep in mind that the script is running confined, therefore some actions
|
46
|
-
might be denied by SELinux. Check audit.log and use audit2allow and other
|
47
|
-
tools when writing scripts.
|
48
|
-
|
49
36
|
## Objects / Models
|
50
37
|
|
51
38
|
Every object (or model in Rails terms) in Foreman can have hooks. Check
|
@@ -53,13 +40,26 @@ Every object (or model in Rails terms) in Foreman can have hooks. Check
|
|
53
40
|
|
54
41
|
* `host/managed` (or `host` in Foreman 1.1)
|
55
42
|
* `report`
|
43
|
+
* `nic/managed`
|
44
|
+
* `hostgroup`
|
45
|
+
* `user`
|
46
|
+
|
47
|
+
To generate a list of *all* possible models, issue the following command:
|
48
|
+
|
49
|
+
# foreman-rake hooks:objects
|
50
|
+
|
51
|
+
and to get events for a listed object (e.g. `host/managed`):
|
52
|
+
|
53
|
+
# foreman-rake hooks:events[host/managed]
|
56
54
|
|
57
55
|
## Orchestration events
|
58
56
|
|
59
57
|
Foreman supports orchestration tasks for hosts and NICs (each network
|
60
58
|
interface) which happen when the object is created, updated and destroyed.
|
61
59
|
These tasks are shown to the user in the UI and if they fail, will
|
62
|
-
automatically trigger a rollback of the action.
|
60
|
+
automatically trigger a rollback of the action. A rollback is performed as
|
61
|
+
an opposite action (e.g. for DHCP record creation a rollback action is
|
62
|
+
destroy).
|
63
63
|
|
64
64
|
To add hooks to these, use these event names:
|
65
65
|
|
@@ -67,11 +67,15 @@ To add hooks to these, use these event names:
|
|
67
67
|
* `update`
|
68
68
|
* `destroy`
|
69
69
|
|
70
|
+
Orchestration hooks can be given a priority (see below), therefore it is
|
71
|
+
possible to order them before or after built-in orchestration steps (before
|
72
|
+
DNS record is created for example).
|
73
|
+
|
70
74
|
## Rails events
|
71
75
|
|
72
|
-
For hooks on anything apart from hosts (which support orchestration,
|
73
|
-
then the standard Rails events will be needed.
|
74
|
-
events provided:
|
76
|
+
For hooks on anything apart from hosts or NICs (which support orchestration,
|
77
|
+
as above) then the standard Rails events will be needed. These are the most
|
78
|
+
interesting events provided:
|
75
79
|
|
76
80
|
* `after_create`, `before_create`
|
77
81
|
* `after_destroy`, `before_destroy`
|
@@ -100,7 +104,7 @@ representation of the object that was hooked, e.g. the hostname for a host.
|
|
100
104
|
A JSON representation of the hook object will be passed in on stdin. A utility
|
101
105
|
to read this with jgrep is provided in `examples/hook_functions.sh` and
|
102
106
|
sourcing this utility script will be enough for most users. Otherwise, you
|
103
|
-
may want to ensure stdin is closed.
|
107
|
+
may want to ensure stdin is closed to prevent pipe buffer from filling.
|
104
108
|
|
105
109
|
echo '{"host":{"name":"foo.example.com"}}' \
|
106
110
|
| ~foreman/config/hooks/host/managed/create/50_register_system.sh \
|
@@ -122,6 +126,26 @@ to rollback its action - in this case the first argument will change as
|
|
122
126
|
appropriate, so must be obeyed by the script (e.g. a "create" hook will be
|
123
127
|
called with "destroy" if it has to be rolled back later).
|
124
128
|
|
129
|
+
## Transactions
|
130
|
+
|
131
|
+
Most hooks are triggered during database transaction. This can cause
|
132
|
+
conflicting updates when hook scripts emits database updates via Foreman CLI
|
133
|
+
or API. It is recommended to avoid this behavior and write a Foreman plugin
|
134
|
+
instead.
|
135
|
+
|
136
|
+
## SELinux notes
|
137
|
+
|
138
|
+
When using official installation on Red Hat and Fedora system, note that
|
139
|
+
SELinux is turned on by default and Foreman is running in confined mode. Make
|
140
|
+
sure that hook scripts has the correct context (`foreman_hook_t` on
|
141
|
+
RHEL7+/Fedora 19+ or `bin_t` on RHEL6):
|
142
|
+
|
143
|
+
restorecon -RvF /usr/share/foreman/config/hooks
|
144
|
+
|
145
|
+
Also keep in mind that the script is running confined, therefore some actions
|
146
|
+
might be denied by SELinux. Check audit.log and use audit2allow and other
|
147
|
+
tools when writing scripts.
|
148
|
+
|
125
149
|
# More resources
|
126
150
|
|
127
151
|
* [Extending Foreman quickly with hook scripts](http://m0dlx.com/blog/Extending_Foreman_quickly_with_hook_scripts.html)
|
data/lib/foreman_hooks.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
module ForemanHooks
|
2
|
-
require 'foreman_hooks/engine'
|
2
|
+
require 'foreman_hooks/engine'
|
3
3
|
require 'foreman_hooks/util'
|
4
4
|
require 'foreman_hooks/callback_hooks'
|
5
5
|
require 'foreman_hooks/orchestration_hook'
|
@@ -39,7 +39,7 @@ module ForemanHooks
|
|
39
39
|
@hooks = discover_hooks
|
40
40
|
@hooks.each do |klass,events|
|
41
41
|
events.each do |event,hooks|
|
42
|
-
logger.info "Finished
|
42
|
+
logger.info "Finished discovering #{hooks.size} hooks for #{klass}##{event}"
|
43
43
|
hooks.sort!
|
44
44
|
end
|
45
45
|
end
|
@@ -68,9 +68,16 @@ module ForemanHooks
|
|
68
68
|
|
69
69
|
def attach_hook(klass, events)
|
70
70
|
if events.keys.detect { |event| ['create', 'update', 'destroy'].include? event }
|
71
|
-
|
71
|
+
unless klass.ancestors.include?(ForemanHooks::OrchestrationHook)
|
72
|
+
logger.debug "Extending #{klass} with foreman_hooks orchestration hooking support"
|
73
|
+
klass.send(:include, ForemanHooks::OrchestrationHook)
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
unless klass.ancestors.include?(ForemanHooks::CallbackHooks)
|
78
|
+
logger.debug "Extending #{klass} with foreman_hooks Rails hooking support"
|
79
|
+
klass.send(:include, ForemanHooks::CallbackHooks)
|
72
80
|
end
|
73
|
-
klass.send(:include, ForemanHooks::CallbackHooks) unless klass.ancestors.include?(ForemanHooks::CallbackHooks)
|
74
81
|
end
|
75
82
|
|
76
83
|
def logger; Rails.logger; end
|
@@ -9,6 +9,7 @@ module ForemanHooks::CallbackHooks
|
|
9
9
|
filter, name = event.to_s.split('_', 2)
|
10
10
|
next unless name
|
11
11
|
|
12
|
+
Rails.logger.debug("Created hook method #{event} on #{self}")
|
12
13
|
set_callback name.to_sym, filter.to_sym, "#{event}_hooks".to_sym
|
13
14
|
define_method("#{event}_hooks") do
|
14
15
|
Rails.logger.debug "Observed #{event} hook on #{self}"
|
data/lib/foreman_hooks/engine.rb
CHANGED
data/lib/foreman_hooks/util.rb
CHANGED
@@ -9,6 +9,8 @@ module ForemanHooks::Util
|
|
9
9
|
'host'
|
10
10
|
when "Host::Discovered"
|
11
11
|
'discovered_host'
|
12
|
+
when "Audited::Adapters::ActiveRecord::Audit"
|
13
|
+
'audit'
|
12
14
|
else
|
13
15
|
self.class.name.downcase
|
14
16
|
end
|
@@ -17,7 +19,8 @@ module ForemanHooks::Util
|
|
17
19
|
def render_hook_json
|
18
20
|
# APIv2 has some pretty good templates. We could extend them later in special cases.
|
19
21
|
# Wrap them in a root node for pre-1.4 compatibility
|
20
|
-
|
22
|
+
view_path = Rails.root.join('app', 'views')
|
23
|
+
json = Rabl.render(self, "api/v2/#{render_hook_type.tableize}/show", :view_path => view_path, :format => :json)
|
21
24
|
%Q|{"#{render_hook_type}":#{json}}|
|
22
25
|
rescue => e
|
23
26
|
logger.warn "Unable to render #{self} (#{self.class}) using RABL: #{e.message}"
|
@@ -43,8 +46,12 @@ module ForemanHooks::Util
|
|
43
46
|
Open3.capture2e(*args.push(:stdin_data => stdin_data))
|
44
47
|
else # 1.8
|
45
48
|
Open3.popen3(*args) do |stdin,stdout,stderr|
|
46
|
-
|
47
|
-
|
49
|
+
begin
|
50
|
+
stdin.write(stdin_data)
|
51
|
+
stdin.close
|
52
|
+
rescue Errno::EPIPE
|
53
|
+
logger.debug "Foreman hook input data skipped, closed pipe"
|
54
|
+
end
|
48
55
|
# we could still deadlock here, it'd ideally select() on stdout+err
|
49
56
|
output = stderr.read
|
50
57
|
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
namespace :hooks do
|
2
|
+
desc 'Print a list of object names that can be hooked'
|
3
|
+
task :objects => :environment do
|
4
|
+
puts ActiveRecord::Base.descendants.collect(&:name).collect(&:underscore).sort
|
5
|
+
end
|
6
|
+
|
7
|
+
desc 'Print a list of event names for a given object, e.g. hooks:events[host/managed]'
|
8
|
+
task :events, [:object] => :environment do |t,args|
|
9
|
+
model = begin
|
10
|
+
args[:object].camelize.constantize
|
11
|
+
rescue NameError => e
|
12
|
+
fail("Unknown model #{args[:object]}, run hooks:objects to get a list (#{e.message})")
|
13
|
+
end
|
14
|
+
|
15
|
+
events = ActiveRecord::Callbacks::CALLBACKS.map(&:to_s).reject { |e| e.start_with?('around_') }
|
16
|
+
events.concat(['create', 'destroy', 'update']) if model.included_modules.include?(Orchestration)
|
17
|
+
puts events.sort
|
18
|
+
end
|
19
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: foreman_hooks
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.3.
|
4
|
+
version: 0.3.10
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Dominic Cleal
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2016-05-16 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: Plugin engine for Foreman that enables running custom hook scripts on
|
14
14
|
Foreman events
|
@@ -31,6 +31,7 @@ files:
|
|
31
31
|
- lib/foreman_hooks/engine.rb
|
32
32
|
- lib/foreman_hooks/orchestration_hook.rb
|
33
33
|
- lib/foreman_hooks/util.rb
|
34
|
+
- lib/tasks/hooks.rake
|
34
35
|
- test/test_helper.rb
|
35
36
|
- test/unit/host_observer_test.rb
|
36
37
|
homepage: http://github.com/theforeman/foreman_hooks
|