bolt 3.26.2 → 3.27.2

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of bolt might be problematic. Click here for more details.

checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7fe078a4da4d1447d8214edee250d80c0132b2a8913bd16f24016315a46ff215
4
- data.tar.gz: 89e27a1ed523fd9aca8d80ea94c53071bde9f0b1af947768880b8055dc47f27b
3
+ metadata.gz: 18244996224b24b6a1a2395a54e97b11389d5b106a18dc8e2ef97563d3a08134
4
+ data.tar.gz: 3d0e5384b7ce5a5b73a082e4d8529defa179737c25ee0166e7be39de0bf7f7c8
5
5
  SHA512:
6
- metadata.gz: 8955b0ea1e737618918839b34c9b6049f884c1983e3ebb0f4ee50c4ea85007fade6dabfbf21ae34f201bf0eabb9497bcd5a33fbe3c833ada430ccced628b4477
7
- data.tar.gz: 8b1e6f84326c1e5adeb988cdadac80b2bb49b71ed2ce24dc0b0c881970e88aadbede4eaf5f3479b8f2434a9a4a221128e643d145ecffc47b1075d566ef741cd3
6
+ metadata.gz: 35ae42d1527062768eadc54e4e0864d015a57e61d5ea9319e6ffd835407bd34a7646f6c632c0911862b37a2c010b5d3921e6badb7bda8219bc5334c3b56b6844
7
+ data.tar.gz: 67109b48c5661ac51ecb9807ca61355006e34165ad287cea54d3b2dcb4615cdd038659842ca1f0c8a98a6e654a747fcfe0aabf030dabb3974173acbadc996a72
@@ -256,7 +256,7 @@ module Bolt
256
256
  futures = targets.map do |target|
257
257
  Concurrent::Future.execute(executor: @pool) do
258
258
  Thread.current[:name] ||= Thread.current.name
259
- @executor.with_node_logging("Compiling manifest block", [target]) do
259
+ @executor.with_node_logging("Compiling manifest block", [target], :trace) do
260
260
  compile(target, scope)
261
261
  end
262
262
  end
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require_relative '../../bolt/config/transport/docker'
4
+ require_relative '../../bolt/config/transport/jail'
4
5
  require_relative '../../bolt/config/transport/local'
5
6
  require_relative '../../bolt/config/transport/lxd'
6
7
  require_relative '../../bolt/config/transport/orch'
@@ -16,6 +17,7 @@ module Bolt
16
17
  # gets passed along to the inventory.
17
18
  TRANSPORT_CONFIG = {
18
19
  'docker' => Bolt::Config::Transport::Docker,
20
+ 'jail' => Bolt::Config::Transport::Jail,
19
21
  'local' => Bolt::Config::Transport::Local,
20
22
  'lxd' => Bolt::Config::Transport::LXD,
21
23
  'pcp' => Bolt::Config::Transport::Orch,
@@ -550,6 +552,12 @@ module Bolt
550
552
  _plugin: true,
551
553
  _example: { "cleanup" => false, "service-url" => "https://docker.example.com" }
552
554
  },
