bolt 2.11.1 → 2.16.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 +1 -1
- data/bolt-modules/boltlib/lib/puppet/datatypes/resourceinstance.rb +3 -2
- data/bolt-modules/boltlib/lib/puppet/functions/add_facts.rb +1 -0
- data/bolt-modules/boltlib/lib/puppet/functions/add_to_group.rb +1 -0
- data/bolt-modules/boltlib/lib/puppet/functions/apply_prep.rb +1 -1
- data/bolt-modules/boltlib/lib/puppet/functions/catch_errors.rb +1 -0
- data/bolt-modules/boltlib/lib/puppet/functions/facts.rb +1 -0
- data/bolt-modules/boltlib/lib/puppet/functions/fail_plan.rb +1 -0
- data/bolt-modules/boltlib/lib/puppet/functions/get_resources.rb +2 -1
- data/bolt-modules/boltlib/lib/puppet/functions/get_target.rb +1 -0
- data/bolt-modules/boltlib/lib/puppet/functions/get_targets.rb +1 -0
- data/bolt-modules/boltlib/lib/puppet/functions/puppetdb_fact.rb +1 -0
- data/bolt-modules/boltlib/lib/puppet/functions/puppetdb_query.rb +1 -0
- data/bolt-modules/boltlib/lib/puppet/functions/remove_from_group.rb +1 -0
- data/bolt-modules/boltlib/lib/puppet/functions/resolve_references.rb +1 -0
- data/bolt-modules/boltlib/lib/puppet/functions/resource.rb +53 -0
- data/bolt-modules/boltlib/lib/puppet/functions/run_command.rb +1 -0
- data/bolt-modules/boltlib/lib/puppet/functions/run_plan.rb +67 -1
- data/bolt-modules/boltlib/lib/puppet/functions/run_script.rb +1 -0
- data/bolt-modules/boltlib/lib/puppet/functions/run_task.rb +6 -3
- data/bolt-modules/boltlib/lib/puppet/functions/run_task_with.rb +8 -2
- data/bolt-modules/boltlib/lib/puppet/functions/set_config.rb +1 -0
- data/bolt-modules/boltlib/lib/puppet/functions/set_feature.rb +1 -0
- data/bolt-modules/boltlib/lib/puppet/functions/set_resources.rb +66 -43
- data/bolt-modules/boltlib/lib/puppet/functions/set_var.rb +1 -0
- data/bolt-modules/boltlib/lib/puppet/functions/upload_file.rb +1 -0
- data/bolt-modules/boltlib/lib/puppet/functions/vars.rb +1 -0
- data/bolt-modules/boltlib/lib/puppet/functions/wait_until_available.rb +1 -0
- data/bolt-modules/boltlib/lib/puppet/functions/without_default_logging.rb +1 -0
- data/bolt-modules/boltlib/lib/puppet/functions/write_file.rb +1 -0
- data/bolt-modules/ctrl/lib/puppet/functions/ctrl/do_until.rb +2 -0
- data/bolt-modules/ctrl/lib/puppet/functions/ctrl/sleep.rb +2 -0
- data/bolt-modules/file/lib/puppet/functions/file/exists.rb +2 -1
- data/bolt-modules/file/lib/puppet/functions/file/join.rb +2 -0
- data/bolt-modules/file/lib/puppet/functions/file/read.rb +3 -1
- data/bolt-modules/file/lib/puppet/functions/file/readable.rb +3 -1
- data/bolt-modules/file/lib/puppet/functions/file/write.rb +2 -0
- data/bolt-modules/out/lib/puppet/functions/out/message.rb +2 -0
- data/bolt-modules/prompt/lib/puppet/functions/prompt.rb +1 -0
- data/bolt-modules/system/lib/puppet/functions/system/env.rb +2 -0
- data/lib/bolt/analytics.rb +21 -2
- data/lib/bolt/applicator.rb +20 -7
- data/lib/bolt/apply_inventory.rb +4 -0
- data/lib/bolt/apply_target.rb +4 -0
- data/lib/bolt/bolt_option_parser.rb +11 -10
- data/lib/bolt/catalog.rb +81 -68
- data/lib/bolt/cli.rb +18 -8
- data/lib/bolt/config.rb +152 -120
- data/lib/bolt/config/options.rb +321 -0
- data/lib/bolt/config/transport/base.rb +16 -16
- data/lib/bolt/config/transport/docker.rb +9 -23
- data/lib/bolt/config/transport/local.rb +6 -44
- data/lib/bolt/config/transport/options.rb +305 -0
- data/lib/bolt/config/transport/orch.rb +9 -18
- data/lib/bolt/config/transport/remote.rb +3 -6
- data/lib/bolt/config/transport/ssh.rb +59 -114
- data/lib/bolt/config/transport/winrm.rb +18 -47
- data/lib/bolt/executor.rb +14 -1
- data/lib/bolt/inventory/group.rb +1 -1
- data/lib/bolt/inventory/inventory.rb +4 -14
- data/lib/bolt/inventory/target.rb +22 -5
- data/lib/bolt/outputter.rb +3 -0
- data/lib/bolt/outputter/rainbow.rb +80 -0
- data/lib/bolt/pal.rb +6 -1
- data/lib/bolt/project.rb +66 -46
- data/lib/bolt/resource_instance.rb +10 -3
- data/lib/bolt/shell/bash.rb +9 -9
- data/lib/bolt/shell/powershell.rb +2 -1
- data/lib/bolt/shell/powershell/snippets.rb +8 -0
- data/lib/bolt/transport/docker.rb +1 -1
- data/lib/bolt/transport/local/connection.rb +2 -1
- data/lib/bolt/transport/ssh/connection.rb +35 -0
- data/lib/bolt/version.rb +1 -1
- data/lib/bolt_spec/bolt_context.rb +1 -1
- data/lib/bolt_spec/run.rb +1 -1
- metadata +23 -5
data/lib/bolt/outputter.rb
CHANGED
@@ -8,6 +8,8 @@ module Bolt
|
|
8
8
|
Bolt::Outputter::Human.new(color, verbose, trace)
|
9
9
|
when 'json'
|
10
10
|
Bolt::Outputter::JSON.new(color, verbose, trace)
|
11
|
+
when 'rainbow'
|
12
|
+
Bolt::Outputter::Rainbow.new(color, verbose, trace)
|
11
13
|
when nil
|
12
14
|
raise "Cannot use outputter before parsing."
|
13
15
|
end
|
@@ -24,4 +26,5 @@ end
|
|
24
26
|
|
25
27
|
require 'bolt/outputter/human'
|
26
28
|
require 'bolt/outputter/json'
|
29
|
+
require 'bolt/outputter/rainbow'
|
27
30
|
require 'bolt/outputter/logger'
|
@@ -0,0 +1,80 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'bolt/pal'
|
4
|
+
require 'paint'
|
5
|
+
|
6
|
+
module Bolt
|
7
|
+
class Outputter
|
8
|
+
class Rainbow < Bolt::Outputter::Human
|
9
|
+
def initialize(color, verbose, trace, stream = $stdout)
|
10
|
+
super
|
11
|
+
@line_color = 0
|
12
|
+
@color = 0
|
13
|
+
@state = :normal
|
14
|
+
end
|
15
|
+
|
16
|
+
# The algorithm is from lolcat (https://github.com/busyloop/lolcat)
|
17
|
+
# lolcat is released with WTFPL
|
18
|
+
def rainbow
|
19
|
+
red = Math.sin(0.3 * @color + 0) * 127 + 128
|
20
|
+
green = Math.sin(0.3 * @color + 2 * Math::PI / 3) * 127 + 128
|
21
|
+
blue = Math.sin(0.3 * @color + 4 * Math::PI / 3) * 127 + 128
|
22
|
+
@color += 1 / 8.0
|
23
|
+
format("%<red>02X%<green>02X%<blue>02X", red: red, green: green, blue: blue)
|
24
|
+
end
|
25
|
+
|
26
|
+
def colorize(color, string)
|
27
|
+
if @color && @stream.isatty
|
28
|
+
if %i[green rainbow].include?(color)
|
29
|
+
a = string.chars.map do |c|
|
30
|
+
case @state
|
31
|
+
when :normal
|
32
|
+
if c == "\e"
|
33
|
+
@state = :ansi
|
34
|
+
elsif c == "\n"
|
35
|
+
@line_color += 1
|
36
|
+
@color = @line_color
|
37
|
+
c
|
38
|
+
else
|
39
|
+
Paint[c, rainbow]
|
40
|
+
end
|
41
|
+
when :ansi
|
42
|
+
@state = :normal if c == 'm'
|
43
|
+
end
|
44
|
+
end
|
45
|
+
a.join('')
|
46
|
+
else
|
47
|
+
"\033[#{COLORS[color]}m#{string}\033[0m"
|
48
|
+
end
|
49
|
+
else
|
50
|
+
string
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def print_summary(results, elapsed_time = nil)
|
55
|
+
ok_set = results.ok_set
|
56
|
+
unless ok_set.empty?
|
57
|
+
@stream.puts colorize(:rainbow, format('Successful on %<size>d target%<plural>s: %<names>s',
|
58
|
+
size: ok_set.size,
|
59
|
+
plural: ok_set.size == 1 ? '' : 's',
|
60
|
+
names: ok_set.targets.map(&:safe_name).join(',')))
|
61
|
+
end
|
62
|
+
|
63
|
+
error_set = results.error_set
|
64
|
+
unless error_set.empty?
|
65
|
+
@stream.puts colorize(:red,
|
66
|
+
format('Failed on %<size>d target%<plural>s: %<names>s',
|
67
|
+
size: error_set.size,
|
68
|
+
plural: error_set.size == 1 ? '' : 's',
|
69
|
+
names: error_set.targets.map(&:safe_name).join(',')))
|
70
|
+
end
|
71
|
+
|
72
|
+
total_msg = format('Ran on %<size>d target%<plural>s',
|
73
|
+
size: results.size,
|
74
|
+
plural: results.size == 1 ? '' : 's')
|
75
|
+
total_msg << " in #{duration_to_string(elapsed_time)}" unless elapsed_time.nil?
|
76
|
+
@stream.puts colorize(:rainbow, total_msg)
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
data/lib/bolt/pal.rb
CHANGED
@@ -137,7 +137,9 @@ module Bolt
|
|
137
137
|
# TODO: If we always call this inside a bolt_executor we can remove this here
|
138
138
|
setup
|
139
139
|
r = Puppet::Pal.in_tmp_environment('bolt', modulepath: @modulepath, facts: {}) do |pal|
|
140
|
-
|
140
|
+
# Only load the project if it a) exists, b) has a name it can be loaded with
|
141
|
+
bolt_project = @project if @project&.name
|
142
|
+
Puppet.override(bolt_project: bolt_project,
|
141
143
|
yaml_plan_instantiator: Bolt::PAL::YamlPlan::Loader) do
|
142
144
|
pal.with_script_compiler do |compiler|
|
143
145
|
alias_types(compiler)
|
@@ -190,6 +192,7 @@ module Bolt
|
|
190
192
|
# versions of "core" types, which are already present on the agent,
|
191
193
|
# but may cause issues on Puppet 5 agents.
|
192
194
|
@original_modulepath,
|
195
|
+
@project,
|
193
196
|
pdb_client,
|
194
197
|
@hiera_config,
|
195
198
|
@max_compiles,
|
@@ -359,6 +362,7 @@ module Bolt
|
|
359
362
|
name = param.name
|
360
363
|
if signature_params.include?(name)
|
361
364
|
params[name] = { 'type' => param.types.first }
|
365
|
+
params[name]['sensitive'] = param.types.first =~ /\ASensitive(\[.*\])?\z/ ? true : false
|
362
366
|
params[name]['default_value'] = defaults[name] if defaults.key?(name)
|
363
367
|
params[name]['description'] = param.text unless param.text.empty?
|
364
368
|
else
|
@@ -390,6 +394,7 @@ module Bolt
|
|
390
394
|
param.type_expr
|
391
395
|
end
|
392
396
|
params[name] = { 'type' => type_str }
|
397
|
+
params[name]['sensitive'] = param.type_expr.instance_of?(Puppet::Pops::Types::PSensitiveType)
|
393
398
|
params[name]['default_value'] = param.value
|
394
399
|
params[name]['description'] = param.description if param.description
|
395
400
|
end
|
data/lib/bolt/project.rb
CHANGED
@@ -2,21 +2,27 @@
|
|
2
2
|
|
3
3
|
require 'pathname'
|
4
4
|
require 'bolt/pal'
|
5
|
+
require 'bolt/config'
|
5
6
|
|
6
7
|
module Bolt
|
7
8
|
class Project
|
8
9
|
BOLTDIR_NAME = 'Boltdir'
|
9
10
|
PROJECT_SETTINGS = {
|
10
11
|
"name" => "The name of the project",
|
11
|
-
"plans" => "An array of plan names to
|
12
|
-
|
12
|
+
"plans" => "An array of plan names to show, if they exist in the project."\
|
13
|
+
"These plans are included in `bolt plan show` output",
|
14
|
+
"tasks" => "An array of task names to show, if they exist in the project."\
|
15
|
+
"These tasks are included in `bolt task show` output"
|
13
16
|
}.freeze
|
14
17
|
|
15
|
-
attr_reader :path, :config_file, :inventory_file, :modulepath, :hiera_config,
|
16
|
-
:puppetfile, :rerunfile, :type, :resource_types
|
18
|
+
attr_reader :path, :data, :config_file, :inventory_file, :modulepath, :hiera_config,
|
19
|
+
:puppetfile, :rerunfile, :type, :resource_types, :warnings, :project_file
|
17
20
|
|
18
21
|
def self.default_project
|
19
|
-
|
22
|
+
create_project(File.expand_path(File.join('~', '.puppetlabs', 'bolt')), 'user')
|
23
|
+
# If homedir isn't defined use the system config path
|
24
|
+
rescue ArgumentError
|
25
|
+
create_project(Bolt::Config.system_path, 'system')
|
20
26
|
end
|
21
27
|
|
22
28
|
# Search recursively up the directory hierarchy for the Project. Look for a
|
@@ -26,9 +32,9 @@ module Bolt
|
|
26
32
|
def self.find_boltdir(dir)
|
27
33
|
dir = Pathname.new(dir)
|
28
34
|
if (dir + BOLTDIR_NAME).directory?
|
29
|
-
|
35
|
+
create_project(dir + BOLTDIR_NAME, 'embedded')
|
30
36
|
elsif (dir + 'bolt.yaml').file? || (dir + 'bolt-project.yaml').file?
|
31
|
-
|
37
|
+
create_project(dir, 'local')
|
32
38
|
elsif dir.root?
|
33
39
|
default_project
|
34
40
|
else
|
@@ -36,9 +42,25 @@ module Bolt
|
|
36
42
|
end
|
37
43
|
end
|
38
44
|
|
39
|
-
def
|
45
|
+
def self.create_project(path, type = 'option')
|
46
|
+
fullpath = Pathname.new(path).expand_path
|
47
|
+
project_file = File.join(fullpath, 'bolt-project.yaml')
|
48
|
+
data = Bolt::Util.read_optional_yaml_hash(File.expand_path(project_file), 'project')
|
49
|
+
new(data, path, type)
|
50
|
+
end
|
51
|
+
|
52
|
+
def initialize(raw_data, path, type = 'option')
|
40
53
|
@path = Pathname.new(path).expand_path
|
41
|
-
@
|
54
|
+
@project_file = @path + 'bolt-project.yaml'
|
55
|
+
|
56
|
+
@warnings = []
|
57
|
+
if (@path + 'bolt.yaml').file? && project_file?
|
58
|
+
msg = "Project-level configuration in bolt.yaml is deprecated if using bolt-project.yaml. "\
|
59
|
+
"Transport config should be set in inventory.yaml, all other config should be set in "\
|
60
|
+
"bolt-project.yaml."
|
61
|
+
@warnings << { msg: msg }
|
62
|
+
end
|
63
|
+
|
42
64
|
@inventory_file = @path + 'inventory.yaml'
|
43
65
|
@modulepath = [(@path + 'modules').to_s, (@path + 'site-modules').to_s, (@path + 'site').to_s]
|
44
66
|
@hiera_config = @path + 'hiera.yaml'
|
@@ -47,9 +69,26 @@ module Bolt
|
|
47
69
|
@resource_types = @path + '.resource_types'
|
48
70
|
@type = type
|
49
71
|
|
50
|
-
|
51
|
-
|
52
|
-
|
72
|
+
tc = Bolt::Config::INVENTORY_OPTIONS.keys & raw_data.keys
|
73
|
+
if tc.any?
|
74
|
+
msg = "Transport configuration isn't supported in bolt-project.yaml. Ignoring keys #{tc}"
|
75
|
+
@warnings << { msg: msg }
|
76
|
+
end
|
77
|
+
|
78
|
+
@data = raw_data.reject { |k, _| Bolt::Config::INVENTORY_OPTIONS.include?(k) }
|
79
|
+
|
80
|
+
# Once bolt.yaml deprecation is removed, this attribute should be removed
|
81
|
+
# and replaced with .project_file in lib/bolt/config.rb
|
82
|
+
@config_file = if (Bolt::Config::BOLT_OPTIONS & @data.keys).any?
|
83
|
+
if (@path + 'bolt.yaml').file?
|
84
|
+
msg = "bolt-project.yaml contains valid config keys, bolt.yaml will be ignored"
|
85
|
+
@warnings << { msg: msg }
|
86
|
+
end
|
87
|
+
@project_file
|
88
|
+
else
|
89
|
+
@path + 'bolt.yaml'
|
90
|
+
end
|
91
|
+
validate if project_file?
|
53
92
|
end
|
54
93
|
|
55
94
|
def to_s
|
@@ -67,15 +106,12 @@ module Bolt
|
|
67
106
|
end
|
68
107
|
alias == eql?
|
69
108
|
|
70
|
-
def
|
109
|
+
def project_file?
|
71
110
|
@project_file.file?
|
72
111
|
end
|
73
112
|
|
74
113
|
def name
|
75
|
-
|
76
|
-
dirname = @path.basename.to_s == 'Boltdir' ? @path.parent.basename.to_s : @path.basename.to_s
|
77
|
-
pname = @data['name'] || dirname
|
78
|
-
pname.include?('-') ? pname.split('-', 2)[1] : pname
|
114
|
+
@data['name']
|
79
115
|
end
|
80
116
|
|
81
117
|
def tasks
|
@@ -86,36 +122,20 @@ module Bolt
|
|
86
122
|
@data['plans']
|
87
123
|
end
|
88
124
|
|
89
|
-
def project_directory_name?(name)
|
90
|
-
# it must match an installed project name according to forge validator
|
91
|
-
name =~ /^[a-z][a-z0-9_]*$/
|
92
|
-
end
|
93
|
-
|
94
|
-
def project_namespaced_name?(name)
|
95
|
-
# it must match the full project name according to forge validator
|
96
|
-
name =~ /^[a-zA-Z0-9]+[-][a-z][a-z0-9_]*$/
|
97
|
-
end
|
98
|
-
|
99
125
|
def validate
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
Configure project name in <project_dir>/bolt-project.yaml
|
114
|
-
ERROR_STRING
|
115
|
-
# If the project name is the same as one of the built-in modules raise a warning
|
116
|
-
elsif Dir.children(Bolt::PAL::BOLTLIB_PATH).include?(name)
|
117
|
-
raise Bolt::ValidationError, "The project '#{name}' will not be loaded. The project name conflicts "\
|
118
|
-
"with a built-in Bolt module of the same name."
|
126
|
+
if name
|
127
|
+
name_regex = /^[a-z][a-z0-9_]*$/
|
128
|
+
if name !~ name_regex
|
129
|
+
raise Bolt::ValidationError, <<~ERROR_STRING
|
130
|
+
Invalid project name '#{name}' in bolt-project.yaml; project name must match #{name_regex.inspect}
|
131
|
+
ERROR_STRING
|
132
|
+
elsif Dir.children(Bolt::PAL::BOLTLIB_PATH).include?(name)
|
133
|
+
raise Bolt::ValidationError, "The project '#{name}' will not be loaded. The project name conflicts "\
|
134
|
+
"with a built-in Bolt module of the same name."
|
135
|
+
end
|
136
|
+
else
|
137
|
+
message = "No project name is specified in bolt-project.yaml. Project-level content will not be available."
|
138
|
+
@warnings << { msg: message }
|
119
139
|
end
|
120
140
|
|
121
141
|
%w[tasks plans].each do |conf|
|
@@ -30,8 +30,7 @@ module Bolt
|
|
30
30
|
@target = resource_hash['target']
|
31
31
|
@type = resource_hash['type'].to_s.capitalize
|
32
32
|
@title = resource_hash['title']
|
33
|
-
|
34
|
-
@state = resource_hash['state'] || resource_hash['parameters'] || {}
|
33
|
+
@state = resource_hash['state'] || {}
|
35
34
|
@desired_state = resource_hash['desired_state'] || {}
|
36
35
|
@events = resource_hash['events'] || []
|
37
36
|
end
|
@@ -84,11 +83,19 @@ module Bolt
|
|
84
83
|
to_hash.to_json(opts)
|
85
84
|
end
|
86
85
|
|
86
|
+
def self.format_reference(type, title)
|
87
|
+
"#{type.capitalize}[#{title}]"
|
88
|
+
end
|
89
|
+
|
87
90
|
def reference
|
88
|
-
|
91
|
+
self.class.format_reference(@type, @title)
|
89
92
|
end
|
90
93
|
alias to_s reference
|
91
94
|
|
95
|
+
def [](attribute)
|
96
|
+
@state[attribute]
|
97
|
+
end
|
98
|
+
|
92
99
|
def add_event(event)
|
93
100
|
@events << event
|
94
101
|
end
|
data/lib/bolt/shell/bash.rb
CHANGED
@@ -35,7 +35,7 @@ module Bolt
|
|
35
35
|
def upload(source, destination, options = {})
|
36
36
|
running_as(options[:run_as]) do
|
37
37
|
with_tmpdir do |dir|
|
38
|
-
basename = File.basename(
|
38
|
+
basename = File.basename(source)
|
39
39
|
tmpfile = File.join(dir.to_s, basename)
|
40
40
|
conn.copy_file(source, tmpfile)
|
41
41
|
# pass over file ownership if we're using run-as to be a different user
|
@@ -332,14 +332,14 @@ module Bolt
|
|
332
332
|
end
|
333
333
|
|
334
334
|
if escalate
|
335
|
-
if use_sudo
|
336
|
-
|
337
|
-
|
338
|
-
|
339
|
-
|
340
|
-
|
341
|
-
|
342
|
-
|
335
|
+
sudo_str = if use_sudo
|
336
|
+
sudo_exec = target.options['sudo-executable'] || "sudo"
|
337
|
+
sudo_flags = [sudo_exec, "-S", "-H", "-u", run_as, "-p", sudo_prompt]
|
338
|
+
sudo_flags += ["-E"] if options[:environment]
|
339
|
+
Shellwords.shelljoin(sudo_flags)
|
340
|
+
else
|
341
|
+
Shellwords.shelljoin(@target.options['run-as-command'] + [run_as])
|
342
|
+
end
|
343
343
|
command_str = build_sudoable_command_str(command_str, sudo_str, @sudo_id, options)
|
344
344
|
end
|
345
345
|
|
@@ -111,7 +111,8 @@ module Bolt
|
|
111
111
|
end
|
112
112
|
|
113
113
|
def mkdirs(dirs)
|
114
|
-
|
114
|
+
paths = dirs.uniq.sort.join('","')
|
115
|
+
mkdir_command = "mkdir -Force -Path (\"#{paths}\")"
|
115
116
|
result = execute(mkdir_command)
|
116
117
|
if result.exit_code != 0
|
117
118
|
message = "Could not create directories: #{result.stderr.string}"
|
@@ -20,7 +20,7 @@ module Bolt
|
|
20
20
|
def upload(target, source, destination, _options = {})
|
21
21
|
with_connection(target) do |conn|
|
22
22
|
conn.with_remote_tmpdir do |dir|
|
23
|
-
basename = File.basename(
|
23
|
+
basename = File.basename(source)
|
24
24
|
tmpfile = "#{dir}/#{basename}"
|
25
25
|
if File.directory?(source)
|
26
26
|
conn.write_remote_directory(source, tmpfile)
|
@@ -50,7 +50,8 @@ module Bolt
|
|
50
50
|
# If it's already a powershell command then invoke it normally.
|
51
51
|
# Otherwise, wrap it in powershell.exe.
|
52
52
|
unless command.start_with?('powershell.exe')
|
53
|
-
|
53
|
+
cmd = Bolt::Shell::Powershell::Snippets.exit_with_code(command)
|
54
|
+
command = ['powershell.exe', *Bolt::Shell::Powershell::PS_ARGS, '-Command', cmd]
|
54
55
|
end
|
55
56
|
end
|
56
57
|
|
@@ -78,6 +78,28 @@ module Bolt
|
|
78
78
|
|
79
79
|
options[:proxy] = Net::SSH::Proxy::Jump.new(target.options['proxyjump']) if target.options['proxyjump']
|
80
80
|
|
81
|
+
# Override the default supported algorithms for net-ssh. By default, a subset of supported algorithms
|
82
|
+
# are enabled in 6.x, while several are deprecated and not enabled by default. The *-algorithms
|
83
|
+
# options can be used to specify a list of algorithms to enable in net-ssh. Any algorithms not in the
|
84
|
+
# list are disabled, including ones that are normally enabled by default. Support for deprecated
|
85
|
+
# algorithms will be removed in 7.x.
|
86
|
+
# https://github.com/net-ssh/net-ssh#supported-algorithms
|
87
|
+
if target.options['encryption-algorithms']
|
88
|
+
options[:encryption] = net_ssh_algorithms(:encryption, target.options['encryption-algorithms'])
|
89
|
+
end
|
90
|
+
|
91
|
+
if target.options['host-key-algorithms']
|
92
|
+
options[:host_key] = net_ssh_algorithms(:host_key, target.options['host-key-algorithms'])
|
93
|
+
end
|
94
|
+
|
95
|
+
if target.options['kex-algorithms']
|
96
|
+
options[:kex] = net_ssh_algorithms(:kex, target.options['kex-algorithms'])
|
97
|
+
end
|
98
|
+
|
99
|
+
if target.options['mac-algorithms']
|
100
|
+
options[:hmac] = net_ssh_algorithms(:hmac, target.options['mac-algorithms'])
|
101
|
+
end
|
102
|
+
|
81
103
|
# This option was to address discrepency betwen net-ssh host-key-check and ssh(1)
|
82
104
|
# For the net-ssh 5.x series it defaults to true, in 6.x it will default to false, and will be removed in 7.x
|
83
105
|
# https://github.com/net-ssh/net-ssh/pull/663#issuecomment-469979931
|
@@ -246,6 +268,19 @@ module Bolt
|
|
246
268
|
end
|
247
269
|
end
|
248
270
|
|
271
|
+
# Add all default algorithms if the 'defaults' key is present and filter
|
272
|
+
# out any unsupported algorithms.
|
273
|
+
def net_ssh_algorithms(type, algorithms)
|
274
|
+
if algorithms.include?('defaults')
|
275
|
+
defaults = Net::SSH::Transport::Algorithms::DEFAULT_ALGORITHMS[type]
|
276
|
+
algorithms += defaults
|
277
|
+
end
|
278
|
+
|
279
|
+
known = Net::SSH::Transport::Algorithms::ALGORITHMS[type]
|
280
|
+
|
281
|
+
algorithms & known
|
282
|
+
end
|
283
|
+
|
249
284
|
def shell
|
250
285
|
@shell ||= if target.options['login-shell'] == 'powershell'
|
251
286
|
Bolt::Shell::Powershell.new(target, self)
|