puppet_litmus 0.8.0 → 0.8.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,224 +1,228 @@
1
- # frozen_string_literal: true
2
-
3
- # helper functions for running puppet commands. They execute a target system specified by ENV['TARGET_HOST']
4
- # heavily uses functions from here https://github.com/puppetlabs/bolt/blob/master/developer-docs/bolt_spec-run.md
5
- module PuppetLitmus::Serverspec
6
- # Applies a manifest twice. First checking for errors. Secondly to make sure no changes occur.
7
- #
8
- # @param manifest [String] puppet manifest code to be applied.
9
- # @return [Boolean] The result of the 2 apply manifests.
10
- def idempotent_apply(manifest)
11
- manifest_file_location = create_manifest_file(manifest)
12
- apply_manifest(nil, catch_failures: true, manifest_file_location: manifest_file_location)
13
- apply_manifest(nil, catch_changes: true, manifest_file_location: manifest_file_location)
14
- end
15
-
16
- # rubocop:disable Layout/TrailingWhitespace
17
-
18
- # Applies a manifest. returning the result of that apply. Mimics the apply_manifest from beaker
19
- #
20
- # When you set the environment variable RSPEC_DEBUG, the output of your
21
- # puppet run will be displayed. If you have set the :debug flag, you will see the
22
- # full debug log. If you have **not** set the :debug flag, it will display the regular
23
- # output.
24
- #
25
- # @param manifest [String] puppet manifest code to be applied.
26
- # @param opts [Hash] Alters the behaviour of the command. Valid options are:
27
- # :catch_changes [Boolean] exit status of 1 if there were changes.
28
- # :expect_failures [Boolean] doesnt return an exit code of non-zero if the apply failed.
29
- # :manifest_file_location [Path] The place on the target system.
30
- # :prefix_command [String] prefixes the puppet apply command; eg "export LANGUAGE='ja'".
31
- # :debug [Boolean] run puppet apply with the debug flag.
32
- # :noop [Boolean] run puppet apply with the noop flag.
33
- # @yieldreturn [Block] this method will yield to a block of code passed by the caller; this can be used for additional validation, etc.
34
- # @return [Object] A result object from the apply.
35
- def apply_manifest(manifest, opts = {})
36
- # rubocop:enable Layout/TrailingWhitespace
37
- target_node_name = ENV['TARGET_HOST']
38
- raise 'manifest and manifest_file_location in the opts hash are mutually exclusive arguments, pick one' if !manifest.nil? && !opts[:manifest_file_location].nil?
39
- raise 'please pass a manifest or the manifest_file_location in the opts hash' if (manifest.nil? || manifest == '') && opts[:manifest_file_location].nil?
40
-
41
- manifest_file_location = opts[:manifest_file_location] || create_manifest_file(manifest)
42
- inventory_hash = if target_node_name.nil? || target_node_name == 'localhost'
43
- nil
44
- else
45
- inventory_hash_from_inventory_file
46
- end
47
- command_to_run = "#{opts[:prefix_command]} puppet apply #{manifest_file_location}"
48
- command_to_run += " --modulepath #{Dir.pwd}/spec/fixtures/modules" if target_node_name.nil? || target_node_name == 'localhost'
49
- command_to_run += ' --detailed-exitcodes' if !opts[:catch_changes].nil? && (opts[:catch_changes] == true)
50
- command_to_run += ' --debug' if !opts[:debug].nil? && (opts[:debug] == true)
51
- command_to_run += ' --noop' if !opts[:noop].nil? && (opts[:noop] == true)
52
- result = run_command(command_to_run, target_node_name, config: nil, inventory: inventory_hash)
53
-
54
- raise "apply manifest failed\n`#{command_to_run}`\n======\n#{result}" if result.first['result']['exit_code'] != 0 && opts[:expect_failures] != true
55
-
56
- result = OpenStruct.new(exit_code: result.first['result']['exit_code'],
57
- stdout: result.first['result']['stdout'],
58
- stderr: result.first['result']['stderr'])
59
- yield result if block_given?
60
- if ENV['RSPEC_DEBUG']
61
- puts "apply manifest succeded\n #{command_to_run}\n======\nwith status #{result.exit_code}"
62
- puts result.stderr
63
- puts result.stdout
64
- end
65
- result
66
- end
67
-
68
- # Creates a manifest file locally in a temp location, if its a remote target copy it to there.
69
- #
70
- # @param manifest [String] puppet manifest code.
71
- # @return [String] The path to the location of the manifest.
72
- def create_manifest_file(manifest)
73
- require 'tmpdir'
74
- target_node_name = ENV['TARGET_HOST']
75
- tmp_filename = File.join(Dir.tmpdir, "manifest_#{Time.now.strftime('%Y%m%d')}_#{Process.pid}_#{rand(0x100000000).to_s(36)}.pp")
76
- manifest_file = File.open(tmp_filename, 'w')
77
- manifest_file.write(manifest)
78
- manifest_file.close
79
- if target_node_name.nil? || target_node_name == 'localhost'
80
- # no need to transfer
81
- manifest_file_location = manifest_file.path
82
- else
83
- # transfer to TARGET_HOST
84
- inventory_hash = inventory_hash_from_inventory_file
85
- manifest_file_location = "/tmp/#{File.basename(manifest_file)}"
86
- result = upload_file(manifest_file.path, manifest_file_location, target_node_name, options: {}, config: nil, inventory: inventory_hash)
87
- raise result.first['result'].to_s unless result.first['status'] == 'success'
88
- end
89
- manifest_file_location
90
- end
91
-
92
- # Runs a command against the target system
93
- #
94
- # @param command_to_run [String] The command to execute.
95
- # @param opts [Hash] Alters the behaviour of the command. Valid options are :expect_failures [Boolean] doesnt return an exit code of non-zero if the command failed.
96
- # @yieldreturn [Block] this method will yield to a block of code passed by the caller; this can be used for additional validation, etc.
97
- # @return [Object] A result object from the command.
98
- def run_shell(command_to_run, opts = {})
99
- target_node_name = ENV['TARGET_HOST']
100
- inventory_hash = if target_node_name.nil? || target_node_name == 'localhost'
101
- nil
102
- else
103
- inventory_hash_from_inventory_file
104
- end
105
- result = run_command(command_to_run, target_node_name, config: nil, inventory: inventory_hash)
106
- raise "shell failed\n`#{command_to_run}`\n======\n#{result}" if result.first['result']['exit_code'] != 0 && opts[:expect_failures] != true
107
-
108
- result = OpenStruct.new(exit_code: result.first['result']['exit_code'],
109
- stdout: result.first['result']['stdout'],
110
- stderr: result.first['result']['stderr'])
111
- yield result if block_given?
112
- result
113
- end
114
-
115
- # Copies file to the target, using its respective transport
116
- #
117
- # @param source [String] place locally, to copy from.
118
- # @param destination [String] place on the target, to copy to.
119
- # @param opts [Hash] Alters the behaviour of the command. Valid options are :expect_failures [Boolean] doesnt return an exit code of non-zero if the command failed.
120
- # @yieldreturn [Block] this method will yield to a block of code passed by the caller; this can be used for additional validation, etc.
121
- # @return [Object] A result object from the command.
122
- def bolt_upload_file(source, destination, opts = {}, options = {})
123
- target_node_name = ENV['TARGET_HOST'] if target_node_name.nil?
124
- inventory_hash = if target_node_name.nil? || target_node_name == 'localhost'
125
- nil
126
- else
127
- inventory_hash_from_inventory_file
128
- end
129
-
130
- result = upload_file(source, destination, target_node_name, options: options, config: nil, inventory: inventory_hash)
131
-
132
- result_obj = {
133
- exit_code: 0,
134
- stdout: result.first['result']['_output'],
135
- stderr: nil,
136
- result: result.first['result'],
137
- }
138
-
139
- if result.first['status'] != 'success'
140
- raise "upload file failed\n======\n#{result}" if opts[:expect_failures] != true
141
-
142
- result_obj[:exit_code] = 255
143
- result_obj[:stderr] = result.first['result']['_error']['msg']
144
- end
145
-
146
- result = OpenStruct.new(exit_code: result_obj[:exit_code],
147
- stdout: result_obj[:stdout],
148
- stderr: result_obj[:stderr])
149
- yield result if block_given?
150
- result
151
- end
152
-
153
- # Runs a task against the target system.
154
- #
155
- # @param task_name [String] The name of the task to run.
156
- # @param params [Hash] key : value pairs to be passed to the task.
157
- # @param opts [Hash] Alters the behaviour of the command. Valid options are :expect_failures [Boolean] doesnt return an exit code of non-zero if the command failed.
158
- # @return [Object] A result object from the task.The values available are stdout, stderr and result.
159
- def run_bolt_task(task_name, params = {}, opts = {})
160
- config_data = { 'modulepath' => File.join(Dir.pwd, 'spec', 'fixtures', 'modules') }
161
- target_node_name = ENV['TARGET_HOST'] if target_node_name.nil?
162
- inventory_hash = if target_node_name.nil? || target_node_name == 'localhost'
163
- nil
164
- else
165
- inventory_hash_from_inventory_file
166
- end
167
-
168
- result = run_task(task_name, target_node_name, params, config: config_data, inventory: inventory_hash)
169
- result_obj = {
170
- exit_code: 0,
171
- stdout: nil,
172
- stderr: nil,
173
- result: result.first['result'],
174
- }
175
-
176
- if result.first['status'] == 'success'
177
- # stdout returns unstructured data if structured data is not available
178
- result_obj[:stdout] = if result.first['result']['_output'].nil?
179
- result.first['result'].to_s
180
- else
181
- result.first['result']['_output']
182
- end
183
-
184
- else
185
- raise "task failed\n`#{task_name}`\n======\n#{result}" if opts[:expect_failures] != true
186
-
187
- result_obj[:exit_code] = result.first['result']['_error']['details'].fetch('exitcode', 255)
188
- result_obj[:stderr] = result.first['result']['_error']['msg']
189
- end
190
-
191
- result = OpenStruct.new(exit_code: result_obj[:exit_code],
192
- stdout: result_obj[:stdout],
193
- stderr: result_obj[:stderr],
194
- result: result_obj[:result])
195
- yield result if block_given?
196
- result
197
- end
198
-
199
- # Runs a script against the target system.
200
- #
201
- # @param script [String] The path to the script on the source machine
202
- # @param opts [Hash] Alters the behaviour of the command. Valid options are :expect_failures [Boolean] doesnt return an exit code of non-zero if the command failed.
203
- # @param arguments [Array] Array of arguments to pass to script on runtime
204
- # @yieldreturn [Block] this method will yield to a block of code passed by the caller; this can be used for additional validation, etc.
205
- # @return [Object] A result object from the script run.
206
- def bolt_run_script(script, opts = {}, arguments: [])
207
- target_node_name = ENV['TARGET_HOST'] if target_node_name.nil?
208
- inventory_hash = if target_node_name.nil? || target_node_name == 'localhost'
209
- nil
210
- else
211
- inventory_hash_from_inventory_file
212
- end
213
-
214
- result = run_script(script, target_node_name, arguments, options: opts, config: nil, inventory: inventory_hash)
215
-
216
- raise "script run failed\n`#{script}`\n======\n#{result}" if result.first['result']['exit_code'] != 0 && opts[:expect_failures] != true
217
-
218
- result = OpenStruct.new(exit_code: result.first['result']['exit_code'],
219
- stdout: result.first['result']['stdout'],
220
- stderr: result.first['result']['stderr'])
221
- yield result if block_given?
222
- result
223
- end
224
- end
1
+ # frozen_string_literal: true
2
+
3
+ # helper functions for running puppet commands. They execute a target system specified by ENV['TARGET_HOST']
4
+ # heavily uses functions from here https://github.com/puppetlabs/bolt/blob/master/developer-docs/bolt_spec-run.md
5
+ module PuppetLitmus::Serverspec
6
+ # Applies a manifest twice. First checking for errors. Secondly to make sure no changes occur.
7
+ #
8
+ # @param manifest [String] puppet manifest code to be applied.
9
+ # @return [Boolean] The result of the 2 apply manifests.
10
+ def idempotent_apply(manifest)
11
+ manifest_file_location = create_manifest_file(manifest)
12
+ apply_manifest(nil, catch_failures: true, manifest_file_location: manifest_file_location)
13
+ apply_manifest(nil, catch_changes: true, manifest_file_location: manifest_file_location)
14
+ end
15
+
16
+ # rubocop:disable Layout/TrailingWhitespace
17
+
18
+ # Applies a manifest. returning the result of that apply. Mimics the apply_manifest from beaker
19
+ #
20
+ # When you set the environment variable RSPEC_DEBUG, the output of your
21
+ # puppet run will be displayed. If you have set the :debug flag, you will see the
22
+ # full debug log. If you have **not** set the :debug flag, it will display the regular
23
+ # output.
24
+ #
25
+ # @param manifest [String] puppet manifest code to be applied.
26
+ # @param opts [Hash] Alters the behaviour of the command. Valid options are:
27
+ # :catch_changes [Boolean] exit status of 1 if there were changes.
28
+ # :expect_failures [Boolean] doesnt return an exit code of non-zero if the apply failed.
29
+ # :manifest_file_location [Path] The place on the target system.
30
+ # :prefix_command [String] prefixes the puppet apply command; eg "export LANGUAGE='ja'".
31
+ # :debug [Boolean] run puppet apply with the debug flag.
32
+ # :noop [Boolean] run puppet apply with the noop flag.
33
+ # @yieldreturn [Block] this method will yield to a block of code passed by the caller; this can be used for additional validation, etc.
34
+ # @return [Object] A result object from the apply.
35
+ def apply_manifest(manifest, opts = {})
36
+ # rubocop:enable Layout/TrailingWhitespace
37
+ target_node_name = ENV['TARGET_HOST']
38
+ raise 'manifest and manifest_file_location in the opts hash are mutually exclusive arguments, pick one' if !manifest.nil? && !opts[:manifest_file_location].nil?
39
+ raise 'please pass a manifest or the manifest_file_location in the opts hash' if (manifest.nil? || manifest == '') && opts[:manifest_file_location].nil?
40
+
41
+ manifest_file_location = opts[:manifest_file_location] || create_manifest_file(manifest)
42
+ inventory_hash = if target_node_name.nil? || target_node_name == 'localhost'
43
+ nil
44
+ else
45
+ inventory_hash_from_inventory_file
46
+ end
47
+ command_to_run = "#{opts[:prefix_command]} puppet apply #{manifest_file_location}"
48
+ command_to_run += " --modulepath #{Dir.pwd}/spec/fixtures/modules" if target_node_name.nil? || target_node_name == 'localhost'
49
+ command_to_run += ' --detailed-exitcodes' if !opts[:catch_changes].nil? && (opts[:catch_changes] == true)
50
+ command_to_run += ' --debug' if !opts[:debug].nil? && (opts[:debug] == true)
51
+ command_to_run += ' --noop' if !opts[:noop].nil? && (opts[:noop] == true)
52
+ result = run_command(command_to_run, target_node_name, config: nil, inventory: inventory_hash)
53
+
54
+ raise "apply manifest failed\n`#{command_to_run}`\n======\n#{result}" if result.first['result']['exit_code'] != 0 && opts[:expect_failures] != true
55
+
56
+ result = OpenStruct.new(exit_code: result.first['result']['exit_code'],
57
+ stdout: result.first['result']['stdout'],
58
+ stderr: result.first['result']['stderr'])
59
+ yield result if block_given?
60
+ if ENV['RSPEC_DEBUG']
61
+ puts "apply manifest succeded\n #{command_to_run}\n======\nwith status #{result.exit_code}"
62
+ puts result.stderr
63
+ puts result.stdout
64
+ end
65
+ result
66
+ end
67
+
68
+ # Creates a manifest file locally in a temp location, if its a remote target copy it to there.
69
+ #
70
+ # @param manifest [String] puppet manifest code.
71
+ # @return [String] The path to the location of the manifest.
72
+ def create_manifest_file(manifest)
73
+ require 'tmpdir'
74
+ target_node_name = ENV['TARGET_HOST']
75
+ tmp_filename = File.join(Dir.tmpdir, "manifest_#{Time.now.strftime('%Y%m%d')}_#{Process.pid}_#{rand(0x100000000).to_s(36)}.pp")
76
+ manifest_file = File.open(tmp_filename, 'w')
77
+ manifest_file.write(manifest)
78
+ manifest_file.close
79
+ if target_node_name.nil? || target_node_name == 'localhost'
80
+ # no need to transfer
81
+ manifest_file_location = manifest_file.path
82
+ else
83
+ # transfer to TARGET_HOST
84
+ inventory_hash = inventory_hash_from_inventory_file
85
+ manifest_file_location = "/tmp/#{File.basename(manifest_file)}"
86
+ result = upload_file(manifest_file.path, manifest_file_location, target_node_name, options: {}, config: nil, inventory: inventory_hash)
87
+ raise result.first['result'].to_s unless result.first['status'] == 'success'
88
+ end
89
+ manifest_file_location
90
+ end
91
+
92
+ # Runs a command against the target system
93
+ #
94
+ # @param command_to_run [String] The command to execute.
95
+ # @param opts [Hash] Alters the behaviour of the command. Valid options are :expect_failures [Boolean] doesnt return an exit code of non-zero if the command failed.
96
+ # @yieldreturn [Block] this method will yield to a block of code passed by the caller; this can be used for additional validation, etc.
97
+ # @return [Object] A result object from the command.
98
+ def run_shell(command_to_run, opts = {})
99
+ target_node_name = ENV['TARGET_HOST']
100
+ inventory_hash = if target_node_name.nil? || target_node_name == 'localhost'
101
+ nil
102
+ else
103
+ inventory_hash_from_inventory_file
104
+ end
105
+ result = run_command(command_to_run, target_node_name, config: nil, inventory: inventory_hash)
106
+ raise "shell failed\n`#{command_to_run}`\n======\n#{result}" if result.first['result']['exit_code'] != 0 && opts[:expect_failures] != true
107
+
108
+ result = OpenStruct.new(exit_code: result.first['result']['exit_code'],
109
+ stdout: result.first['result']['stdout'],
110
+ stderr: result.first['result']['stderr'])
111
+ yield result if block_given?
112
+ result
113
+ end
114
+
115
+ # Copies file to the target, using its respective transport
116
+ #
117
+ # @param source [String] place locally, to copy from.
118
+ # @param destination [String] place on the target, to copy to.
119
+ # @param opts [Hash] Alters the behaviour of the command. Valid options are :expect_failures [Boolean] doesnt return an exit code of non-zero if the command failed.
120
+ # @yieldreturn [Block] this method will yield to a block of code passed by the caller; this can be used for additional validation, etc.
121
+ # @return [Object] A result object from the command.
122
+ def bolt_upload_file(source, destination, opts = {}, options = {})
123
+ target_node_name = ENV['TARGET_HOST'] if target_node_name.nil?
124
+ inventory_hash = if target_node_name.nil? || target_node_name == 'localhost'
125
+ nil
126
+ else
127
+ inventory_hash_from_inventory_file
128
+ end
129
+
130
+ result = upload_file(source, destination, target_node_name, options: options, config: nil, inventory: inventory_hash)
131
+
132
+ result_obj = {
133
+ exit_code: 0,
134
+ stdout: result.first['result']['_output'],
135
+ stderr: nil,
136
+ result: result.first['result'],
137
+ }
138
+
139
+ if result.first['status'] != 'success'
140
+ raise "upload file failed\n======\n#{result}" if opts[:expect_failures] != true
141
+
142
+ result_obj[:exit_code] = 255
143
+ result_obj[:stderr] = result.first['result']['_error']['msg']
144
+ end
145
+
146
+ result = OpenStruct.new(exit_code: result_obj[:exit_code],
147
+ stdout: result_obj[:stdout],
148
+ stderr: result_obj[:stderr])
149
+ yield result if block_given?
150
+ result
151
+ end
152
+
153
+ # Runs a task against the target system.
154
+ #
155
+ # @param task_name [String] The name of the task to run.
156
+ # @param params [Hash] key : value pairs to be passed to the task.
157
+ # @param opts [Hash] Alters the behaviour of the command. Valid options are :expect_failures [Boolean] doesnt return an exit code of non-zero if the command failed.
158
+ # @return [Object] A result object from the task.The values available are stdout, stderr and result.
159
+ def run_bolt_task(task_name, params = {}, opts = {})
160
+ config_data = { 'modulepath' => File.join(Dir.pwd, 'spec', 'fixtures', 'modules') }
161
+ target_node_name = ENV['TARGET_HOST'] if target_node_name.nil?
162
+ inventory_hash = if target_node_name.nil? || target_node_name == 'localhost'
163
+ nil
164
+ else
165
+ inventory_hash_from_inventory_file
166
+ end
167
+
168
+ result = run_task(task_name, target_node_name, params, config: config_data, inventory: inventory_hash)
169
+ result_obj = {
170
+ exit_code: 0,
171
+ stdout: nil,
172
+ stderr: nil,
173
+ result: result.first['result'],
174
+ }
175
+
176
+ if result.first['status'] == 'success'
177
+ # stdout returns unstructured data if structured data is not available
178
+ result_obj[:stdout] = if result.first['result']['_output'].nil?
179
+ result.first['result'].to_s
180
+ else
181
+ result.first['result']['_output']
182
+ end
183
+
184
+ else
185
+ raise "task failed\n`#{task_name}`\n======\n#{result}" if opts[:expect_failures] != true
186
+
187
+ result_obj[:exit_code] = if result.first['result']['_error']['details'].nil?
188
+ 255
189
+ else
190
+ result.first['result']['_error']['details'].fetch('exitcode', 255)
191
+ end
192
+ result_obj[:stderr] = result.first['result']['_error']['msg']
193
+ end
194
+
195
+ result = OpenStruct.new(exit_code: result_obj[:exit_code],
196
+ stdout: result_obj[:stdout],
197
+ stderr: result_obj[:stderr],
198
+ result: result_obj[:result])
199
+ yield result if block_given?
200
+ result
201
+ end
202
+
203
+ # Runs a script against the target system.
204
+ #
205
+ # @param script [String] The path to the script on the source machine
206
+ # @param opts [Hash] Alters the behaviour of the command. Valid options are :expect_failures [Boolean] doesnt return an exit code of non-zero if the command failed.
207
+ # @param arguments [Array] Array of arguments to pass to script on runtime
208
+ # @yieldreturn [Block] this method will yield to a block of code passed by the caller; this can be used for additional validation, etc.
209
+ # @return [Object] A result object from the script run.
210
+ def bolt_run_script(script, opts = {}, arguments: [])
211
+ target_node_name = ENV['TARGET_HOST'] if target_node_name.nil?
212
+ inventory_hash = if target_node_name.nil? || target_node_name == 'localhost'
213
+ nil
214
+ else
215
+ inventory_hash_from_inventory_file
216
+ end
217
+
218
+ result = run_script(script, target_node_name, arguments, options: opts, config: nil, inventory: inventory_hash)
219
+
220
+ raise "script run failed\n`#{script}`\n======\n#{result}" if result.first['result']['exit_code'] != 0 && opts[:expect_failures] != true
221
+
222
+ result = OpenStruct.new(exit_code: result.first['result']['exit_code'],
223
+ stdout: result.first['result']['stdout'],
224
+ stderr: result.first['result']['stderr'])
225
+ yield result if block_given?
226
+ result
227
+ end
228
+ end
@@ -1,6 +1,6 @@
1
- # frozen_string_literal: true
2
-
3
- # version of this gem
4
- module PuppetLitmus
5
- VERSION ||= '0.8.0'
6
- end
1
+ # frozen_string_literal: true
2
+
3
+ # version of this gem
4
+ module PuppetLitmus
5
+ VERSION ||= '0.8.1'
6
+ end