555
+ "jail" => {
556
+ description: "A map of configuration options for the jail transport.",
557
+ type: Hash,
558
+ _plugin: true,
559
+ _example: { cleanup: false }
560
+ },
553
561
  "local" => {
554
562
  description: "A map of configuration options for the local transport. The set of available options is "\
555
563
  "platform dependent.",
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../../../bolt/error'
4
+ require_relative '../../../bolt/config/transport/base'
5
+
6
+ module Bolt
7
+ class Config
8
+ module Transport
9
+ class Jail < Base
10
+ OPTIONS = %w[
11
+ cleanup
12
+ host
13
+ interpreters
14
+ shell-command
15
+ tmpdir
16
+ user
17
+ ].concat(RUN_AS_OPTIONS).sort.freeze
18
+
19
+ DEFAULTS = {
20
+ 'cleanup' => true
21
+ }.freeze
22
+
23
+ private def validate
24
+ super
25
+
26
+ if @config['interpreters']
27
+ @config['interpreters'] = normalize_interpreters(@config['interpreters'])
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
data/lib/bolt/executor.rb CHANGED
@@ -14,6 +14,7 @@ require_relative '../bolt/result'
14
14
  require_relative '../bolt/result_set'
15
15
  # Load transports
16
16
  require_relative '../bolt/transport/docker'
17
+ require_relative '../bolt/transport/jail'
17
18
  require_relative '../bolt/transport/local'
18
19
  require_relative '../bolt/transport/lxd'
19
20
  require_relative '../bolt/transport/orch'
@@ -25,6 +26,7 @@ require_relative '../bolt/transport/winrm'
25
26
  module Bolt
26
27
  TRANSPORTS = {
27
28
  docker: Bolt::Transport::Docker,
29
+ jail: Bolt::Transport::Jail,
28
30
  local: Bolt::Transport::Local,
29
31
  lxd: Bolt::Transport::LXD,
30
32
  pcp: Bolt::Transport::Orch,
@@ -356,7 +356,7 @@ module Bolt
356
356
  if defined? conn.add_env_vars
357
357
  conn.add_env_vars(options[:environment])
358
358
  else
359
- env_decl = options[:environment].map do |env, val|
359
+ env_decl = '/usr/bin/env ' + options[:environment].map do |env, val|
360
360
  "#{env}=#{Shellwords.shellescape(val)}"
361
361
  end.join(' ')
362
362
  end
@@ -0,0 +1,81 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'logging'
4
+ require_relative '../../../bolt/node/errors'
5
+
6
+ module Bolt
7
+ module Transport
8
+ class Jail < Simple
9
+ class Connection
10
+ attr_reader :user, :target
11
+
12
+ def initialize(target)
13
+ raise Bolt::ValidationError, "Target #{target.safe_name} does not have a host" unless target.host
14
+ @target = target
15
+ @user = @target.user || ENV['USER'] || Etc.getlogin
16
+ @logger = Bolt::Logger.logger(target.safe_name)
17
+ @jail_info = {}
18
+ @logger.trace("Initializing jail connection to #{target.safe_name}")
19
+ end
20
+
21
+ def shell
22
+ @shell ||= Bolt::Shell::Bash.new(target, self)
23
+ end
24
+
25
+ def reset_cwd?
26
+ true
27
+ end
28
+
29
+ def jail_id
30
+ @jail_info['jid'].to_s
31
+ end
32
+
33
+ def jail_path
34
+ @jail_info['path']
35
+ end
36
+
37
+ def connect
38
+ output = JSON.parse(`jls --libxo=json`)
39
+ @jail_info = output['jail-information']['jail'].select { |jail| jail['hostname'] == target.host }.first
40
+ raise "Could not find a jail with name matching #{target.host}" if @jail_info.nil?
41
+ @logger.trace { "Opened session" }
42
+ true
43
+ rescue StandardError => e
44
+ raise Bolt::Node::ConnectError.new(
45
+ "Failed to connect to #{target.safe_name}: #{e.message}",
46
+ 'CONNECT_ERROR'
47
+ )
48
+ end
49
+
50
+ def execute(command)
51
+ args = ['-lU', @user]
52
+
53
+ jail_command = %w[jexec] + args + [jail_id] + Shellwords.split(command)
54
+ @logger.trace { "Executing #{jail_command.join(' ')}" }
55
+
56
+ Open3.popen3({}, *jail_command)
57
+ rescue StandardError
58
+ @logger.trace { "Command aborted" }
59
+ raise
60
+ end
61
+
62
+ def upload_file(source, destination)
63
+ @logger.trace { "Uploading #{source} to #{destination}" }
64
+ jail_destination = File.join(jail_path, destination)
65
+ FileUtils.cp(source, jail_destination)
66
+ rescue StandardError => e
67
+ raise Bolt::Node::FileError.new(e.message, 'WRITE_ERROR')
68
+ end
69
+
70
+ def download_file(source, destination, _download)
71
+ @logger.trace { "Downloading #{source} to #{destination}" }
72
+ jail_source = File.join(jail_path, source)
73
+ FileUtils.mkdir_p(destination)
74
+ FileUtils.cp(jail_source, destination)
75
+ rescue StandardError => e
76
+ raise Bolt::Node::FileError.new(e.message, 'WRITE_ERROR')
77
+ end
78
+ end
79
+ end
80
+ end
81
+ end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../../bolt/transport/simple'
4
+
5
+ module Bolt
6
+ module Transport
7
+ class Jail < Simple
8
+ def provided_features
9
+ ['shell']
10
+ end
11
+
12
+ def with_connection(target)
13
+ conn = Connection.new(target)
14
+ conn.connect
15
+ yield conn
16
+ end
17
+ end
18
+ end
19
+ end
20
+
21
+ require_relative 'jail/connection'
data/lib/bolt/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Bolt
4
- VERSION = '3.26.2'
4
+ VERSION = '3.27.2'
5
5
  end
@@ -9,7 +9,11 @@
9
9
  "type": "object",
10
10
  "description": "JSON formatted parameters to be provided to task"
11
11
  },
12
- "target": { "$ref": "partial:target-any" }
12
+ "target": { "$ref": "partial:target-any" },
13
+ "timeout": {
14
+ "type": "integer",
15
+ "description": "Number of seconds to wait before abandoning the task execution on the tartet."
16
+ }
13
17
  },
