openbolt 5.0.0.pre.rc2 → 5.1.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.
Files changed (86) hide show
  1. checksums.yaml +4 -4
  2. data/Puppetfile +18 -12
  3. data/bolt-modules/boltlib/lib/puppet/functions/apply_prep.rb +5 -3
  4. data/bolt-modules/boltlib/lib/puppet/functions/download_file.rb +1 -0
  5. data/bolt-modules/boltlib/lib/puppet/functions/get_resources.rb +2 -0
  6. data/bolt-modules/boltlib/lib/puppet/functions/puppetdb_command.rb +1 -1
  7. data/bolt-modules/boltlib/lib/puppet/functions/run_container.rb +2 -2
  8. data/bolt-modules/boltlib/lib/puppet/functions/run_script.rb +1 -0
  9. data/bolt-modules/boltlib/lib/puppet/functions/set_resources.rb +2 -2
  10. data/bolt-modules/boltlib/lib/puppet/functions/upload_file.rb +1 -0
  11. data/bolt-modules/boltlib/lib/puppet/functions/wait.rb +1 -1
  12. data/bolt-modules/boltlib/lib/puppet/functions/wait_until_available.rb +1 -0
  13. data/bolt-modules/ctrl/lib/puppet/functions/ctrl/do_until.rb +1 -0
  14. data/lib/bolt/analytics.rb +1 -1
  15. data/lib/bolt/application.rb +17 -22
  16. data/lib/bolt/applicator.rb +4 -0
  17. data/lib/bolt/bolt_option_parser.rb +10 -8
  18. data/lib/bolt/cli.rb +7 -6
  19. data/lib/bolt/config/options.rb +59 -67
  20. data/lib/bolt/config/transport/base.rb +1 -0
  21. data/lib/bolt/config/transport/options.rb +59 -59
  22. data/lib/bolt/config.rb +8 -6
  23. data/lib/bolt/executor.rb +9 -24
  24. data/lib/bolt/fiber_executor.rb +3 -1
  25. data/lib/bolt/inventory/group.rb +3 -0
  26. data/lib/bolt/inventory/inventory.rb +2 -0
  27. data/lib/bolt/inventory/options.rb +7 -7
  28. data/lib/bolt/inventory/target.rb +3 -2
  29. data/lib/bolt/inventory.rb +1 -0
  30. data/lib/bolt/logger.rb +2 -0
  31. data/lib/bolt/module.rb +1 -0
  32. data/lib/bolt/module_installer/puppetfile.rb +4 -4
  33. data/lib/bolt/module_installer/resolver.rb +2 -2
  34. data/lib/bolt/module_installer/specs/forge_spec.rb +4 -4
  35. data/lib/bolt/module_installer/specs/git_spec.rb +6 -6
  36. data/lib/bolt/module_installer/specs/id/gitclone.rb +1 -0
  37. data/lib/bolt/module_installer/specs/id/github.rb +2 -1
  38. data/lib/bolt/module_installer/specs/id/gitlab.rb +2 -1
  39. data/lib/bolt/module_installer.rb +3 -1
  40. data/lib/bolt/outputter/human.rb +9 -4
  41. data/lib/bolt/outputter/rainbow.rb +1 -0
  42. data/lib/bolt/pal/yaml_plan/parameter.rb +2 -2
  43. data/lib/bolt/pal/yaml_plan/step/resources.rb +1 -1
  44. data/lib/bolt/pal.rb +4 -1
  45. data/lib/bolt/plan_creator.rb +5 -4
  46. data/lib/bolt/plugin/cache.rb +2 -0
  47. data/lib/bolt/plugin/module.rb +7 -0
  48. data/lib/bolt/plugin/puppet_connect_data.rb +1 -0
  49. data/lib/bolt/plugin/task.rb +3 -0
  50. data/lib/bolt/plugin.rb +4 -0
  51. data/lib/bolt/project.rb +3 -3
  52. data/lib/bolt/project_manager/config_migrator.rb +3 -3
  53. data/lib/bolt/project_manager/inventory_migrator.rb +1 -1
  54. data/lib/bolt/project_manager/module_migrator.rb +7 -6
  55. data/lib/bolt/project_manager.rb +11 -11
  56. data/lib/bolt/puppetdb/config.rb +4 -0
  57. data/lib/bolt/puppetdb/instance.rb +1 -0
  58. data/lib/bolt/rerun.rb +1 -0
  59. data/lib/bolt/resource_instance.rb +1 -1
  60. data/lib/bolt/result.rb +2 -1
  61. data/lib/bolt/shell/bash.rb +2 -1
  62. data/lib/bolt/shell/powershell.rb +4 -3
  63. data/lib/bolt/shell.rb +1 -1
  64. data/lib/bolt/task/run.rb +1 -0
  65. data/lib/bolt/task.rb +3 -0
  66. data/lib/bolt/transport/docker/connection.rb +2 -0
  67. data/lib/bolt/transport/jail/connection.rb +2 -0
  68. data/lib/bolt/transport/lxd/connection.rb +2 -0
  69. data/lib/bolt/transport/lxd.rb +1 -1
  70. data/lib/bolt/transport/podman/connection.rb +2 -0
  71. data/lib/bolt/transport/remote.rb +1 -0
  72. data/lib/bolt/transport/ssh/connection.rb +1 -1
  73. data/lib/bolt/transport/winrm/connection.rb +4 -3
  74. data/lib/bolt/util/format.rb +1 -0
  75. data/lib/bolt/util.rb +7 -4
  76. data/lib/bolt/validator.rb +1 -1
  77. data/lib/bolt/version.rb +1 -1
  78. data/lib/bolt_spec/plans/action_stubs.rb +5 -0
  79. data/lib/bolt_spec/plans/mock_executor.rb +2 -4
  80. data/libexec/apply_catalog.rb +2 -1
  81. data/libexec/custom_facts.rb +1 -1
  82. data/libexec/query_resources.rb +1 -1
  83. metadata +34 -51
  84. data/lib/bolt/config/transport/orch.rb +0 -41
  85. data/lib/bolt/transport/orch/connection.rb +0 -111
  86. data/lib/bolt/transport/orch.rb +0 -271
