bolt 3.26.2 → 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 +4 -4
- data/lib/bolt/config/options.rb +8 -0
- data/lib/bolt/config/transport/jail.rb +33 -0
- data/lib/bolt/executor.rb +2 -0
- data/lib/bolt/shell/bash.rb +1 -1
- data/lib/bolt/transport/jail/connection.rb +81 -0
- data/lib/bolt/transport/jail.rb +21 -0
- data/lib/bolt/version.rb +1 -1
- data/lib/bolt_server/schemas/action-run_task.json +5 -1
- data/lib/bolt_server/transport_app.rb +26 -56
- metadata +17 -9
- data/lib/bolt_server/schemas/connect-data.json +0 -25
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c17b8b0fb4276ed447b6da76d98053171f4d5fda8503233035b919394add9e94
|
4
|
+
data.tar.gz: db0861f045bc751bd69e0da10fe7708b6b0186c5fe1e35e252b383ff935b77f4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: af08780fd019620d3db858eb34387a38a0ef195d9ab56cfc2bc1e6629e1b86fcd2301b489facd81a77915a914d95eb017d5e88ec7443e66c74c72c148f334c5f
|
7
|
+
data.tar.gz: d01bb8cb30bcfd2a48e9537311b6208e8c7340e02b1101745ffe52affdf1503cf7754de7918b179af033aaa3303e9b4f381d460083cc302864f0747f4bc79d6b
|
data/lib/bolt/config/options.rb
CHANGED
@@ -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,
|
data/lib/bolt/shell/bash.rb
CHANGED
@@ -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
@@ -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
|
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
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
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.
|
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:
|
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: '
|
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: '
|
184
|
+
version: '8.0'
|
179
185
|
- !ruby/object:Gem::Dependency
|
180
186
|
name: net-ssh-krb
|
181
187
|
requirement: !ruby/object:Gem::Requirement
|
@@ -374,16 +380,16 @@ dependencies:
|
|
374
380
|
name: puppetlabs_spec_helper
|
375
381
|
requirement: !ruby/object:Gem::Requirement
|
376
382
|
requirements:
|
377
|
-
- - "
|
383
|
+
- - "~>"
|
378
384
|
- !ruby/object:Gem::Version
|
379
|
-
version:
|
385
|
+
version: '5.0'
|
380
386
|
type: :development
|
381
387
|
prerelease: false
|
382
388
|
version_requirements: !ruby/object:Gem::Requirement
|
383
389
|
requirements:
|
384
|
-
- - "
|
390
|
+
- - "~>"
|
385
391
|
- !ruby/object:Gem::Version
|
386
|
-
version:
|
392
|
+
version: '5.0'
|
387
393
|
- !ruby/object:Gem::Dependency
|
388
394
|
name: rake
|
389
395
|
requirement: !ruby/object:Gem::Requirement
|
@@ -509,6 +515,7 @@ files:
|
|
509
515
|
- lib/bolt/config/options.rb
|
510
516
|
- lib/bolt/config/transport/base.rb
|
511
517
|
- lib/bolt/config/transport/docker.rb
|
518
|
+
- lib/bolt/config/transport/jail.rb
|
512
519
|
- lib/bolt/config/transport/local.rb
|
513
520
|
- lib/bolt/config/transport/lxd.rb
|
514
521
|
- lib/bolt/config/transport/options.rb
|
@@ -606,6 +613,8 @@ files:
|
|
606
613
|
- lib/bolt/transport/base.rb
|
607
614
|
- lib/bolt/transport/docker.rb
|
608
615
|
- lib/bolt/transport/docker/connection.rb
|
616
|
+
- lib/bolt/transport/jail.rb
|
617
|
+
- lib/bolt/transport/jail/connection.rb
|
609
618
|
- lib/bolt/transport/local.rb
|
610
619
|
- lib/bolt/transport/local/connection.rb
|
611
620
|
- lib/bolt/transport/lxd.rb
|
@@ -640,7 +649,6 @@ files:
|
|
640
649
|
- lib/bolt_server/schemas/action-run_script.json
|
641
650
|
- lib/bolt_server/schemas/action-run_task.json
|
642
651
|
- lib/bolt_server/schemas/action-upload_file.json
|
643
|
-
- lib/bolt_server/schemas/connect-data.json
|
644
652
|
- lib/bolt_server/schemas/partials/target-any.json
|
645
653
|
- lib/bolt_server/schemas/partials/target-ssh.json
|
646
654
|
- lib/bolt_server/schemas/partials/target-winrm.json
|
@@ -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
|
-
}
|