bolt 2.6.0 → 2.11.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 +4 -3
- data/bolt-modules/boltlib/lib/puppet/datatypes/applyresult.rb +2 -0
- data/bolt-modules/boltlib/lib/puppet/datatypes/resourceinstance.rb +27 -0
- data/bolt-modules/boltlib/lib/puppet/datatypes/result.rb +2 -0
- data/bolt-modules/boltlib/lib/puppet/datatypes/resultset.rb +2 -0
- data/bolt-modules/boltlib/lib/puppet/datatypes/target.rb +4 -3
- data/bolt-modules/boltlib/lib/puppet/functions/run_plan.rb +1 -1
- data/bolt-modules/boltlib/lib/puppet/functions/run_task_with.rb +192 -0
- data/bolt-modules/boltlib/lib/puppet/functions/set_resources.rb +122 -0
- data/bolt-modules/boltlib/types/planresult.pp +12 -1
- data/bolt-modules/file/lib/puppet/functions/file/exists.rb +3 -1
- data/bolt-modules/file/lib/puppet/functions/file/join.rb +1 -1
- data/bolt-modules/file/lib/puppet/functions/file/read.rb +2 -1
- data/bolt-modules/file/lib/puppet/functions/file/readable.rb +3 -1
- data/bolt-modules/file/lib/puppet/functions/file/write.rb +3 -1
- data/bolt-modules/prompt/lib/puppet/functions/prompt.rb +43 -0
- data/lib/bolt/analytics.rb +1 -1
- data/lib/bolt/applicator.rb +3 -2
- data/lib/bolt/apply_inventory.rb +1 -1
- data/lib/bolt/apply_result.rb +1 -1
- data/lib/bolt/apply_target.rb +11 -2
- data/lib/bolt/bolt_option_parser.rb +27 -7
- data/lib/bolt/catalog.rb +32 -3
- data/lib/bolt/cli.rb +52 -22
- data/lib/bolt/config.rb +51 -27
- data/lib/bolt/config/transport/base.rb +3 -3
- data/lib/bolt/config/transport/docker.rb +7 -1
- data/lib/bolt/config/transport/local.rb +9 -1
- data/lib/bolt/config/transport/orch.rb +4 -2
- data/lib/bolt/config/transport/remote.rb +2 -0
- data/lib/bolt/config/transport/ssh.rb +81 -3
- data/lib/bolt/config/transport/winrm.rb +6 -1
- data/lib/bolt/executor.rb +38 -0
- data/lib/bolt/inventory.rb +2 -1
- data/lib/bolt/inventory/group.rb +1 -0
- data/lib/bolt/inventory/inventory.rb +9 -0
- data/lib/bolt/inventory/target.rb +17 -1
- data/lib/bolt/node/output.rb +1 -1
- data/lib/bolt/outputter/human.rb +5 -4
- data/lib/bolt/outputter/json.rb +1 -1
- data/lib/bolt/pal.rb +32 -14
- data/lib/bolt/pal/yaml_plan.rb +1 -0
- data/lib/bolt/plugin.rb +14 -8
- data/lib/bolt/plugin/env_var.rb +2 -1
- data/lib/bolt/plugin/module.rb +40 -7
- data/lib/bolt/plugin/prompt.rb +1 -1
- data/lib/bolt/plugin/puppetdb.rb +5 -2
- data/lib/bolt/project.rb +135 -0
- data/lib/bolt/puppetdb/config.rb +16 -28
- data/lib/bolt/rerun.rb +1 -1
- data/lib/bolt/resource_instance.rb +126 -0
- data/lib/bolt/result.rb +46 -23
- data/lib/bolt/result_set.rb +2 -5
- data/lib/bolt/secret.rb +20 -4
- data/lib/bolt/shell/bash.rb +27 -14
- data/lib/bolt/shell/bash/tmpdir.rb +1 -1
- data/lib/bolt/shell/powershell.rb +43 -15
- data/lib/bolt/shell/powershell/snippets.rb +1 -1
- data/lib/bolt/target.rb +18 -2
- data/lib/bolt/transport/base.rb +24 -8
- data/lib/bolt/transport/docker.rb +3 -3
- data/lib/bolt/transport/docker/connection.rb +11 -7
- data/lib/bolt/transport/local/connection.rb +13 -7
- data/lib/bolt/transport/orch.rb +5 -1
- data/lib/bolt/transport/ssh.rb +6 -2
- data/lib/bolt/transport/ssh/connection.rb +26 -1
- data/lib/bolt/transport/ssh/exec_connection.rb +110 -0
- data/lib/bolt/transport/winrm/connection.rb +10 -2
- data/lib/bolt/version.rb +1 -1
- data/lib/bolt_server/pe/pal.rb +1 -38
- data/lib/bolt_server/transport_app.rb +7 -7
- data/lib/bolt_spec/bolt_context.rb +3 -6
- data/lib/bolt_spec/plans.rb +78 -8
- data/lib/bolt_spec/plans/action_stubs.rb +37 -7
- data/lib/bolt_spec/plans/action_stubs/plan_stub.rb +55 -0
- data/lib/bolt_spec/plans/mock_executor.rb +62 -2
- data/lib/bolt_spec/run.rb +10 -13
- metadata +26 -7
- data/lib/bolt/boltdir.rb +0 -54
- data/lib/bolt/plugin/pkcs7.rb +0 -104
- data/lib/bolt/secret/base.rb +0 -41
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ffe8fa93c2b9de411d9c2ef46c6c68deae3e10c7b711451dd1acf12034952b31
|
4
|
+
data.tar.gz: 4892ece130a2c4c8d70aa6315df85c13be920c290c2e337dddf2b493180bea58
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b95e67238b0af8b5ded1c2f14f1514fb5ab715ae43afbca3247c4f4224d7f403385e0b3f6072babbc90faeb8bcaa4d7cc0b79319258f509340fe765c3e9e13b7
|
7
|
+
data.tar.gz: 9e1584102d3b103632e36d9c922df007c9b780d69a088b964ef59ff4162e94abdc12693e61fea42c5256a97ebf245e2dd4222d4019d98db2d658a10b4f15e317
|
data/Puppetfile
CHANGED
@@ -6,7 +6,7 @@ moduledir File.join(File.dirname(__FILE__), 'modules')
|
|
6
6
|
|
7
7
|
# Core modules used by 'apply'
|
8
8
|
mod 'puppetlabs-service', '1.2.0'
|
9
|
-
mod 'puppetlabs-puppet_agent', '3.0
|
9
|
+
mod 'puppetlabs-puppet_agent', '3.2.0'
|
10
10
|
mod 'puppetlabs-facts', '1.0.0'
|
11
11
|
|
12
12
|
# Core types and providers for Puppet 6
|
@@ -24,7 +24,7 @@ mod 'puppetlabs-zone_core', '1.0.3'
|
|
24
24
|
# Useful additional modules
|
25
25
|
mod 'puppetlabs-package', '1.1.0'
|
26
26
|
mod 'puppetlabs-puppet_conf', '0.6.0'
|
27
|
-
mod 'puppetlabs-python_task_helper', '0.4.
|
27
|
+
mod 'puppetlabs-python_task_helper', '0.4.3'
|
28
28
|
mod 'puppetlabs-reboot', '3.0.0'
|
29
29
|
mod 'puppetlabs-ruby_task_helper', '0.5.1'
|
30
30
|
mod 'puppetlabs-ruby_plugin_helper', '0.1.0'
|
@@ -32,7 +32,8 @@ mod 'puppetlabs-ruby_plugin_helper', '0.1.0'
|
|
32
32
|
# Plugin modules
|
33
33
|
mod 'puppetlabs-aws_inventory', '0.5.0'
|
34
34
|
mod 'puppetlabs-azure_inventory', '0.3.0'
|
35
|
-
mod 'puppetlabs-gcloud_inventory', '0.1.
|
35
|
+
mod 'puppetlabs-gcloud_inventory', '0.1.1'
|
36
|
+
mod 'puppetlabs-pkcs7', '0.1.0'
|
36
37
|
mod 'puppetlabs-terraform', '0.5.0'
|
37
38
|
mod 'puppetlabs-vault', '0.3.0'
|
38
39
|
mod 'puppetlabs-yaml', '0.2.0'
|
@@ -17,5 +17,7 @@ Puppet::DataTypes.create_type('ApplyResult') do
|
|
17
17
|
|
18
18
|
load_file('bolt/apply_result')
|
19
19
|
|
20
|
+
# Needed for Puppet to recognize Bolt::ApplyResult as a Puppet object when deserializing
|
21
|
+
Bolt::ApplyResult.include(Puppet::Pops::Types::PuppetObject)
|
20
22
|
implementation_class Bolt::ApplyResult
|
21
23
|
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
Puppet::DataTypes.create_type('ResourceInstance') do
|
4
|
+
interface <<-PUPPET
|
5
|
+
attributes => {
|
6
|
+
'target' => Target,
|
7
|
+
'type' => Variant[String[1], Type[Resource]],
|
8
|
+
'title' => String[1],
|
9
|
+
'state' => Optional[Hash[String[1], Data]],
|
10
|
+
'desired_state' => Optional[Hash[String[1], Data]],
|
11
|
+
'events' => Optional[Array[Hash[String[1], Data]]]
|
12
|
+
},
|
13
|
+
functions => {
|
14
|
+
add_event => Callable[[Hash[String[1], Data]], [Hash[String[1], Data]]],
|
15
|
+
set_state => Callable[[Hash[String[1], Data]], Hash[String[1], Data]],
|
16
|
+
overwrite_state => Callable[[Hash[String[1], Data]], Hash[String[1], Data]],
|
17
|
+
set_desired_state => Callable[[Hash[String[1], Data]], Hash[String[1], Data]],
|
18
|
+
overwrite_desired_state => Callable[[Hash[String[1], Data]], Hash[String[1], Data]],
|
19
|
+
reference => Callable[[], String]
|
20
|
+
}
|
21
|
+
PUPPET
|
22
|
+
|
23
|
+
load_file('bolt/resource_instance')
|
24
|
+
# Needed for Puppet to recognize Bolt::ResourceInstance as a Puppet object when deserializing
|
25
|
+
Bolt::ResourceInstance.include(Puppet::Pops::Types::PuppetObject)
|
26
|
+
implementation_class Bolt::ResourceInstance
|
27
|
+
end
|
@@ -19,5 +19,7 @@ Puppet::DataTypes.create_type('Result') do
|
|
19
19
|
|
20
20
|
load_file('bolt/result')
|
21
21
|
|
22
|
+
# Needed for Puppet to recognize Bolt::Result as a Puppet object when deserializing
|
23
|
+
Bolt::Result.include(Puppet::Pops::Types::PuppetObject)
|
22
24
|
implementation_class Bolt::Result
|
23
25
|
end
|
@@ -25,5 +25,7 @@ Puppet::DataTypes.create_type('ResultSet') do
|
|
25
25
|
|
26
26
|
load_file('bolt/result_set')
|
27
27
|
|
28
|
+
# Needed for Puppet to recognize Bolt::ResultSet as a Puppet object when deserializing
|
29
|
+
Bolt::ResultSet.include(Puppet::Pops::Types::PuppetObject)
|
28
30
|
implementation_class Bolt::ResultSet
|
29
31
|
end
|
@@ -8,8 +8,6 @@ Puppet::DataTypes.create_type('Target') do
|
|
8
8
|
target_implementation_class = Bolt::Target
|
9
9
|
end
|
10
10
|
|
11
|
-
require 'bolt/target'
|
12
|
-
|
13
11
|
interface <<-PUPPET
|
14
12
|
attributes => {
|
15
13
|
uri => { type => Optional[String[1]], kind => given_or_derived },
|
@@ -20,7 +18,8 @@ Puppet::DataTypes.create_type('Target') do
|
|
20
18
|
vars => { type => Optional[Hash[String[1], Data]], kind => given_or_derived },
|
21
19
|
facts => { type => Optional[Hash[String[1], Data]], kind => given_or_derived },
|
22
20
|
features => { type => Optional[Array[String[1]]], kind => given_or_derived },
|
23
|
-
plugin_hooks => { type => Optional[Hash[String[1], Data]], kind => given_or_derived }
|
21
|
+
plugin_hooks => { type => Optional[Hash[String[1], Data]], kind => given_or_derived },
|
22
|
+
resources => { type => Optional[Hash[String[1], ResourceInstance]], kind => given_or_derived }
|
24
23
|
},
|
25
24
|
functions => {
|
26
25
|
host => Callable[[], Optional[String]],
|
@@ -33,5 +32,7 @@ Puppet::DataTypes.create_type('Target') do
|
|
33
32
|
}
|
34
33
|
PUPPET
|
35
34
|
|
35
|
+
# Needed for Puppet to recognize targets as Puppet objects when deserializing
|
36
|
+
target_implementation_class.include(Puppet::Pops::Types::PuppetObject)
|
36
37
|
implementation_class target_implementation_class
|
37
38
|
end
|
@@ -117,7 +117,7 @@ Puppet::Functions.create_function(:run_plan, Puppet::Functions::InternalFunction
|
|
117
117
|
# undef/nil
|
118
118
|
result = catch(:return) do
|
119
119
|
scope.with_global_scope do |global_scope|
|
120
|
-
|
120
|
+
executor.run_plan(global_scope, closure, params)
|
121
121
|
end
|
122
122
|
nil
|
123
123
|
end&.value
|
@@ -0,0 +1,192 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'bolt/error'
|
4
|
+
require 'bolt/pal'
|
5
|
+
require 'bolt/task'
|
6
|
+
|
7
|
+
# Runs a given instance of a `Task` with target-specific parameters on the given set of targets and
|
8
|
+
# returns the result from each. This function differs from {run_task} by accepting a block that returns
|
9
|
+
# a `Hash` of target-specific parameters that are passed to the task. This can be used to send parameters
|
10
|
+
# based on a target's attributes, such as its `facts`, or to use conditional logic to determine the
|
11
|
+
# parameters a task should receive for a specific target.
|
12
|
+
#
|
13
|
+
# This function does nothing if the list of targets is empty.
|
14
|
+
#
|
15
|
+
# > **Note:** Not available in apply block
|
16
|
+
#
|
17
|
+
# > **Note:** Not available to targets using the pcp transport
|
18
|
+
Puppet::Functions.create_function(:run_task_with) do
|
19
|
+
# Run a task with target-specific parameters.
|
20
|
+
# @param task_name The task to run.
|
21
|
+
# @param targets A pattern identifying zero or more targets. See {get_targets} for accepted patterns.
|
22
|
+
# @param options A hash of additional options.
|
23
|
+
# @option options [Boolean] _catch_errors Whether to catch raised errors.
|
24
|
+
# @option options [Boolean] _noop Run the task in noop mode if available.
|
25
|
+
# @option options [String] _run_as User to run as using privilege escalation.
|
26
|
+
# @param block A block that returns a `Hash` of target-specific parameters for the task.
|
27
|
+
# @return A list of results, one entry per target.
|
28
|
+
# @example Run a task with target-specific parameters as root
|
29
|
+
# run_task_with('my_task', $targets, '_run_as' => 'root') |$t| {
|
30
|
+
# { 'param1' => $t.vars['var1'],
|
31
|
+
# 'param2' => $t.vars['var2'] }
|
32
|
+
# }
|
33
|
+
dispatch :run_task_with do
|
34
|
+
param 'String[1]', :task_name
|
35
|
+
param 'Boltlib::TargetSpec', :targets
|
36
|
+
optional_param 'Hash[String[1], Any]', :options
|
37
|
+
required_block_param 'Callable[Target]', :block
|
38
|
+
return_type 'ResultSet'
|
39
|
+
end
|
40
|
+
|
41
|
+
# Run a task with target-specific parameters, logging the provided description.
|
42
|
+
# @param task_name The task to run.
|
43
|
+
# @param targets A pattern identifying zero or more targets. See {get_targets} for accepted patterns.
|
44
|
+
# @param description A description to be output when calling this function.
|
45
|
+
# @param options A hash of additional options.
|
46
|
+
# @option options [Boolean] _catch_errors Whether to catch raised errors.
|
47
|
+
# @option options [Boolean] _noop Run the task in noop mode if available.
|
48
|
+
# @option options [String] _run_as User to run as using privilege escalation.
|
49
|
+
# @param block A block that returns a `Hash` of target-specific parameters for the task.
|
50
|
+
# @return A list of results, one entry per target.
|
51
|
+
# @example Run a task with target-specific parameters and a description
|
52
|
+
# run_task_with('my_task', $targets, 'Update system packages') |$t| {
|
53
|
+
# { 'param1' => $t.vars['var1'],
|
54
|
+
# 'param2' => $t.vars['var2'] }
|
55
|
+
# }
|
56
|
+
dispatch :run_task_with_with_description do
|
57
|
+
param 'String[1]', :task_name
|
58
|
+
param 'Boltlib::TargetSpec', :targets
|
59
|
+
param 'Optional[String]', :description
|
60
|
+
optional_param 'Hash[String[1], Any]', :options
|
61
|
+
required_block_param 'Callable[Target]', :block
|
62
|
+
return_type 'ResultSet'
|
63
|
+
end
|
64
|
+
|
65
|
+
def run_task_with(task_name, targets, options = {}, &block)
|
66
|
+
run_task_with_with_description(task_name, targets, nil, options, &block)
|
67
|
+
end
|
68
|
+
|
69
|
+
def run_task_with_with_description(task_name, targets, description, options = {})
|
70
|
+
unless Puppet[:tasks]
|
71
|
+
raise Puppet::ParseErrorWithIssue
|
72
|
+
.from_issue_and_stack(
|
73
|
+
Bolt::PAL::Issues::PLAN_OPERATION_NOT_SUPPORTED_WHEN_COMPILING,
|
74
|
+
action: 'run_task_with'
|
75
|
+
)
|
76
|
+
end
|
77
|
+
|
78
|
+
executor = Puppet.lookup(:bolt_executor)
|
79
|
+
inventory = Puppet.lookup(:bolt_inventory)
|
80
|
+
error_set = []
|
81
|
+
|
82
|
+
# Report to analytics
|
83
|
+
executor.report_function_call(self.class.name)
|
84
|
+
executor.report_bundled_content('Task', task_name)
|
85
|
+
|
86
|
+
# Keep valid metaparameters, discarding everything else
|
87
|
+
options = options.select { |k, _v| k.start_with?('_') }
|
88
|
+
.transform_keys { |k| k.sub(/^_/, '').to_sym }
|
89
|
+
|
90
|
+
options[:description] = description if description
|
91
|
+
|
92
|
+
# Get all the targets
|
93
|
+
targets = Array(inventory.get_targets(targets))
|
94
|
+
|
95
|
+
# If all targets use the 'pcp' transport, use a fake task instead of loading the local definition
|
96
|
+
# Otherwise, load the local task definition
|
97
|
+
if (pcp_only = targets.any? && targets.all? { |t| t.transport == 'pcp' })
|
98
|
+
task = Bolt::Task.new(task_name, {}, [{ 'name' => '', 'path' => '' }])
|
99
|
+
else
|
100
|
+
task_signature = Puppet::Pal::ScriptCompiler.new(closure_scope.compiler).task_signature(task_name)
|
101
|
+
|
102
|
+
if task_signature.nil?
|
103
|
+
raise Bolt::Error.unknown_task(task_name)
|
104
|
+
end
|
105
|
+
|
106
|
+
task = Bolt::Task.from_task_signature(task_signature)
|
107
|
+
end
|
108
|
+
|
109
|
+
# Map the targets to their specific parameters and merge with the defaults
|
110
|
+
target_mapping = targets.each_with_object({}) do |target, mapping|
|
111
|
+
params = yield(target)
|
112
|
+
|
113
|
+
# Parameters returned from the block should be a Hash. If they're not, create a failing
|
114
|
+
# Result for the target that will later be added to the ResultSet.
|
115
|
+
unless params.is_a?(Hash)
|
116
|
+
exception = with_stack(
|
117
|
+
:TYPE_MISMATCH,
|
118
|
+
"Block must return a Hash of parameters, received #{params.class}"
|
119
|
+
)
|
120
|
+
error_set << Bolt::Result.from_exception(target, exception, action: 'task')
|
121
|
+
next
|
122
|
+
end
|
123
|
+
|
124
|
+
# If parameters are mismatched, create a failing result for the target that will later
|
125
|
+
# be added to the ResultSet.
|
126
|
+
unless pcp_only
|
127
|
+
params = task.parameter_defaults.merge(params)
|
128
|
+
|
129
|
+
type_match = task_signature.runnable_with?(params) do |mismatch_message|
|
130
|
+
exception = with_stack(:TYPE_MISMATCH, mismatch_message)
|
131
|
+
error_set << Bolt::Result.from_exception(target, exception, action: 'task')
|
132
|
+
end
|
133
|
+
|
134
|
+
next unless type_match
|
135
|
+
end
|
136
|
+
|
137
|
+
# If there is a type mismatch between the type Data and the type of the params, create
|
138
|
+
# a failing result for the target that will later be added to the ResultSet.
|
139
|
+
unless Puppet::Pops::Types::TypeFactory.data.instance?(params)
|
140
|
+
params_t = Puppet::Pops::Types::TypeCalculator.infer_set(params)
|
141
|
+
desc = Puppet::Pops::Types::TypeMismatchDescriber.singleton.describe_mismatch(
|
142
|
+
'Task parameters are not of type Data. run_task_with()',
|
143
|
+
Puppet::Pops::Types::TypeFactory.data, params_t
|
144
|
+
)
|
145
|
+
exception = with_stack(:TYPE_NOT_DATA, desc)
|
146
|
+
error_set << Bolt::Result.from_exception(target, exception, action: 'task')
|
147
|
+
next
|
148
|
+
end
|
149
|
+
|
150
|
+
# Wrap parameters marked with '"sensitive": true' in the task metadata with a
|
151
|
+
# Sensitive wrapper type. This way it's not shown in logs.
|
152
|
+
if (param_spec = task.parameters)
|
153
|
+
params.each do |k, v|
|
154
|
+
if param_spec[k] && param_spec[k]['sensitive']
|
155
|
+
params[k] = Puppet::Pops::Types::PSensitiveType::Sensitive.new(v)
|
156
|
+
end
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
160
|
+
mapping[target] = task.parameter_defaults.merge(params)
|
161
|
+
end
|
162
|
+
|
163
|
+
# Add a noop parameter if the function was called with the noop metaparameter.
|
164
|
+
if options[:noop]
|
165
|
+
if task.supports_noop
|
166
|
+
target_mapping.each_value { |params| params['_noop'] = true }
|
167
|
+
else
|
168
|
+
raise with_stack(:TASK_NO_NOOP, 'Task does not support noop')
|
169
|
+
end
|
170
|
+
end
|
171
|
+
|
172
|
+
if targets.empty?
|
173
|
+
Bolt::ResultSet.new([])
|
174
|
+
else
|
175
|
+
# Combine the results from the task run with any failing results that were
|
176
|
+
# generated earlier when creating the target mapping
|
177
|
+
task_result = executor.run_task_with(target_mapping, task, options)
|
178
|
+
result = Bolt::ResultSet.new(task_result.results + error_set)
|
179
|
+
|
180
|
+
if !result.ok && !options[:catch_errors]
|
181
|
+
raise Bolt::RunFailure.new(result, 'run_task', task_name)
|
182
|
+
end
|
183
|
+
|
184
|
+
result
|
185
|
+
end
|
186
|
+
end
|
187
|
+
|
188
|
+
def with_stack(kind, msg)
|
189
|
+
issue = Puppet::Pops::Issues.issue(kind) { msg }
|
190
|
+
Puppet::ParseErrorWithIssue.from_issue_and_stack(issue)
|
191
|
+
end
|
192
|
+
end
|
@@ -0,0 +1,122 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'bolt/error'
|
4
|
+
|
5
|
+
# Sets one or more ResourceInstances on a Target. This function does not apply or modify
|
6
|
+
# resources on a target.
|
7
|
+
#
|
8
|
+
# For more information about resources see [the
|
9
|
+
# documentation](https://puppet.com/docs/puppet/latest/lang_resources.html).
|
10
|
+
#
|
11
|
+
# > **Note:** The `ResourceInstance` data type is under active development and is subject to
|
12
|
+
# change. You can read more about the data type in the [experimental features
|
13
|
+
# documentation](experimental_features.md#resourceinstance-data-type).
|
14
|
+
#
|
15
|
+
# > **Note:** Not available in apply block
|
16
|
+
Puppet::Functions.create_function(:set_resources) do
|
17
|
+
# Set multiple resources
|
18
|
+
# @param target The `Target` object to add resources to. See {get_targets}.
|
19
|
+
# @param resources The resources to set on the target.
|
20
|
+
# @return The added `ResourceInstance` objects.
|
21
|
+
# @example Add multiple resources to a target with an array of `ResourceInstance` objects.
|
22
|
+
# $resource1 = ResourceInstance.new(
|
23
|
+
# 'target' => $target,
|
24
|
+
# 'type' => 'file',
|
25
|
+
# 'title' => '/etc/puppetlabs',
|
26
|
+
# 'state' => { 'ensure' => 'present' }
|
27
|
+
# )
|
28
|
+
# $resource2 = ResourceInstance.new(
|
29
|
+
# 'target' => $target,
|
30
|
+
# 'type' => 'package',
|
31
|
+
# 'title' => 'openssl',
|
32
|
+
# 'state' => { 'ensure' => 'installed' }
|
33
|
+
# )
|
34
|
+
# $target.set_resources([$resource1, $resource2])
|
35
|
+
# @example Add resources retrieved with [`get_resources`](#get_resources) to a target.
|
36
|
+
# $target.apply_prep
|
37
|
+
# $resources = $target.get_resources(Package).first['resources']
|
38
|
+
# $target.set_resources($resources)
|
39
|
+
dispatch :set_resources do
|
40
|
+
param 'Target', :target
|
41
|
+
param 'Array[Variant[Hash, ResourceInstance]]', :resources
|
42
|
+
return_type 'Array[ResourceInstance]'
|
43
|
+
end
|
44
|
+
|
45
|
+
# Set a single resource
|
46
|
+
# @param target The `Target` object to add resources to. See {get_targets}.
|
47
|
+
# @param resource The resource to set on the target.
|
48
|
+
# @return The added `ResourceInstance` object.
|
49
|
+
# @example Add a single resource to a target with a resource data hash.
|
50
|
+
# $resource = {
|
51
|
+
# 'type' => 'file',
|
52
|
+
# 'title' => '/etc/puppetlabs',
|
53
|
+
# 'state' => { 'ensure' => 'present' }
|
54
|
+
# }
|
55
|
+
# $target.set_resources($resource)
|
56
|
+
dispatch :set_resource do
|
57
|
+
param 'Target', :target
|
58
|
+
param 'Variant[Hash, ResourceInstance]', :resource
|
59
|
+
return_type 'Array[ResourceInstance]'
|
60
|
+
end
|
61
|
+
|
62
|
+
def set_resources(target, resources)
|
63
|
+
unless Puppet[:tasks]
|
64
|
+
raise Puppet::ParseErrorWithIssue
|
65
|
+
.from_issue_and_stack(
|
66
|
+
Bolt::PAL::Issues::PLAN_OPERATION_NOT_SUPPORTED_WHEN_COMPILING,
|
67
|
+
action: 'set_resources'
|
68
|
+
)
|
69
|
+
end
|
70
|
+
|
71
|
+
inventory = Puppet.lookup(:bolt_inventory)
|
72
|
+
executor = Puppet.lookup(:bolt_executor)
|
73
|
+
executor.report_function_call(self.class.name)
|
74
|
+
|
75
|
+
inventory_target = inventory.get_target(target)
|
76
|
+
|
77
|
+
resources.uniq.map do |resource|
|
78
|
+
if resource.is_a?(Hash)
|
79
|
+
# ResourceInstance expects a Target object, so either get a specified target from
|
80
|
+
# the inventory or use the target this function was called on.
|
81
|
+
resource_target = if resource.key?('target')
|
82
|
+
inventory.get_target(resource['target'])
|
83
|
+
else
|
84
|
+
inventory_target
|
85
|
+
end
|
86
|
+
|
87
|
+
# Observed state from get_resources() is under the 'parameters' key
|
88
|
+
resource_state = resource['state'] || resource['parameters']
|
89
|
+
|
90
|
+
init_hash = {
|
91
|
+
'target' => resource_target,
|
92
|
+
'type' => resource['type'],
|
93
|
+
'title' => resource['title'],
|
94
|
+
'state' => resource_state,
|
95
|
+
'desired_state' => resource['desired_state'],
|
96
|
+
'events' => resource['events']
|
97
|
+
}
|
98
|
+
|
99
|
+
# Calling Bolt::ResourceInstance.new or Bolt::ResourceInstance.from_asserted_hash
|
100
|
+
# will not perform any validation on the parameters. Instead, we need to use the
|
101
|
+
# Puppet constructor to initialize the object, which will first validate the parameters
|
102
|
+
# and then call Bolt::ResourceInstance.from_asserted_hash internally. To do this we
|
103
|
+
# first need to get the Puppet datatype and then call the new function on that type.
|
104
|
+
type = Puppet::Pops::Types::TypeParser.singleton.parse('ResourceInstance')
|
105
|
+
resource = call_function('new', type, init_hash)
|
106
|
+
end
|
107
|
+
|
108
|
+
unless resource.target == inventory_target
|
109
|
+
file, line = Puppet::Pops::PuppetStack.top_of_stack
|
110
|
+
raise Bolt::ValidationError, "Cannot set resource #{resource.reference} for target "\
|
111
|
+
"#{resource.target} on target #{inventory_target}. "\
|
112
|
+
"#{Puppet::Util::Errors.error_location(file, line)}"
|
113
|
+
end
|
114
|
+
|
115
|
+
inventory_target.set_resource(resource)
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
def set_resource(target, resource)
|
120
|
+
set_resources(target, [resource])
|
121
|
+
end
|
122
|
+
end
|
@@ -2,4 +2,15 @@
|
|
2
2
|
# should be used as the return type of functions that run plans and return the
|
3
3
|
# results.
|
4
4
|
|
5
|
-
type Boltlib::PlanResult = Variant[Boolean,
|
5
|
+
type Boltlib::PlanResult = Variant[Boolean,
|
6
|
+
Numeric,
|
7
|
+
String,
|
8
|
+
Undef,
|
9
|
+
Error,
|
10
|
+
Result,
|
11
|
+
ApplyResult,
|
12
|
+
ResultSet,
|
13
|
+
Target,
|
14
|
+
ResourceInstance,
|
15
|
+
Array[Boltlib::PlanResult],
|
16
|
+
Hash[String, Boltlib::PlanResult]]
|