foreman_hooks 0.3.9 → 0.3.10
Sign up to get free protection for your applications and to get access to all the features.
- 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
|