14
18
  "required": ["target", "task"],
15
19
  "additionalProperties": false
@@ -9,7 +9,6 @@ require 'bolt/project'
9
9
  require 'bolt/target'
10
10
  require 'bolt_server/file_cache'
11
11
  require 'bolt_server/plugin'
12
- require 'bolt_server/plugin/puppet_connect_data'
13
12
  require 'bolt_server/request_error'
14
13
  require 'bolt/task/puppet_server'
15
14
  require 'json'
@@ -42,7 +41,6 @@ module BoltServer
42
41
  action-upload_file
43
42
  transport-ssh
44
43
  transport-winrm
45
- connect-data
46
44
  action-apply_prep
47
45
  action-apply
48
46
  ].freeze
@@ -126,7 +124,17 @@ module BoltServer
126
124
  end
127
125
  end
128
126
 
129
- def task_helper(target, task, parameters)
127
+ def unwrap_sensitive_results(result_set)
128
+ # Take a ResultSet and unwrap sensitive values
129
+ result_set.each do |result|
130
+ value = result.value
131
+ next unless value.is_a?(Hash)
132
+ next unless value.key?('_sensitive')
133
+ value['_sensitive'] = value['_sensitive'].unwrap
134
+ end
135
+ end
136
+
137
+ def task_helper(target, task, parameters, timeout = nil)
130
138
  # Wrap parameters marked with '"sensitive": true' in the task metadata with a
131
139
  # Sensitive wrapper type. This way it's not shown in logs.
132
140
  if (param_spec = task.parameters)
@@ -137,11 +145,20 @@ module BoltServer
137
145
  end
138
146
  end
139
147
 
140
- @executor.run_task(target, task, parameters).each do |result|
141
- value = result.value
142
- next unless value.is_a?(Hash)
143
- next unless value.key?('_sensitive')
144
- value['_sensitive'] = value['_sensitive'].unwrap
148
+ if timeout && timeout > 0
149
+ task_thread = Thread.new do
150
+ unwrap_sensitive_results(@executor.run_task(target, task, parameters))
151
+ end
152
+ # Wait for the timeout for the task to execute in the thread. If `join` times out, result will be nil.
153
+ if task_thread.join(timeout).nil?
154
+ task_thread.kill
155
+ raise Bolt::Error.new("Task execution on #{target.first.safe_name} timed out after #{timeout} seconds",
156
+ 'boltserver/task-timeout')
157
+ else
158
+ task_thread.value
159
+ end
160
+ else
161
+ unwrap_sensitive_results(@executor.run_task(target, task, parameters))
145
162
  end
146
163
  end
147
164
 
@@ -150,7 +167,7 @@ module BoltServer
150
167
 
151
168
  task_data = body['task']
152
169
  task = Bolt::Task::PuppetServer.new(task_data['name'], task_data['metadata'], task_data['files'], @file_cache)
153
- task_helper(target, task, body['parameters'] || {})
170
+ task_helper(target, task, body['parameters'] || {}, body['timeout'])
154
171
  end
155
172
 
156
173
  def extract_install_task(target)
@@ -825,53 +842,6 @@ module BoltServer
825
842
  [500, e.message]
826
843
  end
827
844
 
