puppet_litmus 0.7.3 → 0.8.0

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