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 +4 -4
- data/README.md +57 -3
- data/examples/{hook_functions.sh → bash/hook_functions.sh} +0 -0
- data/examples/{log.sh → bash/log.sh} +0 -0
- data/examples/python/functions.py +37 -0
- data/examples/python/host/managed/create/10-logger.py +52 -0
- data/extra/foreman-debug.sh +0 -0
- data/lib/foreman_hooks.rb +1 -14
- data/lib/foreman_hooks/as_dependencies_hook.rb +13 -0
- data/lib/foreman_hooks/engine.rb +2 -0
- data/lib/foreman_hooks/orchestration_hook.rb +1 -1
- data/lib/foreman_hooks/util.rb +20 -1
- metadata +8 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2f2bdeb9f5b1cfff753640427f732d376599f824
|
4
|
+
data.tar.gz: d181ec7e648ff2c7631c2d39c69628bcd2f4e362
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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/
|
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-
|
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
|
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)
|
data/extra/foreman-debug.sh
CHANGED
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
|
data/lib/foreman_hooks/engine.rb
CHANGED
@@ -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 "
|
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|
|
data/lib/foreman_hooks/util.rb
CHANGED
@@ -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",
|
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.
|
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-
|
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.
|
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
|