828
- # Returns a list of targets parsed from a Project inventory
829
- #
830
- # @param versioned_project [String] the versioned_project to compute the inventory from
831
- post '/project_inventory_targets' do
832
- content_type :json
833
- body = JSON.parse(request.body.read)
834
- validate_schema(@schemas["connect-data"], body)
835
- in_bolt_project(body['versioned_project']) do |context|
836
- if context[:config].inventoryfile &&
837
- context[:config].project.inventory_file.to_s !=
838
- context[:config].inventoryfile
839
- raise Bolt::ValidationError, "Project inventory must be defined in the " \
840
- "inventory.yaml file at the root of the project directory"
841
- end
842
-
843
- Bolt::Util.validate_file('inventory file', context[:config].project.inventory_file)
844
-
845
- begin
846
- # Set the default puppet_library plugin hook if it has not already been
847
- # set
848
- context[:config].data['plugin-hooks']['puppet_library'] ||= {
849
- 'plugin' => 'task',
850
- 'task' => 'puppet_agent::install',
851
- 'parameters' => {
852
- 'stop_service' => true
853
- }
854
- }
855
-
856
- connect_plugin = BoltServer::Plugin::PuppetConnectData.new(body['puppet_connect_data'])
857
- plugins = Bolt::Plugin.new(context[:config], context[:pal], load_plugins: false)
858
- plugins.add_plugin(connect_plugin)
859
- %w[aws_inventory azure_inventory gcloud_inventory].each do |plugin_name|
860
- plugins.add_module_plugin(plugin_name) if plugins.known_plugin?(plugin_name)
861
- end
862
- inventory = Bolt::Inventory.from_config(context[:config], plugins)
863
- target_list = inventory.get_targets('all').map do |targ|
864
- targ.to_h.merge({ 'transport' => targ.transport, 'plugin_hooks' => targ.plugin_hooks })
865
- end
866
- rescue Bolt::Plugin::PluginError::LoadingDisabled => e
867
- msg = "Cannot load plugin #{e.details['plugin_name']}: plugin not supported"
868
- raise BoltServer::Plugin::PluginNotSupported.new(msg, e.details['plugin_name'])
869
- end
870
-
871
- [200, target_list.to_json]
872
- end
873
- end
874
-
875
845
  # Returns the base64 encoded tar archive of plugin code that is needed to calculate
876
846
  # custom facts
877
847
  #
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bolt
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.26.2
4
+ version: 3.27.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Puppet
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2022-11-16 00:00:00.000000000 Z
11
+ date: 2023-08-14 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: addressable
@@ -42,14 +42,14 @@ dependencies:
42
42
  name: CFPropertyList
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
- - - "~>"
45
+ - - ">="
46
46
  - !ruby/object:Gem::Version
47
47
  version: '2.2'
48
48
  type: :runtime
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
- - - "~>"
52
+ - - ">="
53
53
  - !ruby/object:Gem::Version
54
54
  version: '2.2'
55
55
  - !ruby/object:Gem::Dependency
@@ -59,6 +59,9 @@ dependencies:
59
59
  - - "~>"
60
60
  - !ruby/object:Gem::Version
61
61
  version: '1.0'
62
+ - - "<"
63
+ - !ruby/object:Gem::Version
64
+ version: 1.2.0
62
65
  type: :runtime
63
66
  prerelease: false
64
67
  version_requirements: !ruby/object:Gem::Requirement
@@ -66,6 +69,9 @@ dependencies:
66
69
  - - "~>"
67
70
  - !ruby/object:Gem::Version
68
71
  version: '1.0'
72
+ - - "<"
73
+ - !ruby/object:Gem::Version
74
+ version: 1.2.0
69
75
  - !ruby/object:Gem::Dependency
70
76
  name: ffi
71
77
  requirement: !ruby/object:Gem::Requirement
@@ -146,16 +152,22 @@ dependencies:
146
152
  name: net-scp
147
153
  requirement: !ruby/object:Gem::Requirement
148
154
  requirements:
149
- - - "~>"
155
+ - - ">="
150
156
  - !ruby/object:Gem::Version
151
157
  version: '1.2'
158
+ - - "<"
159
+ - !ruby/object:Gem::Version
160
+ version: '5.0'
152
161
  type: :runtime
153
162
  prerelease: false
154
163
  version_requirements: !ruby/object:Gem::Requirement
155
164
  requirements:
156
- - - "~>"
165
+ - - ">="
157
166
  - !ruby/object:Gem::Version
158
167
  version: '1.2'
168
+ - - "<"
169
+ - !ruby/object:Gem::Version
170
+ version: '5.0'
159
171
  - !ruby/object:Gem::Dependency
160
172
  name: net-ssh
161
173
  requirement: !ruby/object:Gem::Requirement
@@ -165,7 +177,7 @@ dependencies:
165
177
  version: '4.0'
166
178
  - - "<"
167
179
  - !ruby/object:Gem::Version
168
- version: '7.0'
180
+ version: '8.0'
169
181
  type: :runtime
170
182
  prerelease: false
171
183
  version_requirements: !ruby/object:Gem::Requirement
@@ -175,7 +187,7 @@ dependencies:
175
187
  version: '4.0'
