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