bolt 0.14.0 → 0.15.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 +3 -2
- data/lib/bolt/cli.rb +99 -92
- data/lib/bolt/config.rb +7 -8
- data/lib/bolt/error.rb +20 -3
- data/lib/bolt/executor.rb +44 -45
- data/lib/bolt/logger.rb +28 -52
- data/lib/bolt/node.rb +12 -41
- data/lib/bolt/node/orch.rb +28 -34
- data/lib/bolt/node/ssh.rb +26 -21
- data/lib/bolt/node/winrm.rb +41 -19
- data/lib/bolt/notifier.rb +2 -2
- data/lib/bolt/outputter/human.rb +34 -29
- data/lib/bolt/outputter/json.rb +4 -10
- data/lib/bolt/pal.rb +106 -0
- data/lib/bolt/result.rb +90 -87
- data/lib/bolt/result_set.rb +94 -0
- data/lib/bolt/target.rb +61 -13
- data/lib/bolt/version.rb +1 -1
- data/modules/boltlib/lib/puppet/datatypes/result.rb +18 -0
- data/modules/boltlib/lib/puppet/datatypes/resultset.rb +22 -0
- data/modules/boltlib/lib/puppet/datatypes/target.rb +4 -1
- data/modules/boltlib/lib/puppet/functions/file_upload.rb +15 -10
- data/modules/boltlib/lib/puppet/functions/run_command.rb +15 -8
- data/modules/boltlib/lib/puppet/functions/run_script.rb +15 -26
- data/modules/boltlib/lib/puppet/functions/run_task.rb +17 -15
- metadata +23 -9
- data/lib/bolt/execution_result.rb +0 -109
- data/lib/bolt/formatter.rb +0 -9
- data/lib/bolt/node_uri.rb +0 -42
- data/modules/boltlib/lib/puppet/datatypes/executionresult.rb +0 -30
@@ -1,8 +1,11 @@
|
|
1
1
|
Puppet::DataTypes.create_type('Target') do
|
2
2
|
interface <<-PUPPET
|
3
3
|
attributes => {
|
4
|
-
|
4
|
+
uri => String[1],
|
5
5
|
options => { type => Hash[String[1], Data], value => {} }
|
6
|
+
},
|
7
|
+
functions => {
|
8
|
+
name => Callable[[], String[1]],
|
6
9
|
}
|
7
10
|
PUPPET
|
8
11
|
|
@@ -5,6 +5,8 @@
|
|
5
5
|
# * A target is a String with a targets's hostname or a Target.
|
6
6
|
# * The returned value contains information about the result per target.
|
7
7
|
#
|
8
|
+
require 'bolt/error'
|
9
|
+
|
8
10
|
Puppet::Functions.create_function(:file_upload, Puppet::Functions::InternalFunction) do
|
9
11
|
local_types do
|
10
12
|
type 'TargetOrTargets = Variant[String[1], Target, Array[TargetOrTargets]]'
|
@@ -14,11 +16,13 @@ Puppet::Functions.create_function(:file_upload, Puppet::Functions::InternalFunct
|
|
14
16
|
scope_param
|
15
17
|
param 'String[1]', :source
|
16
18
|
param 'String[1]', :destination
|
17
|
-
|
18
|
-
|
19
|
+
param 'TargetOrTargets', :targets
|
20
|
+
optional_param 'Hash[String[1], Any]', :options
|
21
|
+
return_type 'ResultSet'
|
19
22
|
end
|
20
23
|
|
21
|
-
def file_upload(scope, source, destination,
|
24
|
+
def file_upload(scope, source, destination, targets, options = nil)
|
25
|
+
options ||= {}
|
22
26
|
unless Puppet[:tasks]
|
23
27
|
raise Puppet::ParseErrorWithIssue.from_issue_and_stack(
|
24
28
|
Puppet::Pops::Issues::TASK_OPERATION_NOT_SUPPORTED_WHEN_COMPILING, operation: 'file_upload'
|
@@ -40,17 +44,18 @@ Puppet::Functions.create_function(:file_upload, Puppet::Functions::InternalFunct
|
|
40
44
|
end
|
41
45
|
|
42
46
|
# Ensure that that given targets are all Target instances
|
43
|
-
targets = targets
|
47
|
+
targets = [targets] unless targets.is_a?(Array)
|
48
|
+
targets = targets.flatten.map { |t| t.is_a?(String) ? Bolt::Target.from_uri(t) : t }
|
44
49
|
if targets.empty?
|
45
50
|
call_function('debug', "Simulating file upload of '#{found}' - no targets given - no action taken")
|
46
|
-
Bolt::
|
51
|
+
r = Bolt::ResultSet.new([])
|
47
52
|
else
|
48
|
-
|
49
|
-
|
53
|
+
r = executor.file_upload(targets, found, destination)
|
54
|
+
end
|
50
55
|
|
51
|
-
|
52
|
-
|
53
|
-
)
|
56
|
+
if !r.ok && !options['_catch_errors']
|
57
|
+
raise Bolt::RunFailure.new(r, 'upload_file', source)
|
54
58
|
end
|
59
|
+
r
|
55
60
|
end
|
56
61
|
end
|
@@ -5,6 +5,8 @@
|
|
5
5
|
# * A target is a String with a targets's hostname or a Target.
|
6
6
|
# * The returned value contains information about the result per target.
|
7
7
|
#
|
8
|
+
require 'bolt/error'
|
9
|
+
|
8
10
|
Puppet::Functions.create_function(:run_command) do
|
9
11
|
local_types do
|
10
12
|
type 'TargetOrTargets = Variant[String[1], Target, Array[TargetOrTargets]]'
|
@@ -12,11 +14,13 @@ Puppet::Functions.create_function(:run_command) do
|
|
12
14
|
|
13
15
|
dispatch :run_command do
|
14
16
|
param 'String[1]', :command
|
15
|
-
|
16
|
-
|
17
|
+
param 'TargetOrTargets', :targets
|
18
|
+
optional_param 'Hash[String[1], Any]', :options
|
19
|
+
return_type 'ResultSet'
|
17
20
|
end
|
18
21
|
|
19
|
-
def run_command(command,
|
22
|
+
def run_command(command, targets, options = nil)
|
23
|
+
options ||= {}
|
20
24
|
unless Puppet[:tasks]
|
21
25
|
raise Puppet::ParseErrorWithIssue.from_issue_and_stack(
|
22
26
|
Puppet::Pops::Issues::TASK_OPERATION_NOT_SUPPORTED_WHEN_COMPILING, operation: 'run_command'
|
@@ -31,16 +35,19 @@ Puppet::Functions.create_function(:run_command) do
|
|
31
35
|
end
|
32
36
|
|
33
37
|
# Ensure that that given targets are all Target instances
|
34
|
-
targets = targets
|
38
|
+
targets = [targets] unless targets.is_a?(Array)
|
39
|
+
targets = targets.flatten.map { |t| t.is_a?(String) ? Bolt::Target.from_uri(t) : t }
|
35
40
|
|
36
41
|
if targets.empty?
|
37
42
|
call_function('debug', "Simulating run_command('#{command}') - no targets given - no action taken")
|
38
|
-
Bolt::
|
43
|
+
r = Bolt::ResultSet.new([])
|
39
44
|
else
|
40
|
-
|
41
|
-
|
45
|
+
r = executor.run_command(targets, command)
|
46
|
+
end
|
42
47
|
|
43
|
-
|
48
|
+
if !r.ok && !options['_catch_errors']
|
49
|
+
raise Bolt::RunFailure.new(r, 'run_command', command)
|
44
50
|
end
|
51
|
+
r
|
45
52
|
end
|
46
53
|
end
|
@@ -10,26 +10,16 @@ Puppet::Functions.create_function(:run_script, Puppet::Functions::InternalFuncti
|
|
10
10
|
type 'TargetOrTargets = Variant[String[1], Target, Array[TargetOrTargets]]'
|
11
11
|
end
|
12
12
|
|
13
|
-
dispatch :run_script_with_args do
|
14
|
-
scope_param
|
15
|
-
param 'String[1]', :script
|
16
|
-
param 'TargetOrTargets', :targets
|
17
|
-
param 'Struct[arguments => Array[String]]', :arguments
|
18
|
-
return_type 'ExecutionResult'
|
19
|
-
end
|
20
|
-
|
21
13
|
dispatch :run_script do
|
22
14
|
scope_param
|
23
15
|
param 'String[1]', :script
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
def run_script(scope, script, *targets)
|
29
|
-
run_script_with_args(scope, script, targets, 'arguments' => [])
|
16
|
+
param 'TargetOrTargets', :targets
|
17
|
+
optional_param 'Hash[String[1], Any]', :options
|
18
|
+
return_type 'ResultSet'
|
30
19
|
end
|
31
20
|
|
32
|
-
def
|
21
|
+
def run_script(scope, script, targets, options = nil)
|
22
|
+
options ||= {}
|
33
23
|
unless Puppet[:tasks]
|
34
24
|
raise Puppet::ParseErrorWithIssue.from_issue_and_stack(
|
35
25
|
Puppet::Pops::Issues::TASK_OPERATION_NOT_SUPPORTED_WHEN_COMPILING, operation: 'run_script'
|
@@ -56,17 +46,16 @@ Puppet::Functions.create_function(:run_script, Puppet::Functions::InternalFuncti
|
|
56
46
|
end
|
57
47
|
|
58
48
|
# Ensure that that given targets are all Target instances)
|
59
|
-
targets = [targets].flatten.map { |t| t.is_a?(String) ? Bolt::Target.
|
60
|
-
if targets.empty?
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
Bolt::
|
68
|
-
executor.run_script(executor.from_uris(hosts), found, args_hash['arguments'])
|
69
|
-
)
|
49
|
+
targets = [targets].flatten.map { |t| t.is_a?(String) ? Bolt::Target.from_uri(t) : t }
|
50
|
+
r = if targets.empty?
|
51
|
+
Bolt::ResultSet.new([])
|
52
|
+
else
|
53
|
+
executor.run_script(targets, found, options['arguments'] || [])
|
54
|
+
end
|
55
|
+
|
56
|
+
if !r.ok && !options['_catch_errors']
|
57
|
+
raise Bolt::RunFailure.new(r, 'run_script', script)
|
70
58
|
end
|
59
|
+
r
|
71
60
|
end
|
72
61
|
end
|
@@ -5,6 +5,8 @@
|
|
5
5
|
# * A target is a String with a targets's hostname or a Target.
|
6
6
|
# * The returned value contains information about the result per target.
|
7
7
|
#
|
8
|
+
require 'bolt/error'
|
9
|
+
|
8
10
|
Puppet::Functions.create_function(:run_task) do
|
9
11
|
local_types do
|
10
12
|
type 'TargetOrTargets = Variant[String[1], Target, Array[TargetOrTargets]]'
|
@@ -14,7 +16,7 @@ Puppet::Functions.create_function(:run_task) do
|
|
14
16
|
param 'String[1]', :task_name
|
15
17
|
param 'TargetOrTargets', :targets
|
16
18
|
optional_param 'Hash[String[1], Any]', :task_args
|
17
|
-
return_type '
|
19
|
+
return_type 'ResultSet'
|
18
20
|
end
|
19
21
|
|
20
22
|
# this is used from 'bolt task run'
|
@@ -22,16 +24,21 @@ Puppet::Functions.create_function(:run_task) do
|
|
22
24
|
param 'String[1]', :task_name
|
23
25
|
param 'TargetOrTargets', :targets
|
24
26
|
optional_param 'Hash[String[1], Any]', :task_args
|
27
|
+
# return_type 'ResultSet'
|
25
28
|
block_param
|
26
29
|
end
|
27
30
|
|
28
31
|
def run_task(task_name, targets, task_args = nil)
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
+
task_args ||= {}
|
33
|
+
r = run_task_raw(task_name, targets, task_args)
|
34
|
+
if !r.ok && !task_args['_catch_errors']
|
35
|
+
raise Bolt::RunFailure.new(r, 'run_task', task_name)
|
36
|
+
end
|
37
|
+
r
|
32
38
|
end
|
33
39
|
|
34
40
|
def run_task_raw(task_name, targets, task_args = nil, &block)
|
41
|
+
task_args ||= {}
|
35
42
|
unless Puppet[:tasks]
|
36
43
|
raise Puppet::ParseErrorWithIssue.from_issue_and_stack(
|
37
44
|
Puppet::Pops::Issues::TASK_OPERATION_NOT_SUPPORTED_WHEN_COMPILING, operation: 'run_task'
|
@@ -53,7 +60,8 @@ Puppet::Functions.create_function(:run_task) do
|
|
53
60
|
)
|
54
61
|
end
|
55
62
|
|
56
|
-
use_args = task_args.
|
63
|
+
use_args = task_args.reject { |k, _| k.start_with?('_') }
|
64
|
+
|
57
65
|
task_signature.runnable_with?(use_args) do |mismatch|
|
58
66
|
raise Puppet::ParseError, mismatch
|
59
67
|
end || (raise Puppet::ParseError, 'Task parameters did not match')
|
@@ -74,18 +82,12 @@ Puppet::Functions.create_function(:run_task) do
|
|
74
82
|
|
75
83
|
# Ensure that that given targets are all Target instances
|
76
84
|
targets = [targets] unless targets.is_a?(Array)
|
77
|
-
targets = targets.flatten.map { |t| t.is_a?(String) ? Bolt::Target.
|
85
|
+
targets = targets.flatten.map { |t| t.is_a?(String) ? Bolt::Target.from_uri(t) : t }
|
78
86
|
if targets.empty?
|
79
|
-
|
80
|
-
Puppet::Pops::EMPTY_HASH
|
87
|
+
Bolt::ResultSet.new([])
|
81
88
|
else
|
82
|
-
# TODO:
|
83
|
-
|
84
|
-
|
85
|
-
# TODO: separate handling of default since it's platform specific
|
86
|
-
input_method = task.input_method
|
87
|
-
|
88
|
-
executor.run_task(executor.from_uris(hosts), task.executable, input_method, use_args, &block)
|
89
|
+
# TODO: pass entire task to executor
|
90
|
+
executor.run_task(targets, task.executable, task.input_method, use_args, &block)
|
89
91
|
end
|
90
92
|
end
|
91
93
|
end
|
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.15.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-25 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: addressable
|
@@ -114,14 +114,28 @@ dependencies:
|
|
114
114
|
requirements:
|
115
115
|
- - "~>"
|
116
116
|
- !ruby/object:Gem::Version
|
117
|
-
version:
|
117
|
+
version: 1.1.0
|
118
118
|
type: :runtime
|
119
119
|
prerelease: false
|
120
120
|
version_requirements: !ruby/object:Gem::Requirement
|
121
121
|
requirements:
|
122
122
|
- - "~>"
|
123
123
|
- !ruby/object:Gem::Version
|
124
|
-
version:
|
124
|
+
version: 1.1.0
|
125
|
+
- !ruby/object:Gem::Dependency
|
126
|
+
name: logging
|
127
|
+
requirement: !ruby/object:Gem::Requirement
|
128
|
+
requirements:
|
129
|
+
- - "~>"
|
130
|
+
- !ruby/object:Gem::Version
|
131
|
+
version: '2.2'
|
132
|
+
type: :runtime
|
133
|
+
prerelease: false
|
134
|
+
version_requirements: !ruby/object:Gem::Requirement
|
135
|
+
requirements:
|
136
|
+
- - "~>"
|
137
|
+
- !ruby/object:Gem::Version
|
138
|
+
version: '2.2'
|
125
139
|
- !ruby/object:Gem::Dependency
|
126
140
|
name: CFPropertyList
|
127
141
|
requirement: !ruby/object:Gem::Requirement
|
@@ -309,9 +323,7 @@ files:
|
|
309
323
|
- lib/bolt/cli.rb
|
310
324
|
- lib/bolt/config.rb
|
311
325
|
- lib/bolt/error.rb
|
312
|
-
- lib/bolt/execution_result.rb
|
313
326
|
- lib/bolt/executor.rb
|
314
|
-
- lib/bolt/formatter.rb
|
315
327
|
- lib/bolt/logger.rb
|
316
328
|
- lib/bolt/node.rb
|
317
329
|
- lib/bolt/node/errors.rb
|
@@ -319,15 +331,17 @@ files:
|
|
319
331
|
- lib/bolt/node/output.rb
|
320
332
|
- lib/bolt/node/ssh.rb
|
321
333
|
- lib/bolt/node/winrm.rb
|
322
|
-
- lib/bolt/node_uri.rb
|
323
334
|
- lib/bolt/notifier.rb
|
324
335
|
- lib/bolt/outputter.rb
|
325
336
|
- lib/bolt/outputter/human.rb
|
326
337
|
- lib/bolt/outputter/json.rb
|
338
|
+
- lib/bolt/pal.rb
|
327
339
|
- lib/bolt/result.rb
|
340
|
+
- lib/bolt/result_set.rb
|
328
341
|
- lib/bolt/target.rb
|
329
342
|
- lib/bolt/version.rb
|
330
|
-
- modules/boltlib/lib/puppet/datatypes/
|
343
|
+
- modules/boltlib/lib/puppet/datatypes/result.rb
|
344
|
+
- modules/boltlib/lib/puppet/datatypes/resultset.rb
|
331
345
|
- modules/boltlib/lib/puppet/datatypes/target.rb
|
332
346
|
- modules/boltlib/lib/puppet/functions/file_upload.rb
|
333
347
|
- modules/boltlib/lib/puppet/functions/run_command.rb
|
@@ -1578,7 +1592,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
1578
1592
|
version: '0'
|
1579
1593
|
requirements: []
|
1580
1594
|
rubyforge_project:
|
1581
|
-
rubygems_version: 2.
|
1595
|
+
rubygems_version: 2.5.1
|
1582
1596
|
signing_key:
|
1583
1597
|
specification_version: 4
|
1584
1598
|
summary: Execute commands remotely over SSH and WinRM
|
@@ -1,109 +0,0 @@
|
|
1
|
-
module Bolt
|
2
|
-
class ExecutionResult
|
3
|
-
if Object.const_defined?(:Puppet) && Puppet.const_defined?(:Pops)
|
4
|
-
include Puppet::Pops::Types::Iterable
|
5
|
-
include Puppet::Pops::Types::IteratorProducer
|
6
|
-
|
7
|
-
def iterator
|
8
|
-
tc = Puppet::Pops::Types::TypeFactory
|
9
|
-
Puppet::Pops::Types::Iterable.on(
|
10
|
-
@result_hash,
|
11
|
-
tc.tuple([tc.string, tc.data], Puppet::Pops::Types::PHashType::KEY_PAIR_TUPLE_SIZE)
|
12
|
-
)
|
13
|
-
end
|
14
|
-
|
15
|
-
def to_s
|
16
|
-
@result_hash.to_s
|
17
|
-
end
|
18
|
-
else
|
19
|
-
def iterator
|
20
|
-
@result_hash.each
|
21
|
-
end
|
22
|
-
end
|
23
|
-
|
24
|
-
# Creates a pure Data hash from a result hash returned from the Bolt::Executor
|
25
|
-
# @return [Hash{String => Data}] The data hash
|
26
|
-
def self.from_bolt(result_hash)
|
27
|
-
data_result = {}
|
28
|
-
result_hash.each_pair { |k, v| data_result[k.uri] = v.to_h }
|
29
|
-
new(data_result)
|
30
|
-
end
|
31
|
-
|
32
|
-
attr_reader :result_hash
|
33
|
-
|
34
|
-
def initialize(result_hash, final = false)
|
35
|
-
result_hash = convert_errors(result_hash) unless final
|
36
|
-
@result_hash = result_hash
|
37
|
-
end
|
38
|
-
|
39
|
-
def count
|
40
|
-
@result_hash.size
|
41
|
-
end
|
42
|
-
|
43
|
-
def empty
|
44
|
-
@result_hash.empty?
|
45
|
-
end
|
46
|
-
alias empty? empty
|
47
|
-
|
48
|
-
def error_nodes
|
49
|
-
result = {}
|
50
|
-
@result_hash.each_pair { |k, v| result[k] = v if v.is_a?(Puppet::DataTypes::Error) }
|
51
|
-
self.class.new(result, true)
|
52
|
-
end
|
53
|
-
|
54
|
-
def names
|
55
|
-
@result_hash.keys
|
56
|
-
end
|
57
|
-
|
58
|
-
def ok
|
59
|
-
@result_hash.values.none? { |v| v.is_a?(Puppet::DataTypes::Error) }
|
60
|
-
end
|
61
|
-
alias ok? ok
|
62
|
-
|
63
|
-
def ok_nodes
|
64
|
-
result = {}
|
65
|
-
@result_hash.each_pair { |k, v| result[k] = v unless v.is_a?(Error) }
|
66
|
-
self.class.new(result, true)
|
67
|
-
end
|
68
|
-
|
69
|
-
def [](node_uri)
|
70
|
-
@result_hash[node_uri]
|
71
|
-
end
|
72
|
-
|
73
|
-
def value(node_uri)
|
74
|
-
self[node_uri]
|
75
|
-
end
|
76
|
-
|
77
|
-
def values
|
78
|
-
@result_hash.values
|
79
|
-
end
|
80
|
-
|
81
|
-
def _pcore_init_hash
|
82
|
-
@result_hash
|
83
|
-
end
|
84
|
-
|
85
|
-
def eql?(other)
|
86
|
-
self.class == other.class && @result_hash == other.result_hash
|
87
|
-
end
|
88
|
-
|
89
|
-
def ==(other)
|
90
|
-
eql?(other)
|
91
|
-
end
|
92
|
-
|
93
|
-
private
|
94
|
-
|
95
|
-
def convert_errors(result_hash)
|
96
|
-
converted = {}
|
97
|
-
result_hash.each_pair { |k, v| converted[k] = convert_error(v) }
|
98
|
-
converted
|
99
|
-
end
|
100
|
-
|
101
|
-
def convert_error(value_or_error)
|
102
|
-
e = value_or_error['error']
|
103
|
-
v = value_or_error['value']
|
104
|
-
e.nil? ? v : Puppet::DataTypes::Error.new(e['msg'], e['kind'], e['issue_code'], v, e['details'])
|
105
|
-
end
|
106
|
-
|
107
|
-
EMPTY_RESULT = new({})
|
108
|
-
end
|
109
|
-
end
|