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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 46c0a89abfd88c3504155a968576b0bda74eb5d1
4
- data.tar.gz: 706af60156c35ae99e53b9c19a7326075d6b938e
3
+ metadata.gz: a89ac7b975601cb22c02b50fe94047bb880e6989
4
+ data.tar.gz: 7c631de38f23086fedbc7936acef69b5f365d15a
5
5
  SHA512:
6
- metadata.gz: f613b965f1671fabebc64ea67ce1afbd883f3a17324f21e118c695ea5eb0bdc63398ee928fa2859f3d804c31b3f3a839264750d1fe949be33b5361bb6221c101
7
- data.tar.gz: 01afb060d70cbec9d50170e40bcef5c8960502fb77ba3ebdfc8d48bb92d944066d0370d485927c2300f9df448ad21848c91b91620a4844b28dcc579a608a9057
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/$OBJECT/$EVENT/$HOOK_SCRIPT
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, as above)
73
- then the standard Rails events will be needed. These are the most interesting
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)
@@ -1,5 +1,5 @@
1
1
  module ForemanHooks
2
- require 'foreman_hooks/engine' if defined?(Rails) && Rails::VERSION::MAJOR == 3
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 registering #{hooks.size} hooks for #{klass}##{event}"
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
- klass.send(:include, ForemanHooks::OrchestrationHook) unless klass.ancestors.include?(ForemanHooks::OrchestrationHook)
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}"
@@ -8,7 +8,7 @@ module ForemanHooks
8
8
 
9
9
  initializer 'foreman_hooks.register_plugin', :after=> :finisher_hook do |app|
10
10
  Foreman::Plugin.register :foreman_hooks do
11
- end if defined? Foreman::Plugin
11
+ end
12
12
  end
13
13
  end
14
14
  end
@@ -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
- json = Rabl.render(self, "api/v2/#{render_hook_type.tableize}/show", :view_path => 'app/views', :format => :json)
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
- stdin.write(stdin_data)
47
- stdin.close
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.9
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: 2015-09-16 00:00:00.000000000 Z
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