puppet_litmus 0.7.3 → 0.8.0

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