bolt 3.26.1 → 3.27.1

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: '0591d13a9aa93f3c96585985ffdf1619c29f3f13130cbde98e1b24a1a357b84b'
4
- data.tar.gz: 3fe46914478ad07fab90348eb0464a5e45f5c10fa5f921baf3fa089f8d17cad3
3
+ metadata.gz: c17b8b0fb4276ed447b6da76d98053171f4d5fda8503233035b919394add9e94
4
+ data.tar.gz: db0861f045bc751bd69e0da10fe7708b6b0186c5fe1e35e252b383ff935b77f4
5
5
  SHA512:
6
- metadata.gz: a12e686a2ce4a3a15f22e2d45f8210eb6211c910e49e59377e37165554ae5f776c4827dfdb93984d8acdd6295cb7c31f49a090a4239ecc2150bff27f2aeb2bbc
7
- data.tar.gz: 5f6ccddd83c3026b1a34be7ab439d800f82cb997f179ab9967ead53c87b5141f2419dce5ae0a29ad17fc4257b294856e39aa61916fca4cbb907919520ad8fbf3
6
+ metadata.gz: af08780fd019620d3db858eb34387a38a0ef195d9ab56cfc2bc1e6629e1b86fcd2301b489facd81a77915a914d95eb017d5e88ec7443e66c74c72c148f334c5f
7
+ data.tar.gz: d01bb8cb30bcfd2a48e9537311b6208e8c7340e02b1101745ffe52affdf1503cf7754de7918b179af033aaa3303e9b4f381d460083cc302864f0747f4bc79d6b
@@ -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.1'
4
+ VERSION = '3.27.1'
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.1
4
+ version: 3.27.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Puppet
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2022-08-16 00:00:00.000000000 Z
11
+ date: 2023-03-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: addressable
@@ -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
@@ -165,7 +171,7 @@ dependencies:
165
171
  version: '4.0'
166
172
  - - "<"
167
173
  - !ruby/object:Gem::Version
168
- version: '7.0'
174
+ version: '8.0'
169
175
  type: :runtime
170
176
  prerelease: false
171
177
  version_requirements: !ruby/object:Gem::Requirement
@@ -175,7 +181,7 @@ dependencies:
175
181
  version: '4.0'
176
182
  - - "<"
177
183
  - !ruby/object:Gem::Version
178
- version: '7.0'
184
+ version: '8.0'
179
185
  - !ruby/object:Gem::Dependency
180
186
  name: net-ssh-krb
181
187
  requirement: !ruby/object:Gem::Requirement
@@ -256,16 +262,22 @@ dependencies:
256
262
  name: puppet-strings
257
263
  requirement: !ruby/object:Gem::Requirement
258
264
  requirements:
259
- - - "~>"
265
+ - - ">="
266
+ - !ruby/object:Gem::Version
267
+ version: 2.3.0
268
+ - - "<"
260
269
  - !ruby/object:Gem::Version
261
- version: '2.3'
270
+ version: '4.0'
262
271
  type: :runtime
263
272
  prerelease: false
264
273
  version_requirements: !ruby/object:Gem::Requirement
265
274
  requirements:
266
- - - "~>"
275
+ - - ">="
276
+ - !ruby/object:Gem::Version
277
+ version: 2.3.0
278
+ - - "<"
267
279
  - !ruby/object:Gem::Version
268
- version: '2.3'
280
+ version: '4.0'
269
281
  - !ruby/object:Gem::Dependency
270
282
  name: r10k
271
283
  requirement: !ruby/object:Gem::Requirement
@@ -368,16 +380,16 @@ dependencies:
368
380
  name: puppetlabs_spec_helper
369
381
  requirement: !ruby/object:Gem::Requirement
370
382
  requirements:
371
- - - "<="
383
+ - - "~>"
372
384
  - !ruby/object:Gem::Version
373
- version: 2.15.0
385
+ version: '5.0'
374
386
  type: :development
375
387
  prerelease: false
376
388
  version_requirements: !ruby/object:Gem::Requirement
377
389
  requirements:
378
- - - "<="
390
+ - - "~>"
379
391
  - !ruby/object:Gem::Version
380
- version: 2.15.0
392
+ version: '5.0'
381
393
  - !ruby/object:Gem::Dependency
382
394
  name: rake
383
395
  requirement: !ruby/object:Gem::Requirement
@@ -503,6 +515,7 @@ files:
503
515
  - lib/bolt/config/options.rb
504
516
  - lib/bolt/config/transport/base.rb
505
517
  - lib/bolt/config/transport/docker.rb
518
+ - lib/bolt/config/transport/jail.rb
506
519
  - lib/bolt/config/transport/local.rb
507
520
  - lib/bolt/config/transport/lxd.rb
508
521
  - lib/bolt/config/transport/options.rb
@@ -600,6 +613,8 @@ files:
600
613
  - lib/bolt/transport/base.rb
601
614
  - lib/bolt/transport/docker.rb
602
615
  - lib/bolt/transport/docker/connection.rb
616
+ - lib/bolt/transport/jail.rb
617
+ - lib/bolt/transport/jail/connection.rb
603
618
  - lib/bolt/transport/local.rb
604
619
  - lib/bolt/transport/local/connection.rb
605
620
  - lib/bolt/transport/lxd.rb
@@ -634,7 +649,6 @@ files:
634
649
  - lib/bolt_server/schemas/action-run_script.json
635
650
  - lib/bolt_server/schemas/action-run_task.json
636
651
  - lib/bolt_server/schemas/action-upload_file.json
637
- - lib/bolt_server/schemas/connect-data.json
638
652
  - lib/bolt_server/schemas/partials/target-any.json
639
653
  - lib/bolt_server/schemas/partials/target-ssh.json
640
654
  - lib/bolt_server/schemas/partials/target-winrm.json
@@ -690,7 +704,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
690
704
  - !ruby/object:Gem::Version
691
705
  version: '0'
692
706
  requirements: []
693
- rubygems_version: 3.0.9
707
+ rubygems_version: 3.1.6
694
708
  signing_key:
695
709
  specification_version: 4
696
710
  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
- }