bolt 3.1.0 → 3.6.1
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 +11 -11
- data/bolt-modules/boltlib/lib/puppet/datatypes/containerresult.rb +24 -0
- data/bolt-modules/boltlib/lib/puppet/functions/add_facts.rb +1 -1
- data/bolt-modules/boltlib/lib/puppet/functions/run_command.rb +20 -2
- data/bolt-modules/boltlib/lib/puppet/functions/run_container.rb +162 -0
- data/bolt-modules/boltlib/lib/puppet/functions/run_plan.rb +2 -2
- data/bolt-modules/boltlib/lib/puppet/functions/run_script.rb +44 -5
- data/bolt-modules/boltlib/lib/puppet/functions/upload_file.rb +1 -1
- data/bolt-modules/boltlib/types/planresult.pp +1 -0
- data/bolt-modules/file/lib/puppet/functions/file/read.rb +3 -2
- data/bolt-modules/prompt/lib/puppet/functions/prompt.rb +20 -2
- data/bolt-modules/prompt/lib/puppet/functions/prompt/menu.rb +103 -0
- data/lib/bolt/analytics.rb +4 -8
- data/lib/bolt/apply_result.rb +1 -1
- data/lib/bolt/bolt_option_parser.rb +6 -3
- data/lib/bolt/cli.rb +121 -36
- data/lib/bolt/config.rb +15 -7
- data/lib/bolt/config/options.rb +62 -12
- data/lib/bolt/config/transport/lxd.rb +23 -0
- data/lib/bolt/config/transport/options.rb +8 -1
- data/lib/bolt/config/transport/podman.rb +33 -0
- data/lib/bolt/container_result.rb +105 -0
- data/lib/bolt/error.rb +15 -0
- data/lib/bolt/executor.rb +37 -18
- data/lib/bolt/inventory/options.rb +9 -0
- data/lib/bolt/inventory/target.rb +16 -0
- data/lib/bolt/logger.rb +8 -0
- data/lib/bolt/module_installer.rb +2 -2
- data/lib/bolt/module_installer/puppetfile.rb +2 -2
- data/lib/bolt/module_installer/specs/forge_spec.rb +2 -2
- data/lib/bolt/module_installer/specs/git_spec.rb +2 -2
- data/lib/bolt/node/output.rb +14 -4
- data/lib/bolt/outputter/human.rb +259 -90
- data/lib/bolt/outputter/json.rb +3 -1
- data/lib/bolt/outputter/logger.rb +17 -0
- data/lib/bolt/pal.rb +24 -4
- data/lib/bolt/pal/yaml_plan.rb +1 -2
- data/lib/bolt/pal/yaml_plan/evaluator.rb +5 -141
- data/lib/bolt/pal/yaml_plan/step.rb +91 -31
- data/lib/bolt/pal/yaml_plan/step/command.rb +21 -13
- data/lib/bolt/pal/yaml_plan/step/download.rb +15 -16
- data/lib/bolt/pal/yaml_plan/step/eval.rb +11 -11
- data/lib/bolt/pal/yaml_plan/step/message.rb +13 -4
- data/lib/bolt/pal/yaml_plan/step/plan.rb +19 -15
- data/lib/bolt/pal/yaml_plan/step/resources.rb +82 -21
- data/lib/bolt/pal/yaml_plan/step/script.rb +36 -17
- data/lib/bolt/pal/yaml_plan/step/task.rb +19 -16
- data/lib/bolt/pal/yaml_plan/step/upload.rb +16 -17
- data/lib/bolt/pal/yaml_plan/transpiler.rb +3 -3
- data/lib/bolt/plan_creator.rb +1 -1
- data/lib/bolt/plugin.rb +13 -11
- data/lib/bolt/project_manager.rb +1 -1
- data/lib/bolt/project_manager/module_migrator.rb +1 -1
- data/lib/bolt/result.rb +5 -14
- data/lib/bolt/shell.rb +16 -0
- data/lib/bolt/shell/bash.rb +68 -30
- data/lib/bolt/shell/bash/tmpdir.rb +2 -2
- data/lib/bolt/shell/powershell.rb +28 -11
- data/lib/bolt/task.rb +1 -1
- data/lib/bolt/transport/docker.rb +1 -1
- data/lib/bolt/transport/docker/connection.rb +21 -32
- data/lib/bolt/transport/lxd.rb +26 -0
- data/lib/bolt/transport/lxd/connection.rb +99 -0
- data/lib/bolt/transport/orch.rb +13 -5
- data/lib/bolt/transport/podman.rb +19 -0
- data/lib/bolt/transport/podman/connection.rb +98 -0
- data/lib/bolt/transport/ssh/connection.rb +1 -1
- data/lib/bolt/transport/winrm/connection.rb +1 -1
- data/lib/bolt/util.rb +42 -0
- data/lib/bolt/version.rb +1 -1
- data/lib/bolt_server/transport_app.rb +16 -1
- data/lib/bolt_spec/plans/action_stubs.rb +1 -1
- data/lib/bolt_spec/plans/action_stubs/command_stub.rb +8 -1
- data/lib/bolt_spec/plans/action_stubs/script_stub.rb +8 -1
- data/lib/bolt_spec/plans/mock_executor.rb +91 -7
- data/modules/puppet_connect/plans/test_input_data.pp +22 -0
- metadata +12 -2
data/lib/bolt/outputter/json.rb
CHANGED
@@ -116,7 +116,9 @@ module Bolt
|
|
116
116
|
)
|
117
117
|
end
|
118
118
|
|
119
|
-
def print_target_info(
|
119
|
+
def print_target_info(target_list, _inventoryfile)
|
120
|
+
targets = target_list.values.flatten
|
121
|
+
|
120
122
|
@stream.puts ::JSON.pretty_generate(
|
121
123
|
targets: targets.map(&:detail),
|
122
124
|
count: targets.count
|
@@ -20,6 +20,10 @@ module Bolt
|
|
20
20
|
log_plan_start(event)
|
21
21
|
when :plan_finish
|
22
22
|
log_plan_finish(event)
|
23
|
+
when :container_start
|
24
|
+
log_container_start(event)
|
25
|
+
when :container_finish
|
26
|
+
log_container_finish(event)
|
23
27
|
end
|
24
28
|
end
|
25
29
|
|
@@ -48,6 +52,19 @@ module Bolt
|
|
48
52
|
duration = event[:duration]
|
49
53
|
@logger.info("Finished: plan #{plan} in #{duration.round(2)} sec")
|
50
54
|
end
|
55
|
+
|
56
|
+
def log_container_start(event)
|
57
|
+
@logger.info("Starting: run container '#{event[:image]}'")
|
58
|
+
end
|
59
|
+
|
60
|
+
def log_container_finish(event)
|
61
|
+
result = event[:result]
|
62
|
+
if result.success?
|
63
|
+
@logger.info("Finished: run container '#{result.object}' succeeded.")
|
64
|
+
else
|
65
|
+
@logger.info("Finished: run container '#{result.object}' failed.")
|
66
|
+
end
|
67
|
+
end
|
51
68
|
end
|
52
69
|
end
|
53
70
|
end
|
data/lib/bolt/pal.rb
CHANGED
@@ -385,7 +385,7 @@ module Bolt
|
|
385
385
|
plan_cache[plan_name] = info
|
386
386
|
end
|
387
387
|
|
388
|
-
list << [plan_name] unless info['private']
|
388
|
+
list << [plan_name, info['description']] unless info['private']
|
389
389
|
end
|
390
390
|
|
391
391
|
File.write(@project.plan_cache_file, plan_cache.to_json) if updated
|
@@ -446,7 +446,7 @@ module Bolt
|
|
446
446
|
params[name] = { 'type' => param.types.first }
|
447
447
|
params[name]['sensitive'] = param.types.first =~ /\ASensitive(\[.*\])?\z/ ? true : false
|
448
448
|
params[name]['default_value'] = defaults[name] if defaults.key?(name)
|
449
|
-
params[name]['description'] = param.text
|
449
|
+
params[name]['description'] = param.text if param.text && !param.text.empty?
|
450
450
|
else
|
451
451
|
Bolt::Logger.warn(
|
452
452
|
"missing_plan_parameter",
|
@@ -521,10 +521,30 @@ module Bolt
|
|
521
521
|
end
|
522
522
|
end
|
523
523
|
|
524
|
-
def convert_plan(
|
524
|
+
def convert_plan(plan)
|
525
|
+
path = File.expand_path(plan)
|
526
|
+
|
527
|
+
# If the path doesn't exist, check if it's a plan name
|
528
|
+
unless File.exist?(path)
|
529
|
+
in_bolt_compiler do |compiler|
|
530
|
+
sig = compiler.plan_signature(plan)
|
531
|
+
|
532
|
+
# If the plan was loaded, look for it on the module loader
|
533
|
+
# There has to be an easier way to do this...
|
534
|
+
if sig
|
535
|
+
type = compiler.list_plans.find { |p| p.name == plan }
|
536
|
+
path = sig.instance_variable_get(:@plan_func)
|
537
|
+
.loader
|
538
|
+
.find(type)
|
539
|
+
.origin
|
540
|
+
.first
|
541
|
+
end
|
542
|
+
end
|
543
|
+
end
|
544
|
+
|
525
545
|
Puppet[:tasks] = true
|
526
546
|
transpiler = YamlPlan::Transpiler.new
|
527
|
-
transpiler.transpile(
|
547
|
+
transpiler.transpile(path)
|
528
548
|
end
|
529
549
|
|
530
550
|
# Returns a mapping of all modules available to the Bolt compiler
|
data/lib/bolt/pal/yaml_plan.rb
CHANGED
@@ -73,8 +73,7 @@ module Bolt
|
|
73
73
|
def duplicate_check(used_names, name, step_number)
|
74
74
|
if used_names.include?(name)
|
75
75
|
error_message = "Duplicate step name or parameter detected: #{name.inspect}"
|
76
|
-
|
77
|
-
raise Bolt::Error.new(err, "bolt/invalid-plan")
|
76
|
+
raise Step::StepError.new(error_message, name, step_number)
|
78
77
|
end
|
79
78
|
end
|
80
79
|
|
@@ -12,153 +12,15 @@ module Bolt
|
|
12
12
|
@evaluator = Puppet::Pops::Parser::EvaluatingParser.new
|
13
13
|
end
|
14
14
|
|
15
|
-
def dispatch_step(scope, step)
|
16
|
-
step_body = evaluate_code_blocks(scope, step.body)
|
17
|
-
|
18
|
-
# Dispatch based on the step class name
|
19
|
-
step_type = step.class.name.split('::').last.downcase
|
20
|
-
method = "#{step_type}_step"
|
21
|
-
|
22
|
-
send(method, scope, step_body)
|
23
|
-
end
|
24
|
-
|
25
|
-
def task_step(scope, step)
|
26
|
-
task = step['task']
|
27
|
-
targets = step['targets']
|
28
|
-
description = step['description']
|
29
|
-
params = step['parameters'] || {}
|
30
|
-
|
31
|
-
args = if description
|
32
|
-
[task, targets, description, params]
|
33
|
-
else
|
34
|
-
[task, targets, params]
|
35
|
-
end
|
36
|
-
|
37
|
-
scope.call_function('run_task', args)
|
38
|
-
end
|
39
|
-
|
40
|
-
def plan_step(scope, step)
|
41
|
-
plan = step['plan']
|
42
|
-
parameters = step['parameters'] || {}
|
43
|
-
|
44
|
-
args = [plan, parameters]
|
45
|
-
|
46
|
-
scope.call_function('run_plan', args)
|
47
|
-
end
|
48
|
-
|
49
|
-
def script_step(scope, step)
|
50
|
-
script = step['script']
|
51
|
-
targets = step['targets']
|
52
|
-
description = step['description']
|
53
|
-
arguments = step['arguments'] || []
|
54
|
-
|
55
|
-
options = { 'arguments' => arguments }
|
56
|
-
args = if description
|
57
|
-
[script, targets, description, options]
|
58
|
-
else
|
59
|
-
[script, targets, options]
|
60
|
-
end
|
61
|
-
|
62
|
-
scope.call_function('run_script', args)
|
63
|
-
end
|
64
|
-
|
65
|
-
def command_step(scope, step)
|
66
|
-
command = step['command']
|
67
|
-
targets = step['targets']
|
68
|
-
description = step['description']
|
69
|
-
|
70
|
-
args = [command, targets]
|
71
|
-
args << description if description
|
72
|
-
scope.call_function('run_command', args)
|
73
|
-
end
|
74
|
-
|
75
|
-
def upload_step(scope, step)
|
76
|
-
source = step['upload']
|
77
|
-
destination = step['destination']
|
78
|
-
targets = step['targets']
|
79
|
-
description = step['description']
|
80
|
-
|
81
|
-
args = [source, destination, targets]
|
82
|
-
args << description if description
|
83
|
-
scope.call_function('upload_file', args)
|
84
|
-
end
|
85
|
-
|
86
|
-
def download_step(scope, step)
|
87
|
-
source = step['download']
|
88
|
-
destination = step['destination']
|
89
|
-
targets = step['targets']
|
90
|
-
description = step['description']
|
91
|
-
|
92
|
-
args = [source, destination, targets]
|
93
|
-
args << description if description
|
94
|
-
scope.call_function('download_file', args)
|
95
|
-
end
|
96
|
-
|
97
|
-
def eval_step(_scope, step)
|
98
|
-
step['eval']
|
99
|
-
end
|
100
|
-
|
101
|
-
def resources_step(scope, step)
|
102
|
-
targets = step['targets']
|
103
|
-
|
104
|
-
# TODO: Only call apply_prep when needed
|
105
|
-
scope.call_function('apply_prep', targets)
|
106
|
-
manifest = generate_manifest(step['resources'])
|
107
|
-
|
108
|
-
apply_manifest(scope, targets, manifest)
|
109
|
-
end
|
110
|
-
|
111
|
-
def message_step(scope, step)
|
112
|
-
scope.call_function('out::message', [step['message']])
|
113
|
-
end
|
114
|
-
|
115
|
-
def generate_manifest(resources)
|
116
|
-
# inspect returns the Ruby representation of the resource hashes,
|
117
|
-
# which happens to be the same as the Puppet representation
|
118
|
-
puppet_resources = resources.inspect
|
119
|
-
|
120
|
-
# Because the :tasks setting globally controls which mode the parser
|
121
|
-
# is in, we need to make this snippet of non-tasks manifest code
|
122
|
-
# parseable in tasks mode. The way to do that is by putting it in an
|
123
|
-
# apply statement and taking the body.
|
124
|
-
<<~MANIFEST
|
125
|
-
apply('placeholder') {
|
126
|
-
$resources = #{puppet_resources}
|
127
|
-
$resources.each |$res| {
|
128
|
-
Resource[$res['type']] { $res['title']:
|
129
|
-
* => $res['parameters'],
|
130
|
-
}
|
131
|
-
}
|
132
|
-
|
133
|
-
# Add relationships if there is more than one resource
|
134
|
-
if $resources.length > 1 {
|
135
|
-
($resources.length - 1).each |$index| {
|
136
|
-
$lhs = $resources[$index]
|
137
|
-
$rhs = $resources[$index+1]
|
138
|
-
$lhs_resource = Resource[$lhs['type'] , $lhs['title']]
|
139
|
-
$rhs_resource = Resource[$rhs['type'] , $rhs['title']]
|
140
|
-
$lhs_resource -> $rhs_resource
|
141
|
-
}
|
142
|
-
}
|
143
|
-
}
|
144
|
-
MANIFEST
|
145
|
-
end
|
146
|
-
|
147
|
-
def apply_manifest(scope, targets, manifest)
|
148
|
-
ast = @evaluator.parse_string(manifest)
|
149
|
-
apply_block = ast.body.body
|
150
|
-
applicator = Puppet.lookup(:apply_executor)
|
151
|
-
applicator.apply([targets], apply_block, scope)
|
152
|
-
end
|
153
|
-
|
154
15
|
# This is the method that Puppet calls to evaluate the plan. The name
|
155
16
|
# makes more sense for .pp plans.
|
17
|
+
#
|
156
18
|
def evaluate_block_with_bindings(closure_scope, args_hash, plan)
|
157
19
|
plan_result = closure_scope.with_local_scope(args_hash) do |scope|
|
158
20
|
plan.steps.each do |step|
|
159
|
-
step_result =
|
21
|
+
step_result = step.evaluate(scope, self)
|
160
22
|
|
161
|
-
scope.setvar(step.name, step_result) if step.name
|
23
|
+
scope.setvar(step.body['name'], step_result) if step.body['name']
|
162
24
|
end
|
163
25
|
|
164
26
|
evaluate_code_blocks(scope, plan.return)
|
@@ -168,6 +30,7 @@ module Bolt
|
|
168
30
|
end
|
169
31
|
|
170
32
|
# Recursively evaluate any EvaluableString instances in the object.
|
33
|
+
#
|
171
34
|
def evaluate_code_blocks(scope, value)
|
172
35
|
# XXX We should establish a local scope here probably
|
173
36
|
case value
|
@@ -192,6 +55,7 @@ module Bolt
|
|
192
55
|
# Occasionally the Closure will ask us to evaluate what it assumes are
|
193
56
|
# AST objects. Because we've sidestepped the AST, they aren't, so just
|
194
57
|
# return the values as already evaluated.
|
58
|
+
#
|
195
59
|
def evaluate(value, _scope)
|
196
60
|
value
|
197
61
|
end
|
@@ -6,11 +6,7 @@ module Bolt
|
|
6
6
|
class PAL
|
7
7
|
class YamlPlan
|
8
8
|
class Step
|
9
|
-
attr_reader :
|
10
|
-
|
11
|
-
def self.allowed_keys
|
12
|
-
Set['name', 'description', 'targets']
|
13
|
-
end
|
9
|
+
attr_reader :body
|
14
10
|
|
15
11
|
STEP_KEYS = %w[
|
16
12
|
command
|
@@ -24,15 +20,42 @@ module Bolt
|
|
24
20
|
upload
|
25
21
|
].freeze
|
26
22
|
|
23
|
+
class StepError < Bolt::Error
|
24
|
+
def initialize(message, name, step_number)
|
25
|
+
identifier = name ? name.inspect : "number #{step_number}"
|
26
|
+
error = "Parse error in step #{identifier}: \n #{message}"
|
27
|
+
|
28
|
+
super(error, 'bolt/invalid-plan')
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
# Keys that are allowed for the step
|
33
|
+
#
|
34
|
+
def self.allowed_keys
|
35
|
+
required_keys + option_keys + Set['name', 'description', 'targets']
|
36
|
+
end
|
37
|
+
|
38
|
+
# Keys that translate to metaparameters for the plan step's function call
|
39
|
+
#
|
40
|
+
def self.option_keys
|
41
|
+
Set.new
|
42
|
+
end
|
43
|
+
|
44
|
+
# Keys that are required for the step
|
45
|
+
#
|
46
|
+
def self.required_keys
|
47
|
+
Set.new
|
48
|
+
end
|
49
|
+
|
27
50
|
def self.create(step_body, step_number)
|
28
51
|
type_keys = (STEP_KEYS & step_body.keys)
|
29
52
|
case type_keys.length
|
30
53
|
when 0
|
31
|
-
raise
|
54
|
+
raise StepError.new("No valid action detected", step_body['name'], step_number)
|
32
55
|
when 1
|
33
56
|
type = type_keys.first
|
34
57
|
else
|
35
|
-
raise
|
58
|
+
raise StepError.new("Multiple action keys detected: #{type_keys.inspect}", step_body['name'], step_number)
|
36
59
|
end
|
37
60
|
|
38
61
|
step_class = const_get("Bolt::PAL::YamlPlan::Step::#{type.capitalize}")
|
@@ -40,15 +63,49 @@ module Bolt
|
|
40
63
|
step_class.new(step_body)
|
41
64
|
end
|
42
65
|
|
43
|
-
def initialize(
|
44
|
-
@
|
45
|
-
@description = step_body['description']
|
46
|
-
@targets = step_body['targets']
|
47
|
-
@body = step_body
|
66
|
+
def initialize(body)
|
67
|
+
@body = body
|
48
68
|
end
|
49
69
|
|
70
|
+
# Transpiles the step into the plan language
|
71
|
+
#
|
50
72
|
def transpile
|
51
|
-
|
73
|
+
code = String.new(" ")
|
74
|
+
code << "$#{body['name']} = " if body['name']
|
75
|
+
code << function_call(function, format_args(body))
|
76
|
+
code << "\n"
|
77
|
+
end
|
78
|
+
|
79
|
+
# Evaluates the step
|
80
|
+
#
|
81
|
+
def evaluate(scope, evaluator)
|
82
|
+
evaluated = evaluator.evaluate_code_blocks(scope, body)
|
83
|
+
scope.call_function(function, format_args(evaluated))
|
84
|
+
end
|
85
|
+
|
86
|
+
# Formats a list of args from the provided body
|
87
|
+
#
|
88
|
+
private def format_args(_body)
|
89
|
+
raise NotImplementedError, "Step class #{self.class} does not implement #format_args"
|
90
|
+
end
|
91
|
+
|
92
|
+
# Returns the step's corresponding Puppet language function call
|
93
|
+
#
|
94
|
+
private def function_call(function, args)
|
95
|
+
code_args = args.map { |arg| Bolt::Util.to_code(arg) }
|
96
|
+
"#{function}(#{code_args.join(', ')})"
|
97
|
+
end
|
98
|
+
|
99
|
+
# The function that corresponds to the step
|
100
|
+
#
|
101
|
+
private def function
|
102
|
+
raise NotImplementedError, "Step class #{self.class} does not implement #function"
|
103
|
+
end
|
104
|
+
|
105
|
+
# Returns a hash of options formatted for function calls
|
106
|
+
#
|
107
|
+
private def format_options(body)
|
108
|
+
body.slice(*self.class.option_keys).transform_keys { |key| "_#{key}" }
|
52
109
|
end
|
53
110
|
|
54
111
|
def self.validate(body, step_number)
|
@@ -57,19 +114,35 @@ module Bolt
|
|
57
114
|
begin
|
58
115
|
body.each { |k, v| validate_puppet_code(k, v) }
|
59
116
|
rescue Bolt::Error => e
|
60
|
-
raise
|
117
|
+
raise StepError.new(e.msg, body['name'], step_number)
|
118
|
+
end
|
119
|
+
|
120
|
+
if body.key?('parameters')
|
121
|
+
unless body['parameters'].is_a?(Hash)
|
122
|
+
raise StepError.new("Parameters key must be a hash", body['name'], step_number)
|
123
|
+
end
|
124
|
+
|
125
|
+
metaparams = option_keys.map { |key| "_#{key}" }
|
126
|
+
|
127
|
+
if (dups = body['parameters'].keys & metaparams).any?
|
128
|
+
raise StepError.new(
|
129
|
+
"Cannot specify metaparameters when using top-level keys with same name: #{dups.join(', ')}",
|
130
|
+
body['name'],
|
131
|
+
step_number
|
132
|
+
)
|
133
|
+
end
|
61
134
|
end
|
62
135
|
|
63
136
|
unless body.fetch('parameters', {}).is_a?(Hash)
|
64
137
|
msg = "Parameters key must be a hash"
|
65
|
-
raise
|
138
|
+
raise StepError.new(msg, body['name'], step_number)
|
66
139
|
end
|
67
140
|
|
68
141
|
if body.key?('name')
|
69
142
|
name = body['name']
|
70
143
|
unless name.is_a?(String) && name.match?(Bolt::PAL::YamlPlan::VAR_NAME_PATTERN)
|
71
144
|
error_message = "Invalid step name: #{name.inspect}"
|
72
|
-
raise
|
145
|
+
raise StepError.new(error_message, body['name'], step_number)
|
73
146
|
end
|
74
147
|
end
|
75
148
|
end
|
@@ -81,8 +154,7 @@ module Bolt
|
|
81
154
|
illegal_keys = body.keys.to_set - allowed_keys
|
82
155
|
if illegal_keys.any?
|
83
156
|
error_message = "The #{step_type.inspect} step does not support: #{illegal_keys.to_a.inspect} key(s)"
|
84
|
-
|
85
|
-
raise Bolt::Error.new(err, "bolt/invalid-plan")
|
157
|
+
raise StepError.new(error_message, body['name'], step_number)
|
86
158
|
end
|
87
159
|
|
88
160
|
# Ensure all required keys are present
|
@@ -90,8 +162,7 @@ module Bolt
|
|
90
162
|
|
91
163
|
if missing_keys.any?
|
92
164
|
error_message = "The #{step_type.inspect} step requires: #{missing_keys.to_a.inspect} key(s)"
|
93
|
-
|
94
|
-
raise Bolt::Error.new(err, "bolt/invalid-plan")
|
165
|
+
raise StepError.new(error_message, body['name'], step_number)
|
95
166
|
end
|
96
167
|
end
|
97
168
|
|
@@ -123,12 +194,6 @@ module Bolt
|
|
123
194
|
raise Bolt::Error.new("Error parsing #{step_key.inspect}: #{e.basic_message}", "bolt/invalid-plan")
|
124
195
|
end
|
125
196
|
|
126
|
-
def self.step_error(message, name, step_number)
|
127
|
-
identifier = name ? name.inspect : "number #{step_number}"
|
128
|
-
error = "Parse error in step #{identifier}: \n #{message}"
|
129
|
-
Bolt::Error.new(error, 'bolt/invalid-plan')
|
130
|
-
end
|
131
|
-
|
132
197
|
# Parses the an evaluable string, optionally quote it before parsing
|
133
198
|
def self.parse_code_string(code, quote = false)
|
134
199
|
if quote
|
@@ -138,11 +203,6 @@ module Bolt
|
|
138
203
|
Puppet::Pops::Parser::EvaluatingParser.new.parse_string(code)
|
139
204
|
end
|
140
205
|
end
|
141
|
-
|
142
|
-
def function_call(function, args)
|
143
|
-
code_args = args.map { |arg| Bolt::Util.to_code(arg) }
|
144
|
-
"#{function}(#{code_args.join(', ')})"
|
145
|
-
end
|
146
206
|
end
|
147
207
|
end
|
148
208
|
end
|