bolt 2.1.0 → 2.2.0
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/Puppetfile +5 -5
- data/bolt-modules/boltlib/lib/puppet/functions/run_command.rb +1 -1
- data/bolt-modules/boltlib/lib/puppet/functions/run_plan.rb +1 -1
- data/bolt-modules/boltlib/lib/puppet/functions/run_script.rb +1 -1
- data/bolt-modules/boltlib/lib/puppet/functions/run_task.rb +1 -1
- data/bolt-modules/boltlib/lib/puppet/functions/upload_file.rb +1 -1
- data/lib/bolt/applicator.rb +2 -2
- data/lib/bolt/bolt_option_parser.rb +1 -1
- data/lib/bolt/cli.rb +1 -1
- data/lib/bolt/config.rb +201 -206
- data/lib/bolt/config/transport/base.rb +142 -0
- data/lib/bolt/config/transport/docker.rb +42 -0
- data/lib/bolt/config/transport/local.rb +73 -0
- data/lib/bolt/config/transport/orch.rb +47 -0
- data/lib/bolt/config/transport/remote.rb +25 -0
- data/lib/bolt/config/transport/ssh.rb +105 -0
- data/lib/bolt/config/transport/winrm.rb +80 -0
- data/lib/bolt/executor.rb +17 -0
- data/lib/bolt/inventory.rb +12 -5
- data/lib/bolt/inventory/group.rb +1 -1
- data/lib/bolt/inventory/inventory.rb +16 -22
- data/lib/bolt/inventory/target.rb +26 -29
- data/lib/bolt/plugin.rb +5 -5
- data/lib/bolt/plugin/module.rb +1 -1
- data/lib/bolt/plugin/pkcs7.rb +1 -1
- data/lib/bolt/result.rb +1 -1
- data/lib/bolt/target.rb +5 -2
- data/lib/bolt/transport/base.rb +0 -18
- data/lib/bolt/transport/docker.rb +0 -26
- data/lib/bolt/transport/local.rb +0 -30
- data/lib/bolt/transport/local_windows.rb +4 -36
- data/lib/bolt/transport/orch.rb +0 -20
- data/lib/bolt/transport/remote.rb +0 -20
- data/lib/bolt/transport/ssh.rb +0 -85
- data/lib/bolt/transport/sudoable.rb +0 -7
- data/lib/bolt/transport/winrm.rb +0 -66
- data/lib/bolt/util.rb +11 -0
- data/lib/bolt/version.rb +1 -1
- data/lib/bolt_server/transport_app.rb +1 -0
- data/lib/bolt_spec/plans.rb +1 -1
- data/lib/bolt_spec/plans/action_stubs/command_stub.rb +1 -1
- data/lib/bolt_spec/plans/action_stubs/script_stub.rb +1 -1
- data/lib/bolt_spec/plans/action_stubs/task_stub.rb +2 -2
- data/lib/bolt_spec/plans/action_stubs/upload_stub.rb +1 -1
- data/lib/bolt_spec/run.rb +1 -1
- data/libexec/apply_catalog.rb +1 -1
- data/libexec/custom_facts.rb +1 -1
- data/libexec/query_resources.rb +1 -1
- metadata +9 -2
data/lib/bolt/transport/orch.rb
CHANGED
@@ -21,30 +21,10 @@ module Bolt
|
|
21
21
|
|
22
22
|
attr_writer :plan_context
|
23
23
|
|
24
|
-
OPTIONS = {
|
25
|
-
"cacert" => "The path to the CA certificate.",
|
26
|
-
"host" => "Host name.",
|
27
|
-
"job-poll-interval" => "Set interval to poll orchestrator for job status.",
|
28
|
-
"job-poll-timeout" => "Set time to wait for orchestrator job status.",
|
29
|
-
"service-url" => "The URL of the orchestrator API.",
|
30
|
-
"task-environment" => "The environment the orchestrator loads task code from.",
|
31
|
-
"token-file" => "The path to the token file."
|
32
|
-
}.freeze
|
33
|
-
|
34
|
-
def self.options
|
35
|
-
OPTIONS.keys
|
36
|
-
end
|
37
|
-
|
38
|
-
def self.default_options
|
39
|
-
{ 'task-environment' => 'production' }
|
40
|
-
end
|
41
|
-
|
42
24
|
def provided_features
|
43
25
|
['puppet-agent']
|
44
26
|
end
|
45
27
|
|
46
|
-
def self.validate(options); end
|
47
|
-
|
48
28
|
def initialize(*args)
|
49
29
|
# lazy-load expensive gem code
|
50
30
|
require 'orchestrator_client'
|
@@ -6,26 +6,6 @@ require 'bolt/transport/base'
|
|
6
6
|
module Bolt
|
7
7
|
module Transport
|
8
8
|
class Remote < Base
|
9
|
-
OPTIONS = {
|
10
|
-
"run-on" => "The proxy target that the task executes on."
|
11
|
-
}.freeze
|
12
|
-
|
13
|
-
# The options for the remote transport not defined.
|
14
|
-
def self.filter_options(unfiltered)
|
15
|
-
unfiltered
|
16
|
-
end
|
17
|
-
|
18
|
-
def self.default_options
|
19
|
-
{ 'run-on' => 'localhost' }
|
20
|
-
end
|
21
|
-
|
22
|
-
def self.validate(options)
|
23
|
-
# This will fail when validating global config
|
24
|
-
# unless options['device-type']
|
25
|
-
# raise Bolt::ValidationError, 'Must specify device-type for devices'
|
26
|
-
# end
|
27
|
-
end
|
28
|
-
|
29
9
|
# TODO: this should have access to inventory so target doesn't have to
|
30
10
|
def initialize(executor)
|
31
11
|
super()
|
data/lib/bolt/transport/ssh.rb
CHANGED
@@ -8,95 +8,10 @@ require 'shellwords'
|
|
8
8
|
module Bolt
|
9
9
|
module Transport
|
10
10
|
class SSH < Sudoable
|
11
|
-
OPTIONS = {
|
12
|
-
"connect-timeout" => "How long to wait when establishing connections.",
|
13
|
-
"disconnect-timeout" => "How long to wait before force-closing a connection.",
|
14
|
-
"host" => "Host name.",
|
15
|
-
"host-key-check" => "Whether to perform host key validation when connecting.",
|
16
|
-
"interpreters" => "A map of an extension name to the absolute path of an executable, "\
|
17
|
-
"enabling you to override the shebang defined in a task executable. The "\
|
18
|
-
"extension can optionally be specified with the `.` character (`.py` and "\
|
19
|
-
"`py` both map to a task executable `task.py`) and the extension is case "\
|
20
|
-
"sensitive. When a target's name is `localhost`, Ruby tasks run with the "\
|
21
|
-
"Bolt Ruby interpreter by default.",
|
22
|
-
"load-config" => "Whether to load system SSH configuration.",
|
23
|
-
"password" => "Login password.",
|
24
|
-
"port" => "Connection port.",
|
25
|
-
"private-key" => "Either the path to the private key file to use for authentication, or a "\
|
26
|
-
"hash with the key `key-data` and the contents of the private key.",
|
27
|
-
"proxyjump" => "A jump host to proxy connections through, and an optional user to "\
|
28
|
-
"connect with.",
|
29
|
-
"run-as" => "A different user to run commands as after login.",
|
30
|
-
"run-as-command" => "The command to elevate permissions. Bolt appends the user and command "\
|
31
|
-
"strings to the configured `run-as-command` before running it on the "\
|
32
|
-
"target. This command must not require an interactive password prompt, "\
|
33
|
-
"and the `sudo-password` option is ignored when `run-as-command` is "\
|
34
|
-
"specified. The `run-as-command` must be specified as an array.",
|
35
|
-
"script-dir" => "The subdirectory of the tmpdir to use in place of a randomized "\
|
36
|
-
"subdirectory for uploading and executing temporary files on the "\
|
37
|
-
"target. It's expected that this directory already exists as a subdir "\
|
38
|
-
"of tmpdir, which is either configured or defaults to `/tmp`.",
|
39
|
-
"sudo-executable" => "The executable to use when escalating to the configured `run-as` "\
|
40
|
-
"user. This is useful when you want to escalate using the configured "\
|
41
|
-
"`sudo-password`, since `run-as-command` does not use `sudo-password` "\
|
42
|
-
"or support prompting. The command executed on the target is "\
|
43
|
-
"`<sudo-executable> -S -u <user> -p custom_bolt_prompt <command>`. "\
|
44
|
-
"**This option is experimental.**",
|
45
|
-
"sudo-password" => "Password to use when changing users via `run-as`.",
|
46
|
-
"tmpdir" => "The directory to upload and execute temporary files on the target.",
|
47
|
-
"tty" => "Request a pseudo tty for the session. This option is generally "\
|
48
|
-
"only used in conjunction with the `run-as` option when the sudoers "\
|
49
|
-
"policy requires a `tty`.",
|
50
|
-
"user" => "Login user."
|
51
|
-
}.freeze
|
52
|
-
|
53
|
-
def self.options
|
54
|
-
OPTIONS.keys
|
55
|
-
end
|
56
|
-
|
57
|
-
def self.default_options
|
58
|
-
{
|
59
|
-
'connect-timeout' => 10,
|
60
|
-
'tty' => false,
|
61
|
-
'load-config' => true,
|
62
|
-
'disconnect-timeout' => 5
|
63
|
-
}
|
64
|
-
end
|
65
|
-
|
66
11
|
def provided_features
|
67
12
|
['shell']
|
68
13
|
end
|
69
14
|
|
70
|
-
def self.validate(options)
|
71
|
-
validate_sudo_options(options)
|
72
|
-
|
73
|
-
host_key = options['host-key-check']
|
74
|
-
unless host_key.nil? || !!host_key == host_key
|
75
|
-
raise Bolt::ValidationError, 'host-key-check option must be a Boolean true or false'
|
76
|
-
end
|
77
|
-
|
78
|
-
if (key_opt = options['private-key'])
|
79
|
-
unless key_opt.instance_of?(String) || (key_opt.instance_of?(Hash) && key_opt.include?('key-data'))
|
80
|
-
raise Bolt::ValidationError,
|
81
|
-
"private-key option must be the path to a private key file or a hash containing the 'key-data'"
|
82
|
-
end
|
83
|
-
end
|
84
|
-
|
85
|
-
%w[connect-timeout disconnect-timeout].each do |timeout|
|
86
|
-
timeout_value = options[timeout]
|
87
|
-
unless timeout_value.is_a?(Integer) || timeout_value.nil?
|
88
|
-
error_msg = "#{timeout} value must be an Integer, received #{timeout_value}:#{timeout_value.class}"
|
89
|
-
raise Bolt::ValidationError, error_msg
|
90
|
-
end
|
91
|
-
end
|
92
|
-
|
93
|
-
if (dir_opt = options['script-dir'])
|
94
|
-
unless dir_opt.is_a?(String) && !dir_opt.empty?
|
95
|
-
raise Bolt::ValidationError, "script-dir option must be a non-empty string"
|
96
|
-
end
|
97
|
-
end
|
98
|
-
end
|
99
|
-
|
100
15
|
def initialize
|
101
16
|
super
|
102
17
|
|
@@ -6,13 +6,6 @@ require 'bolt/transport/base'
|
|
6
6
|
module Bolt
|
7
7
|
module Transport
|
8
8
|
class Sudoable < Base
|
9
|
-
def self.validate_sudo_options(options)
|
10
|
-
run_as_cmd = options['run-as-command']
|
11
|
-
if run_as_cmd && (!run_as_cmd.is_a?(Array) || run_as_cmd.any? { |n| !n.is_a?(String) })
|
12
|
-
raise Bolt::ValidationError, "run-as-command must be an Array of Strings, received #{run_as_cmd}"
|
13
|
-
end
|
14
|
-
end
|
15
|
-
|
16
9
|
def self.sudo_prompt
|
17
10
|
'[sudo] Bolt needs to run as another user, password: '
|
18
11
|
end
|
data/lib/bolt/transport/winrm.rb
CHANGED
@@ -7,46 +7,6 @@ require 'bolt/transport/powershell'
|
|
7
7
|
module Bolt
|
8
8
|
module Transport
|
9
9
|
class WinRM < Base
|
10
|
-
OPTIONS = {
|
11
|
-
"cacert" => "The path to the CA certificate.",
|
12
|
-
"connect-timeout" => "How long Bolt should wait when establishing connections.",
|
13
|
-
"extensions" => "List of file extensions that are accepted for scripts or tasks. "\
|
14
|
-
"Scripts with these file extensions rely on the target's file type "\
|
15
|
-
"association to run. For example, if Python is installed on the system, "\
|
16
|
-
"a `.py` script runs with `python.exe`. The extensions `.ps1`, `.rb`, and "\
|
17
|
-
"`.pp` are always allowed and run via hard-coded executables.",
|
18
|
-
"file-protocol" => "Which file transfer protocol to use. Either `winrm` or `smb`. Using `smb` is "\
|
19
|
-
"recommended for large file transfers.",
|
20
|
-
"host" => "Host name.",
|
21
|
-
"interpreters" => "A map of an extension name to the absolute path of an executable, "\
|
22
|
-
"enabling you to override the shebang defined in a task executable. The "\
|
23
|
-
"extension can optionally be specified with the `.` character (`.py` and "\
|
24
|
-
"`py` both map to a task executable `task.py`) and the extension is case "\
|
25
|
-
"sensitive. When a target's name is `localhost`, Ruby tasks run with the "\
|
26
|
-
"Bolt Ruby interpreter by default.",
|
27
|
-
"password" => "Login password. **Required unless using Kerberos.**",
|
28
|
-
"port" => "Connection port.",
|
29
|
-
"realm" => "Kerberos realm (Active Directory domain) to authenticate against.",
|
30
|
-
"smb-port" => "With file-protocol set to smb, this is the port to establish a connection on.",
|
31
|
-
"ssl" => "When true, Bolt uses secure https connections for WinRM.",
|
32
|
-
"ssl-verify" => "When true, verifies the targets certificate matches the cacert.",
|
33
|
-
"tmpdir" => "The directory to upload and execute temporary files on the target.",
|
34
|
-
"user" => "Login user. **Required unless using Kerberos.**"
|
35
|
-
}.freeze
|
36
|
-
|
37
|
-
def self.options
|
38
|
-
OPTIONS.keys
|
39
|
-
end
|
40
|
-
|
41
|
-
def self.default_options
|
42
|
-
{
|
43
|
-
'connect-timeout' => 10,
|
44
|
-
'ssl' => true,
|
45
|
-
'ssl-verify' => true,
|
46
|
-
'file-protocol' => 'winrm'
|
47
|
-
}
|
48
|
-
end
|
49
|
-
|
50
10
|
def provided_features
|
51
11
|
['powershell']
|
52
12
|
end
|
@@ -56,32 +16,6 @@ module Bolt
|
|
56
16
|
input_method
|
57
17
|
end
|
58
18
|
|
59
|
-
def self.validate(options)
|
60
|
-
ssl_flag = options['ssl']
|
61
|
-
unless !!ssl_flag == ssl_flag
|
62
|
-
raise Bolt::ValidationError, 'ssl option must be a Boolean true or false'
|
63
|
-
end
|
64
|
-
|
65
|
-
if ssl_flag && (options['file-protocol'] == 'smb')
|
66
|
-
raise Bolt::ValidationError, 'SMB file transfers are not allowed with SSL enabled'
|
67
|
-
end
|
68
|
-
|
69
|
-
if ssl_flag && (ca_path = options['cacert'])
|
70
|
-
Bolt::Util.validate_file('cacert', ca_path)
|
71
|
-
end
|
72
|
-
|
73
|
-
ssl_verify_flag = options['ssl-verify']
|
74
|
-
unless !!ssl_verify_flag == ssl_verify_flag
|
75
|
-
raise Bolt::ValidationError, 'ssl-verify option must be a Boolean true or false'
|
76
|
-
end
|
77
|
-
|
78
|
-
timeout_value = options['connect-timeout']
|
79
|
-
unless timeout_value.is_a?(Integer) || timeout_value.nil?
|
80
|
-
error_msg = "connect-timeout value must be an Integer, received #{timeout_value}:#{timeout_value.class}"
|
81
|
-
raise Bolt::ValidationError, error_msg
|
82
|
-
end
|
83
|
-
end
|
84
|
-
|
85
19
|
def initialize
|
86
20
|
super
|
87
21
|
require 'winrm'
|
data/lib/bolt/util.rb
CHANGED
@@ -238,6 +238,17 @@ module Bolt
|
|
238
238
|
def symbolize_top_level_keys(hsh)
|
239
239
|
hsh.each_with_object({}) { |(k, v), h| k.is_a?(String) ? h[k.to_sym] = v : h[k] = v }
|
240
240
|
end
|
241
|
+
|
242
|
+
# Recursively searches a data structure for plugin references
|
243
|
+
def references?(input)
|
244
|
+
if input.is_a?(Hash)
|
245
|
+
input.key?('_plugin') || input.values.any? { |v| references?(v) }
|
246
|
+
elsif input.is_a?(Array)
|
247
|
+
input.any? { |v| references?(v) }
|
248
|
+
else
|
249
|
+
false
|
250
|
+
end
|
251
|
+
end
|
241
252
|
end
|
242
253
|
end
|
243
254
|
end
|
data/lib/bolt/version.rb
CHANGED
data/lib/bolt_spec/plans.rb
CHANGED
@@ -181,7 +181,7 @@ module BoltSpec
|
|
181
181
|
end
|
182
182
|
|
183
183
|
def inventory
|
184
|
-
@inventory ||= Bolt::Inventory.create_version(inventory_data, config, plugins)
|
184
|
+
@inventory ||= Bolt::Inventory.create_version(inventory_data, config.transport, config.transports, plugins)
|
185
185
|
end
|
186
186
|
|
187
187
|
# Provided as a class so expectations can be placed on it.
|
@@ -44,7 +44,7 @@ module BoltSpec
|
|
44
44
|
@invocation[:params] = params
|
45
45
|
@invocation[:arguments] = params['arguments']
|
46
46
|
@invocation[:options] = params.select { |k, _v| k.start_with?('_') }
|
47
|
-
.
|
47
|
+
.transform_keys { |k| k.sub(/^_/, '').to_sym }
|
48
48
|
self
|
49
49
|
end
|
50
50
|
end
|
@@ -23,7 +23,7 @@ module BoltSpec
|
|
23
23
|
@calls += 1
|
24
24
|
if @return_block
|
25
25
|
# Merge arguments and options into params to match puppet function signature.
|
26
|
-
params = options.
|
26
|
+
params = options.transform_keys { |k| "_#{k}" }
|
27
27
|
params = params.merge(arguments)
|
28
28
|
|
29
29
|
check_resultset(@return_block.call(targets: targets, task: task, params: params), task)
|
@@ -49,7 +49,7 @@ module BoltSpec
|
|
49
49
|
@invocation[:params] = params
|
50
50
|
@invocation[:arguments] = params.reject { |k, _v| k.start_with?('_') }
|
51
51
|
@invocation[:options] = params.select { |k, _v| k.start_with?('_') }
|
52
|
-
.
|
52
|
+
.transform_keys { |k| k.sub(/^_/, '').to_sym }
|
53
53
|
self
|
54
54
|
end
|
55
55
|
end
|
data/lib/bolt_spec/run.rb
CHANGED
@@ -148,7 +148,7 @@ module BoltSpec
|
|
148
148
|
end
|
149
149
|
|
150
150
|
def inventory
|
151
|
-
@inventory ||= Bolt::Inventory.create_version(@inventory_data, config, plugins)
|
151
|
+
@inventory ||= Bolt::Inventory.create_version(@inventory_data, config.transport, config.transports, plugins)
|
152
152
|
end
|
153
153
|
|
154
154
|
def plugins
|
data/libexec/apply_catalog.rb
CHANGED
@@ -68,7 +68,7 @@ begin
|
|
68
68
|
end
|
69
69
|
|
70
70
|
# Transport.connect will modify this hash!
|
71
|
-
transport_conn_info = conn_info.
|
71
|
+
transport_conn_info = conn_info.transform_keys(&:to_sym)
|
72
72
|
|
73
73
|
transport = Puppet::ResourceApi::Transport.connect(type, transport_conn_info)
|
74
74
|
Puppet::ResourceApi::Transport.inject_device(type, transport)
|
data/libexec/custom_facts.rb
CHANGED
@@ -46,7 +46,7 @@ Dir.mktmpdir do |puppet_root|
|
|
46
46
|
end
|
47
47
|
|
48
48
|
# Transport.connect will modify this hash!
|
49
|
-
transport_conn_info = conn_info.
|
49
|
+
transport_conn_info = conn_info.transform_keys(&:to_sym)
|
50
50
|
transport = Puppet::ResourceApi::Transport.connect(type, transport_conn_info)
|
51
51
|
Puppet::ResourceApi::Transport.inject_device(type, transport)
|
52
52
|
|
data/libexec/query_resources.rb
CHANGED
@@ -53,7 +53,7 @@ Dir.mktmpdir do |puppet_root|
|
|
53
53
|
end
|
54
54
|
|
55
55
|
# Transport.connect will modify this hash!
|
56
|
-
transport_conn_info = conn_info.
|
56
|
+
transport_conn_info = conn_info.transform_keys(&:to_sym)
|
57
57
|
|
58
58
|
transport = Puppet::ResourceApi::Transport.connect(type, transport_conn_info)
|
59
59
|
Puppet::ResourceApi::Transport.inject_device(type, transport)
|
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: 2.
|
4
|
+
version: 2.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Puppet
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-03-
|
11
|
+
date: 2020-03-10 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: addressable
|
@@ -400,6 +400,13 @@ files:
|
|
400
400
|
- lib/bolt/catalog/logging.rb
|
401
401
|
- lib/bolt/cli.rb
|
402
402
|
- lib/bolt/config.rb
|
403
|
+
- lib/bolt/config/transport/base.rb
|
404
|
+
- lib/bolt/config/transport/docker.rb
|
405
|
+
- lib/bolt/config/transport/local.rb
|
406
|
+
- lib/bolt/config/transport/orch.rb
|
407
|
+
- lib/bolt/config/transport/remote.rb
|
408
|
+
- lib/bolt/config/transport/ssh.rb
|
409
|
+
- lib/bolt/config/transport/winrm.rb
|
403
410
|
- lib/bolt/error.rb
|
404
411
|
- lib/bolt/executor.rb
|
405
412
|
- lib/bolt/inventory.rb
|