@@ -1,271 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'base64'
4
- require 'find'
5
- require 'json'
6
- require 'pathname'
7
- require_relative '../../bolt/transport/base'
8
- require_relative 'orch/connection'
9
-
10
- module Bolt
11
- module Transport
12
- class Orch < Base
13
- BOLT_COMMAND_TASK = Struct.new(:name).new('bolt_shim::command').freeze
14
- BOLT_SCRIPT_TASK = Struct.new(:name).new('bolt_shim::script').freeze
15
- BOLT_UPLOAD_TASK = Struct.new(:name).new('bolt_shim::upload').freeze
16
-
17
- attr_writer :plan_context
18
-
19
- def provided_features
20
- ['puppet-agent']
21
- end
22
-
23
- def initialize(*args)
24
- # lazy-load expensive gem code
25
- require 'orchestrator_client'
26
-
27
- @connections = {}
28
- super
29
- end
30
-
31
- def finish_plan(result)
32
- if result.is_a? Bolt::PlanResult
33
- @connections.each_value do |conn|
34
- conn.finish_plan(result)
35
- rescue StandardError => e
36
- @logger.trace("Failed to finish plan on #{conn.key}: #{e.message}")
37
- end
38
- end
39
- end
40
-
41
- # It's safe to create connections here for now because the
42
- # batches/threads are per connection.
43
- def get_connection(conn_opts)
44
- key = Connection.get_key(conn_opts)
45
- unless (conn = @connections[key])
46
- conn = @connections[key] = Connection.new(conn_opts, @plan_context, logger)
47
- end
48
- conn
49
- end
50
-
51
- def process_run_results(targets, results, task_name, position = [])
52
- targets_by_name = Hash[targets.map { |t| t.host || t.name }.zip(targets)]
53
- results.map do |node_result|
54
- target = targets_by_name[node_result['name']]
55
- state = node_result['state']
56
- result = node_result['result']
57
-
58
- # If it's finished or already has a proper error simply pass it to the
59
- # the result otherwise make sure an error is generated
60
- if state == 'finished' || (result && result['_error'])
61
- if result['_error']
62
- unless result['_error'].is_a?(Hash)
63
- result['_error'] = { 'kind' => 'puppetlabs.tasks/task-error',
64
- 'issue_code' => 'TASK_ERROR',
65
- 'msg' => result['_error'],
66
- 'details' => {} }
67
- end
68
-
69
- result['_error']['details'] ||= {}
70
- unless result['_error']['details'].is_a?(Hash)
71
- deets = result['_error']['details']
72
- result['_error']['details'] = { 'msg' => deets }
73
- end
74
- file_line = %w[file line].zip(position).to_h.compact
75
- result['_error']['details'].merge!(file_line) unless result['_error']['details']['file']
76
- end
77
-
78
- Bolt::Result.new(target, value: result, action: 'task', object: task_name)
79
- elsif state == 'skipped'
80
- details = %w[file line].zip(position).to_h.compact
81
- Bolt::Result.new(
82
- target,
83
- value: { '_error' => {
84
- 'kind' => 'puppetlabs.tasks/skipped-node',
85
- 'msg' => "Target #{target.safe_name} was skipped",
86
- 'details' => details
87
- } },
88
- action: 'task', object: task_name
89
- )
90
- else
91
- # Make a generic error with a unkown exit_code
92
- Bolt::Result.for_task(target, result.to_json, '', 'unknown', task_name, position)
93
- end
94
- end
95
- end
96
-
97
- def batch_command(targets, command, options = {}, position = [], &callback)
98
- if options[:env_vars] && !options[:env_vars].empty?
99
- raise NotImplementedError, "pcp transport does not support setting environment variables"
100
- end
101
-
102
- params = {
103
- 'command' => command
104
- }
105
- results = run_task_job(targets,
106
- BOLT_COMMAND_TASK,
107
- params,
108
- options,
109
- position,
110
- &callback)
111
- callback ||= proc {}
112
- results.map! { |result| unwrap_bolt_result(result.target, result, 'command', command) }
113
- results.each do |result|
114
- callback.call(type: :node_result, result: result)
115
- end
116
- end
117
-
118
- def batch_script(targets, script, arguments, options = {}, position = [], &callback)
119
- if options[:env_vars] && !options[:env_vars].empty?
120
- raise NotImplementedError, "pcp transport does not support setting environment variables"
121
- end
122
-
123
- content = File.open(script, &:read)
124
- content = Base64.encode64(content)
125
- params = {
126
- 'content' => content,
127
- 'arguments' => arguments,
128
- 'name' => Pathname(script).basename.to_s
129
- }
130
- callback ||= proc {}
131
- results = run_task_job(targets, BOLT_SCRIPT_TASK, params, options, position, &callback)
132
- results.map! { |result| unwrap_bolt_result(result.target, result, 'script', script) }
133
- results.each do |result|
134
- callback.call(type: :node_result, result: result)
135
- end
136
- end
137
-
138
- def pack(directory)
139
- # lazy-load expensive gem code
140
- require 'minitar'
141
- require 'zlib'
142
-
143
- start_time = Time.now
144
- io = StringIO.new
145
- output = Minitar::Output.new(Zlib::GzipWriter.new(io))
146
- Find.find(directory) do |file|
147
- next unless File.file?(file)
148
-
149
- tar_path = Pathname.new(file).relative_path_from(Pathname.new(directory))
150
- @logger.trace("Packing #{file} to #{tar_path}")
151
- stat = File.stat(file)
152
- content = File.binread(file)
153
- output.tar.add_file_simple(
154
- tar_path.to_s,
155
- data: content,
156
- size: content.size,
157
- mode: stat.mode & 0o777,
158
- mtime: stat.mtime
159
- )
160
- end
161
-
162
- duration = Time.now - start_time
163
- @logger.trace("Packed upload in #{duration * 1000} ms")
164
-
165
- output.close
166
- io.string
167
- ensure
168
- # Closes both tar and sgz.
169
- output&.close
170
- end
171
-
172
- def batch_upload(targets, source, destination, options = {}, position = [], &callback)
173
- stat = File.stat(source)
174
- content = if stat.directory?
175
- pack(source)
176
- else
177
- File.open(source, &:read)
178
- end
179
- content = Base64.encode64(content)
180
- mode = File.stat(source).mode
181
- params = {
182
- 'path' => destination,
183
- 'content' => content,
184
- 'mode' => mode,
185
- 'directory' => stat.directory?
186
- }
187
- callback ||= proc {}
188
- results = run_task_job(targets, BOLT_UPLOAD_TASK, params, options, position, &callback)
189
- results.map! do |result|
190
- if result.error_hash
191
- result
192
- else
193
- Bolt::Result.for_upload(result.target, source, destination)
194
- end
195
- end
196
- results.each do |result|
197
- callback&.call(type: :node_result, result: result)
198
- end
199
- end
200
-
201
- def batch_download(targets, *_args)
202
- error = {
203
- 'kind' => 'bolt/not-supported-error',
204
- 'msg' => 'pcp transport does not support downloading files',
205
- 'details' => {}
206
- }
207
-
208
- targets.map do |target|
209
- Bolt::Result.new(target, error: error, action: 'download')
210
- end
211
- end
212
-
213
- def batches(targets)
214
- targets.group_by { |target| Connection.get_key(target.options) }.values
215
- end
216
-
217
- def run_task_job(targets, task, arguments, options, position)
218
- targets.each do |target|
219
- yield(type: :node_start, target: target) if block_given?
220
- end
221
-
222
- begin
223
- # unpack any Sensitive data
224
- arguments = unwrap_sensitive_args(arguments)
225
- results = get_connection(targets.first.options).run_task(targets, task, arguments, options)
226
-
227
- process_run_results(targets, results, task.name, position)
228
- rescue OrchestratorClient::ApiError => e
229
- targets.map do |target|
230
- Bolt::Result.new(target, error: e.data)
231
- end
232
- rescue StandardError => e
233
- targets.map do |target|
234
- Bolt::Result.from_exception(target, e, action: 'task')
235
- end
236
- end
237
- end
238
-
239
- def batch_task(targets, task, arguments, options = {}, position = [], &callback)
240
- callback ||= proc {}
241
- results = run_task_job(targets, task, arguments, options, position, &callback)
242
- results.each do |result|
243
- callback.call(type: :node_result, result: result)
244
- end
245
- end
246
-
247
- def batch_task_with(_targets, _task, _target_mapping, _options = {}, _position = [])
248
- raise NotImplementedError, "pcp transport does not support run_task_with()"
249
- end
250
-
251
- def batch_connected?(targets)
252
- resp = get_connection(targets.first.options).query_inventory(targets)
253
- resp['items'].all? { |node| node['connected'] }
254
- end
255
-
256
- # run_task generates a result that makes sense for a generic task which
257
- # needs to be unwrapped to extract stdout/stderr/exitcode.
258
- #
259
- def unwrap_bolt_result(target, result, action, obj)
260
- if result.error_hash
261
- # something went wrong return the failure
262
- return result
263
- end
264
-
265
- # If we get here, there's no error so we don't need the file or line
266
- # number
267
- Bolt::Result.for_command(target, result.value, action, obj, [])
268
- end
269
- end
270
- end
271
- end