176
188
  - - "<"
177
189
  - !ruby/object:Gem::Version
178
- version: '7.0'
190
+ version: '8.0'
179
191
  - !ruby/object:Gem::Dependency
180
192
  name: net-ssh-krb
181
193
  requirement: !ruby/object:Gem::Requirement
@@ -261,7 +273,7 @@ dependencies:
261
273
  version: 2.3.0
262
274
  - - "<"
263
275
  - !ruby/object:Gem::Version
264
- version: '4.0'
276
+ version: '5.0'
265
277
  type: :runtime
266
278
  prerelease: false
267
279
  version_requirements: !ruby/object:Gem::Requirement
@@ -271,7 +283,7 @@ dependencies:
271
283
  version: 2.3.0
272
284
  - - "<"
273
285
  - !ruby/object:Gem::Version
274
- version: '4.0'
286
+ version: '5.0'
275
287
  - !ruby/object:Gem::Dependency
276
288
  name: r10k
277
289
  requirement: !ruby/object:Gem::Requirement
@@ -374,16 +386,16 @@ dependencies:
374
386
  name: puppetlabs_spec_helper
375
387
  requirement: !ruby/object:Gem::Requirement
376
388
  requirements:
377
- - - "<="
389
+ - - "~>"
378
390
  - !ruby/object:Gem::Version
379
- version: 2.15.0
391
+ version: '5.0'
380
392
  type: :development
381
393
  prerelease: false
382
394
  version_requirements: !ruby/object:Gem::Requirement
383
395
  requirements:
384
- - - "<="
396
+ - - "~>"
385
397
  - !ruby/object:Gem::Version
386
- version: 2.15.0
398
+ version: '5.0'
387
399
  - !ruby/object:Gem::Dependency
388
400
  name: rake
389
401
  requirement: !ruby/object:Gem::Requirement
@@ -509,6 +521,7 @@ files:
509
521
  - lib/bolt/config/options.rb
510
522
  - lib/bolt/config/transport/base.rb
511
523
  - lib/bolt/config/transport/docker.rb
524
+ - lib/bolt/config/transport/jail.rb
512
525
  - lib/bolt/config/transport/local.rb
513
526
  - lib/bolt/config/transport/lxd.rb
514
527
  - lib/bolt/config/transport/options.rb
@@ -606,6 +619,8 @@ files:
606
619
  - lib/bolt/transport/base.rb
607
620
  - lib/bolt/transport/docker.rb
608
621
  - lib/bolt/transport/docker/connection.rb
622
+ - lib/bolt/transport/jail.rb
623
+ - lib/bolt/transport/jail/connection.rb
609
624
  - lib/bolt/transport/local.rb
610
625
  - lib/bolt/transport/local/connection.rb
611
626
  - lib/bolt/transport/lxd.rb
@@ -640,7 +655,6 @@ files:
640
655
  - lib/bolt_server/schemas/action-run_script.json
641
656
  - lib/bolt_server/schemas/action-run_task.json
642
657
  - lib/bolt_server/schemas/action-upload_file.json
643
- - lib/bolt_server/schemas/connect-data.json
644
658
  - lib/bolt_server/schemas/partials/target-any.json
645
659
  - lib/bolt_server/schemas/partials/target-ssh.json
646
660
  - lib/bolt_server/schemas/partials/target-winrm.json
@@ -696,7 +710,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
696
710
  - !ruby/object:Gem::Version
697
711
  version: '0'
698
712
  requirements: []
699
- rubygems_version: 3.1.6
713
+ rubygems_version: 3.4.12
700
714
  signing_key:
701
715
  specification_version: 4
702
716
  summary: Execute commands remotely over SSH and WinRM
@@ -1,25 +0,0 @@
1
- {
2
- "$schema": "http://json-schema.org/draft-04/schema#",
3
- "title": "project_inventory_targets connect plugin data",
4
- "description": "POST project_inventory_targets connect plugin data",
5
- "type": "object",
6
- "properties": {
7
- "puppet_connect_data": {
8
- "type": "object",
9
- "patternProperties": {
10
- ".*": {
11
- "type": "object",
12
- "properties": {
13
- "value": {}
14
- },
15
- "required": ["value"]
16
- }
17
- },
18
- "additionalProperties": false
19
- },
20
- "versioned_project": {
21
- "type": "string"
22
- }
23
- },
24
- "required": ["puppet_connect_data", "versioned_project"]
25
- }