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.

@@ -1,8 +1,11 @@
1
1
  Puppet::DataTypes.create_type('Target') do
2
2
  interface <<-PUPPET
3
3
  attributes => {
4
- host => String[1],
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
- repeated_param 'TargetOrTargets', :targets
18
- return_type 'ExecutionResult'
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, *targets)
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.flatten.map { |t| t.is_a?(String) ? Bolt::Target.new(t) : t }
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::ExecutionResult::EMPTY_RESULT
51
+ r = Bolt::ResultSet.new([])
47
52
  else
48
- # Awaits change in the executor, enabling it receive Target instances
49
- hosts = targets.map(&:host)
53
+ r = executor.file_upload(targets, found, destination)
54
+ end
50
55
 
51
- Bolt::ExecutionResult.from_bolt(
52
- executor.file_upload(executor.from_uris(hosts), found, destination)
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
- repeated_param 'TargetOrTargets', :targets
16
- return_type 'ExecutionResult'
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, *targets)
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.flatten.map { |t| t.is_a?(String) ? Bolt::Target.new(t) : t }
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::ExecutionResult::EMPTY_RESULT
43
+ r = Bolt::ResultSet.new([])
39
44
  else
40
- # Awaits change in the executor, enabling it receive Target instances
41
- hosts = targets.map(&:host)
45
+ r = executor.run_command(targets, command)
46
+ end
42
47
 
43
- Bolt::ExecutionResult.from_bolt(executor.run_command(executor.from_uris(hosts), command))
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
- repeated_param 'TargetOrTargets', :targets
25
- return_type 'ExecutionResult'
26
- end
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 run_script_with_args(scope, script, targets, args_hash)
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.new(t) : t }
60
- if targets.empty?
61
- call_function('debug', "Simulating run_script of '#{found}' - no targets given - no action taken")
62
- Bolt::ExecutionResult::EMPTY_RESULT
63
- else
64
- # Awaits change in the executor, enabling it receive Target instances
65
- hosts = targets.map(&:host)
66
-
67
- Bolt::ExecutionResult.from_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 'ExecutionResult'
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
- Bolt::ExecutionResult.from_bolt(
30
- run_task_raw(task_name, targets, task_args)
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.nil? ? {} : 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.new(t) : t }
85
+ targets = targets.flatten.map { |t| t.is_a?(String) ? Bolt::Target.from_uri(t) : t }
78
86
  if targets.empty?
79
- call_function('debug', "Simulating run of task #{task.name} - no targets given - no action taken")
80
- Puppet::Pops::EMPTY_HASH
87
+ Bolt::ResultSet.new([])
81
88
  else
82
- # TODO: Awaits change in the executor, enabling it receive Target instances
83
- hosts = targets.map(&:host)
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.14.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 00:00:00.000000000 Z
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: '1.0'
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: '1.0'
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/executionresult.rb
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.6.12
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
@@ -1,9 +0,0 @@
1
- require 'logger'
2
-
3
- module Bolt
4
- class Formatter < Logger::Formatter
5
- def call(severity, time, progname, msg)
6
- "#{format_datetime(time)} #{severity} #{progname}: #{msg2str(msg)}\n"
7
- end
8
- end
9
- end