foreman_hooks 0.3.13 → 0.3.14

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 40ce82d00a918185af3f0e75063311cdca9c7ecb
4
- data.tar.gz: ba63e860d91d252f31fc231a6ca16ca9f63129ca
3
+ metadata.gz: 2f2bdeb9f5b1cfff753640427f732d376599f824
4
+ data.tar.gz: d181ec7e648ff2c7631c2d39c69628bcd2f4e362
5
5
  SHA512:
6
- metadata.gz: 6740120f31efa77b71e218bade83661697dc9aba205444f2bc04f48864d13f0b159fe74f77c76cb44c5c46228bb890f0db4997bb49969a75d9dc983c60dded52
7
- data.tar.gz: 2a94de8cf7102c8a20c4b6ec79734a4856736ada300160dcf6793254a399cc56c9dd435a50d0256c0e39c2627e3d08a993274617c37b130c5123938ea106f0cd
6
+ metadata.gz: a10e596c30229296c2b8e90f5c6023f227cec98763b45ca956247131027722c26eaa3716636853322d41ae96e91732c9afae5f0fafe0a353cccc8ccb32ece938
7
+ data.tar.gz: 1a9c5966288d7d7f2e02277bf31e6d32cecc00cb128a697adb1c1eb09ce54e9ecb1e323eaf9abf71cacee9faa336bd338781f16a9d7198aa849dee759526b9b6
data/README.md CHANGED
@@ -17,7 +17,8 @@ Please see the Foreman wiki for appropriate instructions:
17
17
  The gem name is "foreman_hooks".
18
18
 
19
19
  RPM users can install the "tfm-rubygem-foreman_hooks" or
20
- "rubygem-foreman_hooks" packages.
20
+ "rubygem-foreman_hooks" packages. Debian/Ubuntu users can install the
21
+ "ruby-foreman-hooks" package.
21
22
 
22
23
  # Usage
23
24
 
@@ -31,7 +32,11 @@ Examples:
31
32
  ~foreman/config/hooks/host/managed/create/50_register_system.sh
32
33
  ~foreman/config/hooks/host/managed/destroy/15_cleanup_database.sh
33
34
  ~foreman/config/hooks/smart_proxy/after_create/01_email_operations.sh
34
- ~foreman/config/hooks/audited/adapters/active_record/audit/after_create/01_syslog.sh
35
+ ~foreman/config/hooks/audited/audit/after_create/01_syslog.sh
36
+
37
+ After adding or removing hooks, restart the Foreman server to update the list
38
+ of known hooks (usually `apache2` or `httpd` when using Passenger, or
39
+ `touch ~foreman/tmp/restart.txt`).
35
40
 
36
41
  ## Objects / Models
37
42
 
@@ -147,6 +152,54 @@ to rollback its action - in this case the first argument will change as
147
152
  appropriate, so must be obeyed by the script (e.g. a "create" hook will be
148
153
  called with "destroy" if it has to be rolled back later).
149
154
 
