foreman_hooks-host_rename 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
data/Gemfile ADDED
@@ -0,0 +1,2 @@
1
+ gemspec
2
+ source 'https://rubygems.org'
@@ -0,0 +1,31 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ foreman_hooks-host_rename (0.0.3)
5
+ foreman_hooks
6
+ json
7
+ kwalify
8
+ minitest
9
+ rest_client
10
+ sqlite3
11
+
12
+ GEM
13
+ remote: https://rubygems.org/
14
+ specs:
15
+ foreman_hooks (0.3.7)
16
+ json (1.8.1)
17
+ kwalify (0.7.2)
18
+ minitest (5.4.2)
19
+ netrc (0.7.9)
20
+ rake (10.3.2)
21
+ rest_client (1.8.1)
22
+ netrc (~> 0.7.7)
23
+ sqlite3 (1.3.9)
24
+
25
+ PLATFORMS
26
+ ruby
27
+
28
+ DEPENDENCIES
29
+ bundler
30
+ foreman_hooks-host_rename!
31
+ rake
data/LICENSE ADDED
@@ -0,0 +1,18 @@
1
+ Copyright (c) 2014 Bronto Software Inc.
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy of
4
+ this software and associated documentation files (the "Software"), to deal in
5
+ the Software without restriction, including without limitation the rights to
6
+ use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
7
+ the Software, and to permit persons to whom the Software is furnished to do so,
8
+ subject to the following conditions:
9
+
10
+ The above copyright notice and this permission notice shall be included in all
11
+ copies or substantial portions of the Software.
12
+
13
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
15
+ FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
16
+ COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
17
+ IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
18
+ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,87 @@
1
+ foreman_hooks-host_rename
2
+ ===================
3
+
4
+ This hook is designed to extend the Foreman Hooks mechanism to detect when a host
5
+ has been renamed and fire a custom 'rename' hook.
6
+
7
+ Requirements
8
+ ============
9
+
10
+ This hook has only been tested in the following environment:
11
+
12
+ * CentOS 6.5
13
+ * Ruby 1.9.3 installed via the SCL mechanism
14
+
15
+ Installation
16
+ ============
17
+
18
+ 1. Install the gem as root, using the Ruby 1.9 install location:
19
+
20
+ sudo scl enable ruby193 'gem install foreman_hooks-host_rename'
21
+
22
+ 2. Create a configuration file in /etc/foreman_hooks-host_rename/settings.yaml.
23
+ See the 'Configuration' section for details.
24
+
25
+ 3. Run 'sudo foreman_hooks-host_rename --install' to register the hook with
26
+ Foreman.
27
+
28
+ 4. Restart Apache via 'sudo service httpd restart'
29
+
30
+ Configuration
31
+ =============
32
+
33
+ The configuration file is stored in conf/settings.yaml. Here are the variables:
34
+
35
+ foreman_host
36
+
37
+ The FQDN of the host that runs Foreman
38
+
39
+ foreman_user, foreman_password
40
+
41
+ The user account to login to Foreman with
42
+
43
+ rename_hook_command
44
+
45
+ The command to run after a host is renamed. A JSON object will be passed in via STDIN, and two parameters will be set in ARGV:
46
+ 1. the old hostname, as a FQDN
47
+ 2. the new hostname, as a FQDN
48
+
49
+ For an example, see conf/settings.yaml.EXAMPLE
50
+
51
+ Uninstallation
52
+ ==============
53
+
54
+ To remove the hook, perform the following steps:
55
+
56
+ 1. Run 'sudo foreman_hooks-host_rename --uninstall' to unregister the hook with
57
+ Foreman.
58
+
59
+ 2. Restart Apache via 'sudo service httpd restart'
60
+
61
+ Bugs
62
+ ====
63
+
64
+ * Some configuration options are undocumented.
65
+ * The database and logs are stored in /var/tmp by default.
66
+
67
+ Copyright
68
+ =========
69
+
70
+ Copyright (c) 2014 Bronto Software Inc.
71
+
72
+ Permission is hereby granted, free of charge, to any person obtaining a copy of
73
+ this software and associated documentation files (the "Software"), to deal in
74
+ the Software without restriction, including without limitation the rights to
75
+ use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
76
+ the Software, and to permit persons to whom the Software is furnished to do so,
77
+ subject to the following conditions:
78
+
79
+ The above copyright notice and this permission notice shall be included in all
80
+ copies or substantial portions of the Software.
81
+
82
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
83
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
84
+ FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
85
+ COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
86
+ IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
87
+ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,41 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+
4
+ require 'optparse'
5
+ require 'ostruct'
6
+ require 'foreman_hook/host_rename'
7
+
8
+ action = :run
9
+ options = OpenStruct.new
10
+ options.verbose = false
11
+
12
+ OptionParser.new do |opts|
13
+ opts.on( '--verbose', 'Display extra debugging information') do |arg|
14
+ options.verbose = true
15
+ end
16
+
17
+ opts.on( '--install', 'Install the hook into Foreman') do
18
+ action = :install
19
+ end
20
+
21
+ opts.on( '--uninstall', 'Install the hook from Foreman') do
22
+ action = :uninstall
23
+ end
24
+
25
+ opts.on( '-h', '--help', 'Display this screen' ) do
26
+ puts opts
27
+ exit
28
+ end
29
+ end.parse!
30
+
31
+ hook = ForemanHook::HostRename.new
32
+ case action
33
+ when :install
34
+ hook.install
35
+ when :uninstall
36
+ hook.uninstall
37
+ when :run
38
+ hook.run
39
+ else
40
+ raise ArgumentError, 'Must specify a valid action' if action.nil?
41
+ end
@@ -0,0 +1,28 @@
1
+ type: map
2
+ mapping:
3
+ "foreman_user":
4
+ type: str
5
+ required: yes
6
+ "foreman_password":
7
+ type: str
8
+ required: yes
9
+ "foreman_host":
10
+ type: str
11
+ required: yes
12
+ "hook_user":
13
+ type: str
14
+ required: no
15
+ "log_path":
16
+ type: str
17
+ required: no
18
+ "log_level":
19
+ type: str
20
+ required: no
21
+ pattern: /^(debug|warn|notice)$/
22
+ "database_path":
23
+ type: str
24
+ pattern: /^\//
25
+ required: no
26
+ "rename_hook_command":
27
+ type: str
28
+ required: yes
@@ -0,0 +1,5 @@
1
+ ---
2
+ :foreman_host: 'foreman.acme.com'
3
+ :foreman_user: 'api-user'
4
+ :foreman_password: 'password1'
5
+ :rename_hook_command: '/bin/true'
@@ -0,0 +1 @@
1
+ *.db
@@ -0,0 +1,31 @@
1
+ require File.expand_path("../lib/foreman_hooks/host_rename/version", __FILE__)
2
+
3
+ Gem::Specification.new do |s|
4
+ s.name = "foreman_hooks-host_rename"
5
+ s.version = ForemanHooks::VERSION
6
+ s.platform = Gem::Platform::RUBY
7
+ s.authors = ["Mark Heily", "Bronto Software, Inc."]
8
+ s.email = ["mark.heily@bronto.com"]
9
+ s.homepage = "https://github.com/bronto/foreman_hooks-host_rename"
10
+ s.summary = "Foreman hook that fires when a host is renamed"
11
+ s.description = "See the README for details"
12
+
13
+ # Dependencies
14
+ s.required_ruby_version = '>= 1.9.3'
15
+ %w(foreman_hooks minitest json sqlite3 rest_client kwalify).each do |dep|
16
+ s.add_runtime_dependency dep
17
+ end
18
+
19
+ s.add_development_dependency "bundler"
20
+ s.add_development_dependency "rake"
21
+
22
+ # If you need to check in files that aren't .rb files, add them here
23
+ s.files = Dir[
24
+ "conf/{schema.yaml,settings.yaml.EXAMPLE}", "db/.gitignore",
25
+ "LICENSE", "*.md", "Gemfile", "Gemfile.lock", "*.gemspec",
26
+ ] + Dir.glob("{bin,lib}/**/*")
27
+ s.require_path = 'lib'
28
+
29
+ s.executables = ["foreman_hooks-host_rename"]
30
+
31
+ end
@@ -0,0 +1,290 @@
1
+ #
2
+ # Foreman hook that detects when a host has been renamed and runs a 'rename' hook
3
+ #
4
+ # Copyright (c) 2014 Bronto Software Inc.
5
+ #
6
+ # Permission is hereby granted, free of charge, to any person obtaining a copy of
7
+ # this software and associated documentation files (the "Software"), to deal in
8
+ # the Software without restriction, including without limitation the rights to
9
+ # use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
10
+ # the Software, and to permit persons to whom the Software is furnished to do so,
11
+ # subject to the following conditions:
12
+ #
13
+ # The above copyright notice and this permission notice shall be included in all
14
+ # copies or substantial portions of the Software.
15
+ #
16
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
18
+ # FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
19
+ # COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
20
+ # IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21
+ # CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
+ #
23
+
24
+ raise 'Unsupported version of Ruby' unless RUBY_VERSION >= '1.9.3'
25
+
26
+ module ForemanHook
27
+ class HostRename
28
+ require 'fileutils'
29
+ require 'json'
30
+ require 'logger'
31
+ require 'kwalify'
32
+ require 'sqlite3'
33
+ require 'rest_client'
34
+ require 'pp'
35
+ require 'yaml'
36
+
37
+ attr_accessor :database_path
38
+
39
+ # Given a nested hash, convert all keys from String to Symbol type
40
+ # Based on http://stackoverflow.com/questions/800122/best-way-to-convert-strings-to-symbols-in-hash
41
+ #
42
+ def symbolize(obj)
43
+ return obj.inject({}){|memo,(k,v)| memo[k.to_sym] = symbolize(v); memo} if obj.is_a? Hash
44
+ return obj.inject([]){|memo,v | memo << symbolize(v); memo} if obj.is_a? Array
45
+ return obj
46
+ end
47
+
48
+ # Parse the configuration file
49
+ def parse_config(conffile = nil)
50
+ conffile ||= Dir.glob([
51
+ "/etc/foreman_hooks-host_rename/settings.yaml",
52
+ "#{confdir}/settings.yaml"])[0]
53
+ raise "Could not locate the configuration file" if conffile.nil?
54
+
55
+ # Parse the configuration file
56
+ config = {
57
+ hook_user: 'foreman',
58
+ database_path: prefix + '/db/foreman_hook_rename.db',
59
+ log_path: '/var/tmp/foreman_hook_rename.log',
60
+ log_level: 'warn',
61
+ rename_hook_command: '/bin/true',
62
+ }.merge(symbolize(YAML.load(File.read(conffile))))
63
+ config.each do |k,v|
64
+ instance_variable_set("@#{k}",v)
65
+ end
66
+
67
+ # Validate the schema
68
+ document = Kwalify::Yaml.load_file(conffile)
69
+ schema = Kwalify::Yaml.load_file("#{confdir}/schema.yaml")
70
+ validator = Kwalify::Validator.new(schema)
71
+ errors = validator.validate(document)
72
+ if errors && !errors.empty?
73
+ puts "WARNING: The following errors were found in #{conffile}:"
74
+ for e in errors
75
+ puts "[#{e.path}] #{e.message}"
76
+ end
77
+ raise "Errors in the configuration file"
78
+ end
79
+
80
+ check_script @rename_hook_command
81
+ end
82
+
83
+ # Do additional sanity checking on the database path
84
+ def validate_database
85
+ db = @database_path
86
+ raise "bad mode of #{db}" unless File.world_readable?(db).nil?
87
+ end
88
+
89
+ # Do additional sanity checking on a hook script
90
+ def check_script(path)
91
+ binary=path.split(' ')[0]
92
+ raise "#{path} does not exist" unless File.exist? binary
93
+ raise "#{path} is not executable" unless File.executable? binary
94
+ path
95
+ end
96
+
97
+ # Given an absolute [+path+] within the Foreman API, return the full URI
98
+ def foreman_uri(path)
99
+ raise ArgumentError, 'path must start with a /' unless path =~ /^\//
100
+ ['https://', @foreman_user, ':', @foreman_password, '@',
101
+ @foreman_host, '/api/v2', path].join('')
102
+ end
103
+
104
+ # Get all the host IDs and FQDNs and populate the host table
105
+ def sync_host_table
106
+ uri = foreman_uri('/hosts?per_page=9999999')
107
+ debug "Loading hosts from #{uri}"
108
+ json = RestClient.get uri
109
+ debug "Got JSON: #{json}"
110
+ JSON.parse(json)['results'].each do |rec|
111
+ @db.execute "insert into host (id,name) values ( ?, ? )",
112
+ rec['id'], rec['name']
113
+ end
114
+ end
115
+
116
+ # Initialize an empty database
117
+ def initialize_database
118
+ @db = SQLite3::Database.new @database_path
119
+ File.chmod 0600, @database_path
120
+ begin
121
+ @db.execute 'drop table if exists host;'
122
+ @db.execute <<-SQL
123
+ create table host (
124
+ id INT,
125
+ name varchar(254)
126
+ );
127
+ SQL
128
+ sync_host_table
129
+ rescue
130
+ File.unlink @database_path
131
+ raise
132
+ end
133
+ end
134
+
135
+ # Open a database connection. If the database does not exist, initialize it.
136
+ def open_database
137
+ if File.exist? @database_path
138
+ validate_database
139
+ @db = SQLite3::Database.new @database_path
140
+ else
141
+ initialize_database
142
+ end
143
+ end
144
+
145
+ # Update the database based on the foreman_hook
146
+ def execute_hook_action
147
+ @rename = false
148
+ name = @rec['host']['name']
149
+ id = @rec['host']['id']
150
+
151
+ case @action
152
+ when 'create'
153
+ sql = "insert into host (id, name) values (?, ?)"
154
+ params = [id, name]
155
+ when 'update'
156
+ # Check if we are renaming the host
157
+ @old_name = @db.get_first_row('select name from host where id = ?', id)[0]
158
+ if @old_name.nil?
159
+ warn 'received an update for a non-existent host'
160
+ else
161
+ @rename = @old_name != name
162
+ end
163
+ debug "checking for a rename: old=#{@old_name} new=#{name} rename?=#{@rename}"
164
+
165
+ sql = 'update host set name = ? where id = ?'
166
+ params = [name, id]
167
+ when 'destroy'
168
+ sql = 'delete from host where id = ?'
169
+ params = [id]
170
+ else
171
+ raise ArgumentError, "unsupported action: #{ARGV[0]}"
172
+ end
173
+ debug "updating database; id=#{id} name=#{name} sql=#{sql}"
174
+ stm = @db.prepare sql
175
+ stm.bind_params *params
176
+ stm.execute
177
+ end
178
+
179
+ # Check if the host has been renamed
180
+ # @return true, if the host has been renamed
181
+ def rename?
182
+ @rename
183
+ end
184
+
185
+ def execute_rename_action
186
+ raise 'old_name is nil' if @old_name.nil?
187
+ raise 'new_name is nil' if @rec['host']['name'].nil?
188
+ cmd = @rename_hook_command + ' ' + @old_name + ' ' + @rec['host']['name']
189
+ debug "Running the rename hook action: #{cmd}"
190
+ open('|' + cmd, 'w+') do |subprocess|
191
+ subprocess.write @rec.to_json
192
+ end
193
+ rc = $?.exitstatus
194
+ warn "Hook exited with status #{rc}" if rc != 0
195
+ end
196
+
197
+ def parse_hook_data
198
+ @action = ARGV[0] # one of: create, update, destroy
199
+ @rec = JSON.parse $stdin.read
200
+ debug "action=#{@action} rec=#{@rec.inspect}"
201
+ end
202
+
203
+ def log_level=(level)
204
+ @log_level = level
205
+ @log.level = level
206
+ end
207
+
208
+ def open_logfile
209
+ @log = Logger.new(@log_path, 10, 1024000)
210
+ case @log_level
211
+ when 'debug'
212
+ @log.level = Logger::DEBUG
213
+ when 'warn'
214
+ @log.level = Logger::WARN
215
+ when 'info'
216
+ @log.level = Logger::INFO
217
+ else
218
+ raise 'Unsupported log_level'
219
+ end
220
+ end
221
+
222
+ # Convenience methods for writing to the logfile
223
+ def debug(message) ; @log.debug(message) ; end
224
+ def notice(message) ; @log.notice(message) ; end
225
+ def warn(message) ; @log.warn(message) ; end
226
+
227
+ def initialize(opts = {})
228
+ if opts.has_key? :config
229
+ f = Tempfile.new('hook-settings')
230
+ f.write(opts[:config].to_yaml)
231
+ f.close
232
+ parse_config(f.path)
233
+ else
234
+ parse_config
235
+ end
236
+ end
237
+
238
+ def run
239
+ open_logfile
240
+ begin
241
+ open_database
242
+ parse_hook_data
243
+ execute_hook_action
244
+ execute_rename_action if rename?
245
+ rescue Exception => e
246
+ @log.error e.message
247
+ @log.error e.backtrace.to_yaml
248
+ end
249
+ end
250
+
251
+ def install(hookdir = nil)
252
+ hookdir ||= '/usr/share/foreman/config/hooks/host/managed'
253
+ raise "hook directory not found" unless File.exist? hookdir
254
+ %w(create update destroy).each do |event|
255
+ path = "#{hookdir}/#{event}"
256
+ raise "path not found: #{path}" unless File.exist? path
257
+ hook = "#{path}/99_host_rename"
258
+ next if File.exist? hook
259
+ f = File.open(hook, 'w')
260
+ f.puts '#!/bin/sh'
261
+ f.puts 'exec scl enable ruby193 "/usr/bin/foreman_hooks-host_rename $*"'
262
+ f.close
263
+ File.chmod 0755, hook
264
+ end
265
+ sysconfdir = '/etc/foreman_hooks-host_rename'
266
+ Dir.mkdir sysconfdir unless File.exist? sysconfdir
267
+ puts 'The hook has been installed. Please restart Apache to activate the hook.'
268
+ end
269
+
270
+ def uninstall(hookdir = nil)
271
+ hookdir ||= '/usr/share/foreman/config/hooks/host/managed'
272
+ %w(create update destroy).each do |event|
273
+ hook = "#{hookdir}/#{event}/99_host_rename"
274
+ #puts "removing #{hook}.."
275
+ File.unlink hook if File.exist? hook
276
+ end
277
+ puts 'The hook has been uninstalled. Please restart Apache to deactivate the hook.'
278
+ end
279
+
280
+ private
281
+
282
+ def prefix
283
+ @prefix ||= File.realpath(File.dirname(__FILE__) + '/../../')
284
+ end
285
+
286
+ def confdir
287
+ @confdir ||= "#{prefix}/conf"
288
+ end
289
+ end
290
+ end
@@ -0,0 +1,3 @@
1
+ module ForemanHooks
2
+ VERSION = "0.0.3"
3
+ end
metadata ADDED
@@ -0,0 +1,186 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: foreman_hooks-host_rename
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.3
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Mark Heily
9
+ - Bronto Software, Inc.
10
+ autorequire:
11
+ bindir: bin
12
+ cert_chain: []
13
+ date: 2014-10-28 00:00:00.000000000 Z
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: foreman_hooks
17
+ requirement: !ruby/object:Gem::Requirement
18
+ none: false
19
+ requirements:
20
+ - - ! '>='
21
+ - !ruby/object:Gem::Version
22
+ version: '0'
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ none: false
27
+ requirements:
28
+ - - ! '>='
29
+ - !ruby/object:Gem::Version
30
+ version: '0'
31
+ - !ruby/object:Gem::Dependency
32
+ name: minitest
33
+ requirement: !ruby/object:Gem::Requirement
34
+ none: false
35
+ requirements:
36
+ - - ! '>='
37
+ - !ruby/object:Gem::Version
38
+ version: '0'
39
+ type: :runtime
40
+ prerelease: false
41
+ version_requirements: !ruby/object:Gem::Requirement
42
+ none: false
43
+ requirements:
44
+ - - ! '>='
45
+ - !ruby/object:Gem::Version
46
+ version: '0'
47
+ - !ruby/object:Gem::Dependency
48
+ name: json
49
+ requirement: !ruby/object:Gem::Requirement
50
+ none: false
51
+ requirements:
52
+ - - ! '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ type: :runtime
56
+ prerelease: false
57
+ version_requirements: !ruby/object:Gem::Requirement
58
+ none: false
59
+ requirements:
60
+ - - ! '>='
61
+ - !ruby/object:Gem::Version
62
+ version: '0'
63
+ - !ruby/object:Gem::Dependency
64
+ name: sqlite3
65
+ requirement: !ruby/object:Gem::Requirement
66
+ none: false
67
+ requirements:
68
+ - - ! '>='
69
+ - !ruby/object:Gem::Version
70
+ version: '0'
71
+ type: :runtime
72
+ prerelease: false
73
+ version_requirements: !ruby/object:Gem::Requirement
74
+ none: false
75
+ requirements:
76
+ - - ! '>='
77
+ - !ruby/object:Gem::Version
78
+ version: '0'
79
+ - !ruby/object:Gem::Dependency
80
+ name: rest_client
81
+ requirement: !ruby/object:Gem::Requirement
82
+ none: false
83
+ requirements:
84
+ - - ! '>='
85
+ - !ruby/object:Gem::Version
86
+ version: '0'
87
+ type: :runtime
88
+ prerelease: false
89
+ version_requirements: !ruby/object:Gem::Requirement
90
+ none: false
91
+ requirements:
92
+ - - ! '>='
93
+ - !ruby/object:Gem::Version
94
+ version: '0'
95
+ - !ruby/object:Gem::Dependency
96
+ name: kwalify
97
+ requirement: !ruby/object:Gem::Requirement
98
+ none: false
99
+ requirements:
100
+ - - ! '>='
101
+ - !ruby/object:Gem::Version
102
+ version: '0'
103
+ type: :runtime
104
+ prerelease: false
105
+ version_requirements: !ruby/object:Gem::Requirement
106
+ none: false
107
+ requirements:
108
+ - - ! '>='
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ - !ruby/object:Gem::Dependency
112
+ name: bundler
113
+ requirement: !ruby/object:Gem::Requirement
114
+ none: false
115
+ requirements:
116
+ - - ! '>='
117
+ - !ruby/object:Gem::Version
118
+ version: '0'
119
+ type: :development
120
+ prerelease: false
121
+ version_requirements: !ruby/object:Gem::Requirement
122
+ none: false
123
+ requirements:
124
+ - - ! '>='
125
+ - !ruby/object:Gem::Version
126
+ version: '0'
127
+ - !ruby/object:Gem::Dependency
128
+ name: rake
129
+ requirement: !ruby/object:Gem::Requirement
130
+ none: false
131
+ requirements:
132
+ - - ! '>='
133
+ - !ruby/object:Gem::Version
134
+ version: '0'
135
+ type: :development
136
+ prerelease: false
137
+ version_requirements: !ruby/object:Gem::Requirement
138
+ none: false
139
+ requirements:
140
+ - - ! '>='
141
+ - !ruby/object:Gem::Version
142
+ version: '0'
143
+ description: See the README for details
144
+ email:
145
+ - mark.heily@bronto.com
146
+ executables:
147
+ - foreman_hooks-host_rename
148
+ extensions: []
149
+ extra_rdoc_files: []
150
+ files:
151
+ - conf/schema.yaml
152
+ - conf/settings.yaml.EXAMPLE
153
+ - db/.gitignore
154
+ - LICENSE
155
+ - README.md
156
+ - Gemfile
157
+ - Gemfile.lock
158
+ - foreman_hooks-host_rename.gemspec
159
+ - bin/foreman_hooks-host_rename
160
+ - lib/foreman_hooks/host_rename/version.rb
161
+ - lib/foreman_hooks/host_rename.rb
162
+ homepage: https://github.com/bronto/foreman_hooks-host_rename
163
+ licenses: []
164
+ post_install_message:
165
+ rdoc_options: []
166
+ require_paths:
167
+ - lib
168
+ required_ruby_version: !ruby/object:Gem::Requirement
169
+ none: false
170
+ requirements:
171
+ - - ! '>='
172
+ - !ruby/object:Gem::Version
173
+ version: 1.9.3
174
+ required_rubygems_version: !ruby/object:Gem::Requirement
175
+ none: false
176
+ requirements:
177
+ - - ! '>='
178
+ - !ruby/object:Gem::Version
179
+ version: '0'
180
+ requirements: []
181
+ rubyforge_project:
182
+ rubygems_version: 1.8.23
183
+ signing_key:
184
+ specification_version: 3
185
+ summary: Foreman hook that fires when a host is renamed
186
+ test_files: []