bolt 0.13.0 → 0.14.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/exe/bolt +0 -1
- data/lib/bolt/cli.rb +22 -30
- data/lib/bolt/config.rb +15 -13
- data/lib/bolt/execution_result.rb +2 -2
- data/lib/bolt/executor.rb +50 -15
- data/lib/bolt/logger.rb +56 -0
- data/lib/bolt/node.rb +4 -14
- data/lib/bolt/node/ssh.rb +2 -8
- data/lib/bolt/node/winrm.rb +16 -9
- data/lib/bolt/outputter/human.rb +3 -1
- data/lib/bolt/version.rb +1 -1
- metadata +4 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6515bd6a3cf63131c23e0809aa98a057030977a3
|
4
|
+
data.tar.gz: eee81f558aefb21e761082b04bd73bd631e6685d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5598b32bf144d8fe0a2cc0601f5ec136235646b182c1a4dc9c4f00aef467f6ea88cdcfcdec25c4fbf88241aa3485d5e9317f34a5d44d8a982f81725678ce8f1b
|
7
|
+
data.tar.gz: 2aac3a8c35530eecaf1e57e206d24f8ae3c0f4eb0f53199ff4d14c491cbef873a8b0791843242fb5ff5890393356da0f0f1235b815d093f075c31938cf1d2e4d
|
data/exe/bolt
CHANGED
data/lib/bolt/cli.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
require 'uri'
|
2
2
|
require 'optparse'
|
3
3
|
require 'benchmark'
|
4
|
-
require 'logger'
|
4
|
+
require 'bolt/logger'
|
5
5
|
require 'json'
|
6
6
|
require 'bolt/node'
|
7
7
|
require 'bolt/version'
|
@@ -109,7 +109,6 @@ HELP
|
|
109
109
|
}
|
110
110
|
@config = Bolt::Config.new
|
111
111
|
@parser = create_option_parser(@options)
|
112
|
-
@logger = Logger.new(STDERR)
|
113
112
|
end
|
114
113
|
|
115
114
|
def create_option_parser(results)
|
@@ -249,6 +248,7 @@ HELP
|
|
249
248
|
|
250
249
|
@config.load_file(options[:configfile])
|
251
250
|
@config.update_from_cli(options)
|
251
|
+
Logger.configure(@config)
|
252
252
|
@config.validate
|
253
253
|
|
254
254
|
# This section handles parsing non-flag options which are
|
@@ -272,6 +272,9 @@ HELP
|
|
272
272
|
validate(options)
|
273
273
|
|
274
274
|
options
|
275
|
+
rescue Bolt::CLIError => e
|
276
|
+
warn e.message
|
277
|
+
raise e
|
275
278
|
end
|
276
279
|
|
277
280
|
def print_help(mode)
|
@@ -417,11 +420,11 @@ HELP
|
|
417
420
|
return
|
418
421
|
end
|
419
422
|
|
420
|
-
executor = Bolt::Executor.new(@config, options[:noop])
|
421
|
-
|
422
423
|
if options[:mode] == 'plan'
|
424
|
+
executor = Bolt::Executor.new(@config, options[:noop], true)
|
423
425
|
execute_plan(executor, options)
|
424
426
|
else
|
427
|
+
executor = Bolt::Executor.new(@config, options[:noop])
|
425
428
|
nodes = executor.from_uris(options[:nodes])
|
426
429
|
|
427
430
|
results = nil
|
@@ -478,8 +481,6 @@ HELP
|
|
478
481
|
options[:task_options],
|
479
482
|
&block)
|
480
483
|
end
|
481
|
-
rescue Puppet::Error
|
482
|
-
raise Bolt::CLIError, "Exiting because of an error in Puppet code"
|
483
484
|
end
|
484
485
|
|
485
486
|
def execute_plan(executor, options)
|
@@ -489,8 +490,6 @@ HELP
|
|
489
490
|
options[:task_options])
|
490
491
|
end
|
491
492
|
outputter.print_plan(result)
|
492
|
-
rescue Puppet::Error
|
493
|
-
raise Bolt::CLIError, "Exiting because of an error in Puppet code"
|
494
493
|
end
|
495
494
|
|
496
495
|
def validate_file(type, path)
|
@@ -517,13 +516,24 @@ HELP
|
|
517
516
|
@outputter ||= Bolt::Outputter.for_format(@config[:format])
|
518
517
|
end
|
519
518
|
|
519
|
+
# Runs a block in a PAL script compiler configured for Bolt.
|
520
|
+
# Catches exceptions thrown by the block and re-raises them as Bolt::CLIError.
|
520
521
|
def in_bolt_compiler(opts = [])
|
521
522
|
Puppet.initialize_settings(opts)
|
522
|
-
Puppet::Pal.in_tmp_environment('bolt', modulepath: [BOLTLIB_PATH] + @config[:modulepath], facts: {}) do |pal|
|
523
|
+
r = Puppet::Pal.in_tmp_environment('bolt', modulepath: [BOLTLIB_PATH] + @config[:modulepath], facts: {}) do |pal|
|
523
524
|
pal.with_script_compiler do |compiler|
|
524
|
-
|
525
|
+
begin
|
526
|
+
yield compiler
|
527
|
+
rescue Puppet::PreformattedError => err
|
528
|
+
err.cause
|
529
|
+
rescue StandardError => err
|
530
|
+
err
|
531
|
+
end
|
525
532
|
end
|
526
533
|
end
|
534
|
+
|
535
|
+
raise Bolt::CLIError, r.message if r.is_a? StandardError
|
536
|
+
r
|
527
537
|
end
|
528
538
|
|
529
539
|
def list_tasks
|
@@ -534,16 +544,12 @@ HELP
|
|
534
544
|
[task_name, task_sig.task.description]
|
535
545
|
end
|
536
546
|
end
|
537
|
-
rescue Puppet::Error
|
538
|
-
raise Bolt::CLIError, "Failure while reading task metadata"
|
539
547
|
end
|
540
548
|
|
541
549
|
def list_plans
|
542
550
|
in_bolt_compiler do |compiler|
|
543
551
|
compiler.list_plans.map { |plan| [plan.name] }.sort
|
544
552
|
end
|
545
|
-
rescue Puppet::Error
|
546
|
-
raise Bolt::CLIError, "Failure while reading plans"
|
547
553
|
end
|
548
554
|
|
549
555
|
def get_task_info(task_name)
|
@@ -552,26 +558,12 @@ HELP
|
|
552
558
|
end
|
553
559
|
raise Bolt::CLIError, "Could not find task #{task_name} in your modulepath" if task.nil?
|
554
560
|
task.task_hash
|
555
|
-
rescue Puppet::Error
|
556
|
-
raise Bolt::CLIError, "Failure while reading task metadata"
|
557
561
|
end
|
558
562
|
|
559
563
|
def run_task(name, nodes, args, &block)
|
560
|
-
|
561
|
-
|
562
|
-
begin
|
563
|
-
compiler.call_function('run_task', name, nodes, args, &block)
|
564
|
-
rescue Puppet::ParseError => e
|
565
|
-
# we assume that the Puppet::ParseError is due to a problem with
|
566
|
-
# the task and/or its parameters, but since the with_script_compiler
|
567
|
-
# method rescues these errors and raises different ones instead,
|
568
|
-
# we save it in a local variable and raise it as Bolt::CLIError
|
569
|
-
# outside of the block
|
570
|
-
parse_error = e
|
571
|
-
end
|
564
|
+
in_bolt_compiler do |compiler|
|
565
|
+
compiler.call_function('run_task', name, nodes, args, &block)
|
572
566
|
end
|
573
|
-
raise Bolt::CLIError, parse_error.message if parse_error
|
574
|
-
result
|
575
567
|
end
|
576
568
|
|
577
569
|
# Expects to be called with a configured Puppet compiler or error.instance? will fail
|
data/lib/bolt/config.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
require 'logger'
|
1
|
+
require 'bolt/logger'
|
2
2
|
require 'yaml'
|
3
3
|
require 'bolt/cli'
|
4
4
|
|
@@ -6,7 +6,6 @@ module Bolt
|
|
6
6
|
Config = Struct.new(
|
7
7
|
:concurrency,
|
8
8
|
:format,
|
9
|
-
:log_destination,
|
10
9
|
:log_level,
|
11
10
|
:modulepath,
|
12
11
|
:transport,
|
@@ -16,12 +15,10 @@ module Bolt
|
|
16
15
|
DEFAULTS = {
|
17
16
|
concurrency: 100,
|
18
17
|
transport: 'ssh',
|
19
|
-
format: 'human'
|
20
|
-
log_level: Logger::WARN,
|
21
|
-
log_destination: STDERR
|
18
|
+
format: 'human'
|
22
19
|
}.freeze
|
23
20
|
|
24
|
-
TRANSPORT_OPTIONS = %i[insecure password run_as sudo_password
|
21
|
+
TRANSPORT_OPTIONS = %i[insecure password run_as sudo_password extensions
|
25
22
|
key tty tmpdir user connect_timeout cacert
|
26
23
|
token_file orch_task_environment service_url].freeze
|
27
24
|
|
@@ -61,7 +58,7 @@ module Bolt
|
|
61
58
|
if path.nil?
|
62
59
|
found_default = default_paths.select { |p| File.exist?(p) }
|
63
60
|
if found_default.size > 1
|
64
|
-
logger = Logger.
|
61
|
+
logger = Logger.get_logger
|
65
62
|
logger.warn "Config files found at #{found_default.join(', ')}, using the first"
|
66
63
|
end
|
67
64
|
# Use first found, fall back to first default and try to load even if it didn't exist
|
@@ -130,6 +127,11 @@ module Bolt
|
|
130
127
|
if data['winrm']['cacert']
|
131
128
|
self[:transports][:winrm][:cacert] = data['winrm']['cacert']
|
132
129
|
end
|
130
|
+
if data['winrm']['extensions']
|
131
|
+
# Accept a single entry or a list, ensure each is prefixed with '.'
|
132
|
+
self[:transports][:winrm][:extensions] =
|
133
|
+
[data['winrm']['extensions']].flatten.map { |ext| ext[0] != '.' ? '.' + ext : ext }
|
134
|
+
end
|
133
135
|
end
|
134
136
|
|
135
137
|
if data['pcp']
|
@@ -170,12 +172,6 @@ module Bolt
|
|
170
172
|
self[:transports][transport][key] = options[key] if options[key]
|
171
173
|
end
|
172
174
|
end
|
173
|
-
|
174
|
-
if options[:sudo_password] && self[:transports][:ssh][:run_as].nil?
|
175
|
-
logger = Logger.new(self[:log_destination])
|
176
|
-
logger.warn("'--sudo-password will not be used without specifying a" \
|
177
|
-
"user to escalate to with --run-as")
|
178
|
-
end
|
179
175
|
end
|
180
176
|
|
181
177
|
def validate
|
@@ -187,6 +183,12 @@ module Bolt
|
|
187
183
|
raise Bolt::CLIError, "Unsupported format: '#{self[:format]}'"
|
188
184
|
end
|
189
185
|
|
186
|
+
if self[:transports][:ssh][:sudo_password] && self[:transports][:ssh][:run_as].nil?
|
187
|
+
logger = Logger.get_logger
|
188
|
+
logger.warn("--sudo-password will not be used without specifying a " \
|
189
|
+
"user to escalate to with --run-as")
|
190
|
+
end
|
191
|
+
|
190
192
|
self[:transports].each_value do |v|
|
191
193
|
timeout_value = v[:connect_timeout]
|
192
194
|
unless timeout_value.is_a?(Integer) || timeout_value.nil?
|
@@ -47,7 +47,7 @@ module Bolt
|
|
47
47
|
|
48
48
|
def error_nodes
|
49
49
|
result = {}
|
50
|
-
@result_hash.each_pair { |k, v| result[k] = v if v.is_a?(Error) }
|
50
|
+
@result_hash.each_pair { |k, v| result[k] = v if v.is_a?(Puppet::DataTypes::Error) }
|
51
51
|
self.class.new(result, true)
|
52
52
|
end
|
53
53
|
|
@@ -56,7 +56,7 @@ module Bolt
|
|
56
56
|
end
|
57
57
|
|
58
58
|
def ok
|
59
|
-
@result_hash.values.none? { |v| v.is_a?(Error) }
|
59
|
+
@result_hash.values.none? { |v| v.is_a?(Puppet::DataTypes::Error) }
|
60
60
|
end
|
61
61
|
alias ok? ok
|
62
62
|
|
data/lib/bolt/executor.rb
CHANGED
@@ -1,22 +1,20 @@
|
|
1
|
-
require 'logger'
|
1
|
+
require 'bolt/logger'
|
2
|
+
require 'json'
|
2
3
|
require 'concurrent'
|
3
4
|
require 'bolt/result'
|
4
5
|
require 'bolt/config'
|
5
|
-
require 'bolt/formatter'
|
6
6
|
require 'bolt/notifier'
|
7
7
|
|
8
8
|
module Bolt
|
9
9
|
class Executor
|
10
10
|
attr_reader :noop
|
11
11
|
|
12
|
-
def initialize(config = Bolt::Config.new, noop = nil)
|
12
|
+
def initialize(config = Bolt::Config.new, noop = nil, plan_logging = false)
|
13
13
|
@config = config
|
14
|
-
@logger = Logger.
|
15
|
-
@logger.progname = 'executor'
|
16
|
-
@logger.level = config[:log_level]
|
17
|
-
@logger.formatter = Bolt::Formatter.new
|
14
|
+
@logger = Logger.get_logger(progname: 'executor')
|
18
15
|
@noop = noop
|
19
16
|
@notifier = Bolt::Notifier.new
|
17
|
+
@plan_logging = plan_logging
|
20
18
|
end
|
21
19
|
|
22
20
|
def from_uris(nodes)
|
@@ -67,36 +65,73 @@ module Bolt
|
|
67
65
|
results_to_hash(results)
|
68
66
|
end
|
69
67
|
|
68
|
+
def summary(action, object, result)
|
69
|
+
fc = result.select { |_, r| r.error }.length
|
70
|
+
npl = result.length == 1 ? '' : 's'
|
71
|
+
fpl = fc == 1 ? '' : 's'
|
72
|
+
"Ran #{action} '#{object}' on #{result.length} node#{npl} with #{fc} failure#{fpl}"
|
73
|
+
end
|
74
|
+
|
70
75
|
def run_command(nodes, command)
|
76
|
+
level = @plan_logging ? Logger::NOTICE : Logger::INFO
|
77
|
+
@logger.log(level, "Starting command run '#{command}' on #{nodes.map(&:uri)}")
|
71
78
|
callback = block_given? ? Proc.new : nil
|
72
79
|
|
73
|
-
on(nodes, callback) do |node|
|
74
|
-
|
80
|
+
r = on(nodes, callback) do |node|
|
81
|
+
@logger.debug("Running command '#{command}' on #{node.uri}")
|
82
|
+
node_result = node.run_command(command)
|
83
|
+
@logger.debug("Result on #{node.uri}: #{JSON.dump(node_result.to_result)}")
|
84
|
+
node_result
|
75
85
|
end
|
86
|
+
@logger.log(level, summary('command', command, r))
|
87
|
+
r
|
76
88
|
end
|
77
89
|
|
78
90
|
def run_script(nodes, script, arguments)
|
91
|
+
level = @plan_logging ? Logger::NOTICE : Logger::INFO
|
92
|
+
@logger.log(level, "Starting script run #{script} on #{nodes.map(&:uri)}")
|
93
|
+
@logger.debug("Arguments: #{arguments}")
|
79
94
|
callback = block_given? ? Proc.new : nil
|
80
95
|
|
81
|
-
on(nodes, callback) do |node|
|
82
|
-
|
96
|
+
r = on(nodes, callback) do |node|
|
97
|
+
@logger.debug { "Running script '#{script}' on #{node.uri}" }
|
98
|
+
node_result = node.run_script(script, arguments)
|
99
|
+
@logger.debug("Result on #{node.uri}: #{JSON.dump(node_result.to_result)}")
|
100
|
+
node_result
|
83
101
|
end
|
102
|
+
@logger.log(level, summary('script', script, r))
|
103
|
+
r
|
84
104
|
end
|
85
105
|
|
86
106
|
def run_task(nodes, task, input_method, arguments)
|
107
|
+
level = @plan_logging ? Logger::NOTICE : Logger::INFO
|
108
|
+
@logger.log(level, "Starting task #{task} on #{nodes.map(&:uri)}")
|
109
|
+
@logger.debug("Arguments: #{arguments} Input method: #{input_method}")
|
87
110
|
callback = block_given? ? Proc.new : nil
|
88
111
|
|
89
|
-
on(nodes, callback) do |node|
|
90
|
-
|
112
|
+
r = on(nodes, callback) do |node|
|
113
|
+
@logger.debug { "Running task run '#{task}' on #{node.uri}" }
|
114
|
+
node_result = node.run_task(task, input_method, arguments)
|
115
|
+
@logger.debug("Result on #{node.uri}: #{JSON.dump(node_result.to_result)}")
|
116
|
+
node_result
|
91
117
|
end
|
118
|
+
@logger.log(level, summary('task', task, r))
|
119
|
+
r
|
92
120
|
end
|
93
121
|
|
94
122
|
def file_upload(nodes, source, destination)
|
123
|
+
level = @plan_logging ? Logger::NOTICE : Logger::INFO
|
124
|
+
@logger.log(level, "Starting file upload from #{source} to #{destination} on #{nodes.map(&:uri)}")
|
95
125
|
callback = block_given? ? Proc.new : nil
|
96
126
|
|
97
|
-
on(nodes, callback) do |node|
|
98
|
-
|
127
|
+
r = on(nodes, callback) do |node|
|
128
|
+
@logger.debug { "Uploading: '#{source}' to #{node.uri}" }
|
129
|
+
node_result = node.upload(source, destination)
|
130
|
+
@logger.debug("Result on #{node.uri}: #{JSON.dump(node_result.to_result)}")
|
131
|
+
node_result
|
99
132
|
end
|
133
|
+
@logger.log(level, summary('upload', source, r))
|
134
|
+
r
|
100
135
|
end
|
101
136
|
|
102
137
|
private
|
data/lib/bolt/logger.rb
ADDED
@@ -0,0 +1,56 @@
|
|
1
|
+
require 'logger'
|
2
|
+
require 'bolt/formatter'
|
3
|
+
|
4
|
+
class Logger
|
5
|
+
send :remove_const, 'SEV_LABEL'
|
6
|
+
|
7
|
+
SEV_LABEL = {
|
8
|
+
0 => 'DEBUG',
|
9
|
+
1 => 'INFO',
|
10
|
+
2 => 'NOTICE',
|
11
|
+
3 => 'WARN',
|
12
|
+
4 => 'ERROR',
|
13
|
+
5 => 'FATAL',
|
14
|
+
6 => 'ANY'
|
15
|
+
}.freeze
|
16
|
+
|
17
|
+
module Severity
|
18
|
+
levels = %w[WARN ERROR FATAL ANY]
|
19
|
+
levels.each do |level|
|
20
|
+
send(:remove_const, level) if const_defined?(level)
|
21
|
+
end
|
22
|
+
NOTICE = 2
|
23
|
+
WARN = 3
|
24
|
+
ERROR = 4
|
25
|
+
FATAL = 5
|
26
|
+
ANY = 6
|
27
|
+
end
|
28
|
+
|
29
|
+
def notice(progname = nil, &block)
|
30
|
+
add(NOTICE, nil, progname, &block)
|
31
|
+
end
|
32
|
+
|
33
|
+
def notice?
|
34
|
+
@level <= NOTICE
|
35
|
+
end
|
36
|
+
|
37
|
+
# rubocop:disable Style/ClassVars
|
38
|
+
@@config = {
|
39
|
+
log_destination: STDERR,
|
40
|
+
log_level: NOTICE
|
41
|
+
}
|
42
|
+
|
43
|
+
# Not thread safe call only during startup
|
44
|
+
def self.configure(config)
|
45
|
+
@@config[:log_level] = config[:log_level] if config[:log_level]
|
46
|
+
end
|
47
|
+
|
48
|
+
def self.get_logger(**conf)
|
49
|
+
conf = @@config.merge(conf)
|
50
|
+
logger = new(conf[:log_destination])
|
51
|
+
logger.level = conf[:log_level]
|
52
|
+
logger.progname = conf[:progname] if conf[:progname]
|
53
|
+
logger.formatter = Bolt::Formatter.new
|
54
|
+
logger
|
55
|
+
end
|
56
|
+
end
|
data/lib/bolt/node.rb
CHANGED
@@ -1,6 +1,5 @@
|
|
1
|
-
require 'logger'
|
1
|
+
require 'bolt/logger'
|
2
2
|
require 'bolt/node_uri'
|
3
|
-
require 'bolt/formatter'
|
4
3
|
require 'bolt/result'
|
5
4
|
require 'bolt/config'
|
6
5
|
require 'bolt/target'
|
@@ -52,17 +51,10 @@ module Bolt
|
|
52
51
|
@service_url = transport_conf[:service_url]
|
53
52
|
@token_file = transport_conf[:token_file]
|
54
53
|
@orch_task_environment = transport_conf[:orch_task_environment]
|
54
|
+
@extensions = transport_conf[:extensions]
|
55
55
|
|
56
|
-
@logger =
|
57
|
-
@transport_logger =
|
58
|
-
end
|
59
|
-
|
60
|
-
def init_logger(destination, level)
|
61
|
-
logger = Logger.new(destination)
|
62
|
-
logger.progname = @host
|
63
|
-
logger.level = level
|
64
|
-
logger.formatter = Bolt::Formatter.new
|
65
|
-
logger
|
56
|
+
@logger = Logger.get_logger(progname: @host)
|
57
|
+
@transport_logger = Logger.get_logger(progname: @host, log_level: Logger::WARN)
|
66
58
|
end
|
67
59
|
|
68
60
|
def upload(source, destination)
|
@@ -76,12 +68,10 @@ module Bolt
|
|
76
68
|
end
|
77
69
|
|
78
70
|
def run_command(command)
|
79
|
-
@logger.info { "Running command: #{command}" }
|
80
71
|
_run_command(command)
|
81
72
|
end
|
82
73
|
|
83
74
|
def run_script(script, arguments)
|
84
|
-
@logger.info { "Running script: #{script}" }
|
85
75
|
_run_script(script, arguments)
|
86
76
|
end
|
87
77
|
|
data/lib/bolt/node/ssh.rb
CHANGED
@@ -82,13 +82,13 @@ module Bolt
|
|
82
82
|
)
|
83
83
|
end
|
84
84
|
elsif data =~ /^#{@user} is not in the sudoers file\./
|
85
|
-
@logger.
|
85
|
+
@logger.debug { data }
|
86
86
|
raise Bolt::Node::EscalateError.new(
|
87
87
|
"User #{@user} does not have sudo permission on #{@uri}",
|
88
88
|
'SUDO_DENIED'
|
89
89
|
)
|
90
90
|
elsif data =~ /^Sorry, try again\./
|
91
|
-
@logger.
|
91
|
+
@logger.debug { data }
|
92
92
|
raise Bolt::Node::EscalateError.new(
|
93
93
|
"Sudo password for user #{@user} not recognized on #{@uri}",
|
94
94
|
'BAD_PASSWORD'
|
@@ -260,9 +260,6 @@ SCRIPT
|
|
260
260
|
end
|
261
261
|
|
262
262
|
def _run_script(script, arguments)
|
263
|
-
@logger.info { "Running script '#{script}'" }
|
264
|
-
@logger.debug { "arguments: #{arguments}" }
|
265
|
-
|
266
263
|
with_remote_file(script) do |remote_path|
|
267
264
|
output = execute("'#{remote_path}' #{Shellwords.join(arguments)}",
|
268
265
|
sudoable: true)
|
@@ -278,9 +275,6 @@ SCRIPT
|
|
278
275
|
export_args = {}
|
279
276
|
stdin, output = nil
|
280
277
|
|
281
|
-
@logger.info { "Running task '#{task}'" }
|
282
|
-
@logger.debug { "arguments: #{arguments}\ninput_method: #{input_method}" }
|
283
|
-
|
284
278
|
if STDIN_METHODS.include?(input_method)
|
285
279
|
stdin = JSON.dump(arguments)
|
286
280
|
end
|
data/lib/bolt/node/winrm.rb
CHANGED
@@ -2,6 +2,7 @@ require 'winrm'
|
|
2
2
|
require 'winrm-fs'
|
3
3
|
require 'bolt/result'
|
4
4
|
require 'base64'
|
5
|
+
require 'set'
|
5
6
|
|
6
7
|
module Bolt
|
7
8
|
class WinRM < Node
|
@@ -16,6 +17,8 @@ module Bolt
|
|
16
17
|
|
17
18
|
def initialize(host, port, user, password, **kwargs)
|
18
19
|
super(host, port, user, password, **kwargs)
|
20
|
+
@extensions = DEFAULT_EXTENSIONS.to_set.merge(@extensions || [])
|
21
|
+
@logger.debug { "WinRM initialized for #{@extensions.to_a} extensions" }
|
19
22
|
end
|
20
23
|
|
21
24
|
def connect
|
@@ -401,7 +404,7 @@ exit $(Invoke-Interpreter @invokeArgs)
|
|
401
404
|
PS
|
402
405
|
end
|
403
406
|
|
404
|
-
|
407
|
+
DEFAULT_EXTENSIONS = ['.ps1', '.rb', '.pp'].freeze
|
405
408
|
|
406
409
|
PS_ARGS = %w[
|
407
410
|
-NoProfile -NonInteractive -NoLogo -ExecutionPolicy Bypass
|
@@ -428,6 +431,12 @@ PS
|
|
428
431
|
'puppet.bat',
|
429
432
|
['apply', "\"#{path}\""]
|
430
433
|
]
|
434
|
+
else
|
435
|
+
# Run the script via cmd, letting Windows extension handling determine how
|
436
|
+
[
|
437
|
+
'cmd.exe',
|
438
|
+
['/c', "\"#{path}\""]
|
439
|
+
]
|
431
440
|
end
|
432
441
|
end
|
433
442
|
|
@@ -440,7 +449,6 @@ PS
|
|
440
449
|
end
|
441
450
|
|
442
451
|
def write_remote_file(source, destination)
|
443
|
-
@logger.debug { "Uploading #{source} to #{destination}" }
|
444
452
|
fs = ::WinRM::FS::FileManager.new(@connection)
|
445
453
|
# TODO: raise FileError here if this fails
|
446
454
|
fs.upload(source, destination)
|
@@ -463,10 +471,13 @@ PS
|
|
463
471
|
|
464
472
|
def with_remote_file(file)
|
465
473
|
ext = File.extname(file)
|
466
|
-
|
467
|
-
|
474
|
+
unless @extensions.include?(ext)
|
475
|
+
raise FileError.new("File extension #{ext} is not enabled, "\
|
476
|
+
"to run it please add to 'winrm: extensions'", 'FILETYPE_ERROR')
|
477
|
+
end
|
478
|
+
file_base = File.basename(file)
|
468
479
|
dir = make_tempdir
|
469
|
-
dest = "#{dir}\\#{file_base}
|
480
|
+
dest = "#{dir}\\#{file_base}"
|
470
481
|
begin
|
471
482
|
write_remote_file(file, dest)
|
472
483
|
shell_init
|
@@ -488,7 +499,6 @@ PS
|
|
488
499
|
end
|
489
500
|
|
490
501
|
def _run_script(script, arguments)
|
491
|
-
@logger.info { "Running script '#{script}'" }
|
492
502
|
with_remote_file(script) do |remote_path|
|
493
503
|
if powershell_file?(remote_path)
|
494
504
|
mapped_args = arguments.map do |a|
|
@@ -523,9 +533,6 @@ catch
|
|
523
533
|
end
|
524
534
|
|
525
535
|
def _run_task(task, input_method, arguments)
|
526
|
-
@logger.info { "Running task '#{task}'" }
|
527
|
-
@logger.debug { "arguments: #{arguments}\ninput_method: #{input_method}" }
|
528
|
-
|
529
536
|
if STDIN_METHODS.include?(input_method)
|
530
537
|
stdin = JSON.dump(arguments)
|
531
538
|
end
|
data/lib/bolt/outputter/human.rb
CHANGED
data/lib/bolt/version.rb
CHANGED
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: 0.
|
4
|
+
version: 0.14.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Puppet
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-01-
|
11
|
+
date: 2018-01-11 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: addressable
|
@@ -312,6 +312,7 @@ files:
|
|
312
312
|
- lib/bolt/execution_result.rb
|
313
313
|
- lib/bolt/executor.rb
|
314
314
|
- lib/bolt/formatter.rb
|
315
|
+
- lib/bolt/logger.rb
|
315
316
|
- lib/bolt/node.rb
|
316
317
|
- lib/bolt/node/errors.rb
|
317
318
|
- lib/bolt/node/orch.rb
|
@@ -1577,7 +1578,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
1577
1578
|
version: '0'
|
1578
1579
|
requirements: []
|
1579
1580
|
rubyforge_project:
|
1580
|
-
rubygems_version: 2.
|
1581
|
+
rubygems_version: 2.6.12
|
1581
1582
|
signing_key:
|
1582
1583
|
specification_version: 4
|
1583
1584
|
summary: Execute commands remotely over SSH and WinRM
|