155
+ ## Logging
156
+
157
+ Entries are logged at application startup and during execution of hooks, but
158
+ most will be at 'debug' level and may use the 'sql' logger. Enable this in
159
+ Foreman's `/etc/foreman/settings.yaml`:
160
+
161
+ ```yaml
162
+ :logging:
163
+ :level: debug
164
+ :loggers:
165
+ :sql:
166
+ :enabled: true
167
+ ```
168
+
169
+ See [Foreman manual: Debugging](https://theforeman.org/manuals/latest/index.html#7.2Debugging)
170
+ for full details.
171
+
172
+ Enabling debugging and searching the Foreman log file (`/var/log/foreman/production.log`)
173
+ for the word "hook" will find all relevant log entries.
174
+
175
+ ### Hook discovery and setup
176
+
177
+ Expect to see these entries when the server starts:
178
+
179
+ * `Found hook to Host::Managed#create, filename 01_example` - for each
180
+ executable hook script in the correct location
181
+ * `Finished discovering 3 hooks for Host::Managed#create` - for each unique
182
+ event with hook scripts
183
+ * `Extending Host::Managed with foreman_hooks orchestration hooking support` -
184
+ if any orchestration (create/update/destroy) hooks exist for that object
185
+ * `Extending Host::Managed with foreman_hooks Rails hooking support` - if any
186
+ Rails events hooks exist for that object
187
+ * `Created hook method after_create on Host::Managed` - for each type of Rails
188
+ event that has hooks
189
+
190
+ ### Running hooks
191
+
192
+ Expect to see these entries logged when a hooked action occurs:
193
+
194
+ * `Observed after_create hook on test.example.com` when a registered Rails
195
+ event occurs, hook will then execute immediately
196
+ * `Queuing 3 hooks for Host::Managed#create` when an orchestration action is
197
+ being set up (hook will be executed later during orchestration)
198
+ * `Queuing hook 01_example for Host::Managed#create at priority 01` for each
199
+ hook registered when setting up an orchestration action
200
+ * `Running hook: /example/config/hooks/host/managed/create/01_example create test.example.com`
201
+ as the hook (orchestration or Rails event) is executed
202
+
150
203
  ## Transactions
151
204
 
152
205
  Most hooks are triggered during database transaction. This can cause
@@ -169,6 +222,7 @@ tools when writing scripts.
169
222
 
170
223
  # More resources
171
224
 
225
+ * [foreman\_hooks issue tracker](https://github.com/theforeman/foreman_hooks/issues)
172
226
  * [Extending Foreman quickly with hook scripts](http://m0dlx.com/blog/Extending_Foreman_quickly_with_hook_scripts.html)
173
227
  * [AWS VPC Buildout With Foreman Hooks for RDNS Creation](http://www.brian2.net/posts/foreman_hooks_aws_vpc/)
174
228
  * [Foreman <-> FreeIPA Integration Guide](https://bitbin.de/blog/2013/11/foreman-freeipa-integration-guide/)
@@ -176,7 +230,7 @@ tools when writing scripts.
176
230
 
177
231
  # Copyright
178
232
 
179
- Copyright (c) 2012-2013 Red Hat Inc.
233
+ Copyright (c) 2012-2017 Dominic Cleal
180
234
 
181
235
  This program is free software: you can redistribute it and/or modify
182
236
  it under the terms of the GNU General Public License as published by
File without changes
@@ -0,0 +1,37 @@
1
+ #!/usr/bin/env python
2
+ #######
3
+ # To allow this module to be imported by other triggers
4
+ # execute the commands below:
5
+ # $ mkdir -p /usr/share/foreman-community/hooks
6
+ # $ touch /usr/share/foreman-community/hooks/__init__.py
7
+ # $ cp functions.py /usr/share/foreman-community/hooks/
8
+ ########
9
+ import json
10
+ import sys
11
+ import tempfile
12
+
13
+ HOOK_TEMP_DIR = "/usr/share/foreman/tmp"
14
+
15
+ # HOOK_EVENT = update, create, before_destroy etc.
16
+ # HOOK_OBJECT = to_s representation of the object, e.g. host's fqdn
17
+ HOOK_EVENT, HOOK_OBJECT = (sys.argv[1], sys.argv[2])
18
+
19
+
20
+ def get_json_hook():
21
+ '''
22
+ Create JSON object to be imported by hook/trigger
23
+ Saves the data received via stdin to file.
24
+ It does not require to save to a file, but it may be useful
25
+ to troubleshooting.
26
+ '''
27
+
28
+ with tempfile.NamedTemporaryFile(
29
+ dir=HOOK_TEMP_DIR,
30
+ # set to False for troubleshooting
31
+ delete=True,
32
+ prefix="foreman_hooks.") as hook:
33
+
34
+ json_hook = sys.stdin.read()
35
+ hook.file.write(json_hook)
36
+ hook.file.flush()
37
+ return json.loads(json_hook)
@@ -0,0 +1,52 @@
1
+ #!/usr/bin/env python
2
+ import sys
3
+ import tempfile
4
+ import subprocess
5
+
6
+ sys.path.append('/usr/share/foreman-community/hooks')
7
+
8
+ from functions import \
9
+ (HOOK_EVENT, HOOK_OBJECT, HOOK_TEMP_DIR, get_json_hook)
10
+
11
+ PREFIX = "created_by_hook-{}".format(sys.argv[0].split('/')[-1])
12
+
13
+ HOOK_JSON = get_json_hook()
14
+
15
+ cmd = ['logger']
16
+
17
+ # read the information received
18
+ if HOOK_JSON.get('host'):
19
+ hostname = HOOK_JSON.get('host').get('name', None)
20
+ if hostname:
21
+ cmd.append('System:{0}'.format(hostname))
22
+
23
+ mac_address = HOOK_JSON.get('host').get('mac', None)
24
+ if mac_address:
25
+ cmd.append('MAC:{0}'.format(mac_address))
26
+
27
+ operating_system = HOOK_JSON.get('host').get('operatingsystem_name', None)
28
+ if operating_system:
29
+ cmd.append('OS:{0}'.format(operating_system))
30
+
31
+ # execute logger command
32
+ subprocess.call(cmd)
33
+
34
+ # for troubleshooting purposes, you can save the received data to a file
35
+ # to parse the information to be used on the trigger.
36
+ # To accomplish it, set the variable dumpdata to True
37
+ dumpdata = False
38
+ if dumpdata:
39
+ with tempfile.NamedTemporaryFile(dir=HOOK_TEMP_DIR,
40
+ delete=False,
41
+ prefix=PREFIX) as fd:
42
+ fd.file.write("HOOK_OBJECT: %s\n" % HOOK_OBJECT)
43
+ fd.file.write("HOOK_EVENT: %s\n" % HOOK_EVENT)
44
+ fd.file.write("HOOK_JSON: %s\n" % HOOK_JSON)
45
+
46
+ # local variables
47
+ fd.file.write("hostname: %s\n" % hostname)
48
+ fd.file.write("mac_address: %s\n" % mac_address)
49
+ fd.file.write("os: %s\n" % operating_system)
50
+ fd.file.flush()
51
+
52
+ sys.exit(0)
File without changes
data/lib/foreman_hooks.rb CHANGED
@@ -1,6 +1,7 @@
1
1
  module ForemanHooks
2
2
  require 'foreman_hooks/engine'
3
3
  require 'foreman_hooks/util'
4
+ require 'foreman_hooks/as_dependencies_hook'
4
5
  require 'foreman_hooks/callback_hooks'
5
6
  require 'foreman_hooks/orchestration_hook'
6
7
 
@@ -83,17 +84,3 @@ module ForemanHooks
83
84
  def logger; Rails.logger; end
84
85
  end
85
86
  end
86
-
87
- module ActiveSupport::Dependencies
88
- class << self
89
- def load_missing_constant_with_hooks(from_mod, constant_name)
90
- ret = load_missing_constant_without_hooks(from_mod, constant_name)
91
- ForemanHooks.hooks.each do |klass,events|
92
- ForemanHooks.attach_hook(ret, events) if ret.name == klass
93
- end
94
- ret
95
- end
96
-
97
- alias_method_chain :load_missing_constant, :hooks
98
- end
99
- end
@@ -0,0 +1,13 @@
1
+ module ForemanHooks
2
+ module ASDependenciesHook
3
+ def load_missing_constant(from_mod, constant_name)
4
+ super(from_mod, constant_name).tap do |ret|
5
+ ForemanHooks.hooks.each do |klass,events|
6
+ ForemanHooks.attach_hook(ret, events) if ret.name == klass
7
+ end
8
+ end
9
+ end
10
+ end
11
+
12
+ ActiveSupport::Dependencies.singleton_class.send(:prepend, ASDependenciesHook)
13
+ end
@@ -2,6 +2,8 @@ require 'foreman_hooks'
2
2
 
3
3
  module ForemanHooks
4
4
  class Engine < ::Rails::Engine
5
+ engine_name 'foreman_hooks'
6
+
5
7
  config.to_prepare do
6
8
  ForemanHooks.hooks.each do |klass,events|
7
9
  begin
@@ -27,7 +27,7 @@ module ForemanHooks::OrchestrationHook
27
27
  end
28
28
 
29
29
  return unless hooks = ForemanHooks.find_hooks(self.class, event)
30
- logger.debug "Queueing #{hooks.size} hooks for #{self.class.to_s}##{event}"
30
+ logger.debug "Queuing #{hooks.size} hooks for #{self.class.to_s}##{event}"
31
31
 
32
32
  counter = 0
33
33
  hooks.each do |filename|
@@ -20,7 +20,8 @@ module ForemanHooks::Util
20
20
  # APIv2 has some pretty good templates. We could extend them later in special cases.
21
21
  # Wrap them in a root node for pre-1.4 compatibility
22
22
  view_path = ActionController::Base.view_paths.collect(&:to_path)
23
- json = Rabl.render(self, "api/v2/#{render_hook_type.tableize}/show", :view_path => view_path, :format => :json)
23
+ json = Rabl.render(self, "api/v2/#{render_hook_type.tableize}/show",
24
+ view_path: view_path, format: :json, scope: RablScope.new)
24
25
  %Q|{"#{render_hook_type}":#{json}}|
25
26
  rescue => e
26
27
  logger.warn "Unable to render #{self} (#{self.class}) using RABL: #{e.message}"
@@ -29,6 +30,11 @@ module ForemanHooks::Util
29
30
  end
30
31
 
31
32
  def exec_hook(*args)
33
+ unless File.executable?(args.first)
34
+ logger.warn("Hook #{args.first} no longer exists or isn't executable, so skipping execution of the hook. The server should be restarted after adding or removing hooks.")
35
+ return true
36
+ end
37
+
32
38
  logger.debug "Running hook: #{args.join(' ')}"
33
39
  success, output = if defined? Bundler && Bundler.responds_to(:with_clean_env)
34
40
  Bundler.with_clean_env { exec_hook_int(render_hook_json, *args) }
@@ -60,4 +66,17 @@ module ForemanHooks::Util
60
66
  logger.debug "Hook output: #{output}" if output && !output.empty?
61
67
  [status.success?, output]
62
68
  end
69
+
70
+ class RablScope
71
+ def initialize
72
+ # Used by api/v2/hosts/main.json.yaml to include parameter lists
73
+ @all_parameters = true
74
+ @parameters = true
75
+ end
76
+
77
+ def params
78
+ # Used by app/views/api/v2/common/show_hidden.json.rabl to show hidden parameter values (#17653)
79
+ { 'show_hidden' => true, 'show_hidden_parameters' => true }
80
+ end
81
+ end
63
82
  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.13
4
+ version: 0.3.14
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dominic Cleal
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-02-16 00:00:00.000000000 Z
11
+ date: 2017-05-17 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
@@ -24,10 +24,13 @@ files:
24
24
  - README.md
25
25
  - Rakefile
26
26
  - TODO
27
- - examples/hook_functions.sh
28
- - examples/log.sh
27
+ - examples/bash/hook_functions.sh
28
+ - examples/bash/log.sh
29
+ - examples/python/functions.py
30
+ - examples/python/host/managed/create/10-logger.py
29
31
  - extra/foreman-debug.sh
30
32
  - lib/foreman_hooks.rb
33
+ - lib/foreman_hooks/as_dependencies_hook.rb
31
34
  - lib/foreman_hooks/callback_hooks.rb
32
35
  - lib/foreman_hooks/engine.rb
33
36
  - lib/foreman_hooks/orchestration_hook.rb
@@ -55,7 +58,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
55
58
  version: '0'
56
59
  requirements: []
57
60
  rubyforge_project:
58
- rubygems_version: 2.6.8
61
+ rubygems_version: 2.6.10
59
62
  signing_key:
60
63
  specification_version: 4
61
64
  summary: Run custom hook scripts on Foreman events