bolt 1.31.1 → 1.32.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/bolt-modules/boltlib/lib/puppet/datatypes/target.rb +49 -16
- data/bolt-modules/boltlib/lib/puppet/functions/get_resources.rb +9 -2
- data/bolt-modules/boltlib/lib/puppet/functions/get_target.rb +36 -0
- data/bolt-modules/boltlib/lib/puppet/functions/run_plan.rb +42 -0
- data/bolt-modules/boltlib/lib/puppet/functions/set_config.rb +46 -0
- data/bolt-modules/boltlib/lib/puppet/functions/set_feature.rb +1 -0
- data/bolt-modules/boltlib/lib/puppet/functions/set_var.rb +6 -2
- data/lib/bolt/analytics.rb +1 -1
- data/lib/bolt/apply_result.rb +23 -0
- data/lib/bolt/bolt_option_parser.rb +16 -0
- data/lib/bolt/boltdir.rb +3 -1
- data/lib/bolt/cli.rb +20 -6
- data/lib/bolt/config.rb +1 -3
- data/lib/bolt/inventory/group2.rb +40 -34
- data/lib/bolt/inventory/inventory2.rb +203 -134
- data/lib/bolt/inventory.rb +2 -3
- data/lib/bolt/pal/issues.rb +6 -0
- data/lib/bolt/pal.rb +29 -1
- data/lib/bolt/plugin.rb +2 -2
- data/lib/bolt/secret/base.rb +3 -1
- data/lib/bolt/target.rb +147 -0
- data/lib/bolt/task.rb +1 -1
- data/lib/bolt/transport/powershell.rb +12 -5
- data/lib/bolt/transport/winrm.rb +1 -2
- data/lib/bolt/version.rb +1 -1
- data/lib/bolt_server/schemas/action-run_script.json +4 -1
- data/lib/bolt_spec/plans/mock_executor.rb +17 -0
- data/lib/bolt_spec/plans/publish_stub.rb +49 -0
- data/lib/bolt_spec/plans.rb +18 -1
- data/lib/bolt_spec/run.rb +5 -2
- data/lib/plan_executor/app.rb +1 -1
- metadata +5 -2
@@ -5,6 +5,7 @@ require 'bolt/inventory/group2'
|
|
5
5
|
module Bolt
|
6
6
|
class Inventory
|
7
7
|
class Inventory2
|
8
|
+
attr_reader :targets, :plugins, :config
|
8
9
|
# This uses "targets" in the message instead of "nodes"
|
9
10
|
class WildcardError < Bolt::Error
|
10
11
|
def initialize(target)
|
@@ -12,11 +13,7 @@ module Bolt
|
|
12
13
|
end
|
13
14
|
end
|
14
15
|
|
15
|
-
|
16
|
-
|
17
|
-
def initialize(data, config = nil, plugins: nil, target_vars: {},
|
18
|
-
target_facts: {}, target_features: {},
|
19
|
-
target_plugin_hooks: {})
|
16
|
+
def initialize(data, config = nil, plugins: nil)
|
20
17
|
@logger = Logging.logger[self]
|
21
18
|
# Config is saved to add config options to targets
|
22
19
|
@config = config || Bolt::Config.default
|
@@ -24,10 +21,8 @@ module Bolt
|
|
24
21
|
@groups = Group2.new(@data.merge('name' => 'all'), plugins)
|
25
22
|
@plugins = plugins
|
26
23
|
@group_lookup = {}
|
27
|
-
|
28
|
-
@
|
29
|
-
@target_features = target_features
|
30
|
-
@target_plugin_hooks = target_plugin_hooks
|
24
|
+
# The targets hash is the canonical source for all targets in inventory
|
25
|
+
@targets = {}
|
31
26
|
@groups.resolve_aliases(@groups.target_aliases, @groups.target_names)
|
32
27
|
collect_groups
|
33
28
|
end
|
@@ -40,6 +35,10 @@ module Bolt
|
|
40
35
|
2
|
41
36
|
end
|
42
37
|
|
38
|
+
def target_implementation_class
|
39
|
+
Bolt::Target2
|
40
|
+
end
|
41
|
+
|
43
42
|
def collect_groups
|
44
43
|
# Provide a lookup map for finding a group by name
|
45
44
|
@group_lookup = @groups.collect_groups
|
@@ -56,13 +55,15 @@ module Bolt
|
|
56
55
|
alias node_names target_names
|
57
56
|
|
58
57
|
def get_targets(targets)
|
59
|
-
targets
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
58
|
+
flat_target_list(targets).map { |t| update_target(t) }
|
59
|
+
end
|
60
|
+
|
61
|
+
def get_target(target)
|
62
|
+
target_array = flat_target_list(target)
|
63
|
+
if target_array.count > 1
|
64
|
+
raise ValidationError.new("'#{target}' refers to #{target_array.count} targets", nil)
|
65
|
+
end
|
66
|
+
get_targets(target_array.first).first
|
66
67
|
end
|
67
68
|
|
68
69
|
def add_to_group(targets, desired_group)
|
@@ -78,41 +79,6 @@ module Bolt
|
|
78
79
|
end
|
79
80
|
end
|
80
81
|
|
81
|
-
def set_var(target, key, value)
|
82
|
-
data = { key => value }
|
83
|
-
set_vars_from_hash(target.name, data)
|
84
|
-
end
|
85
|
-
|
86
|
-
def vars(target)
|
87
|
-
@target_vars[target.name] || {}
|
88
|
-
end
|
89
|
-
|
90
|
-
def add_facts(target, new_facts = {})
|
91
|
-
@logger.warn("No facts to add") if new_facts.empty?
|
92
|
-
set_facts(target.name, new_facts)
|
93
|
-
end
|
94
|
-
|
95
|
-
def facts(target)
|
96
|
-
@target_facts[target.name] || {}
|
97
|
-
end
|
98
|
-
|
99
|
-
def set_feature(target, feature, value = true)
|
100
|
-
@target_features[target.name] ||= Set.new
|
101
|
-
if value
|
102
|
-
@target_features[target.name] << feature
|
103
|
-
else
|
104
|
-
@target_features[target.name].delete(feature)
|
105
|
-
end
|
106
|
-
end
|
107
|
-
|
108
|
-
def features(target)
|
109
|
-
@target_features[target.name] || Set.new
|
110
|
-
end
|
111
|
-
|
112
|
-
def plugin_hooks(target)
|
113
|
-
@target_plugin_hooks[target.name] || {}
|
114
|
-
end
|
115
|
-
|
116
82
|
def data_hash
|
117
83
|
{
|
118
84
|
data: {},
|
@@ -147,8 +113,13 @@ module Bolt
|
|
147
113
|
private :config_plugin
|
148
114
|
|
149
115
|
# Pass a target to get_targets for a public version of this
|
150
|
-
# Should this reconfigure configured targets?
|
151
116
|
def update_target(target)
|
117
|
+
# Ensure all targets in inventory are included in the all group.
|
118
|
+
unless @groups.target_names.include?(target.name)
|
119
|
+
add_to_group([target], 'all')
|
120
|
+
end
|
121
|
+
|
122
|
+
# Get merged data between targets and groups
|
152
123
|
data = @groups.data_for(target.name)
|
153
124
|
data ||= {}
|
154
125
|
|
@@ -157,23 +128,24 @@ module Bolt
|
|
157
128
|
data['config'] = {}
|
158
129
|
end
|
159
130
|
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
set_vars_from_hash(target.name, data['vars']) unless @target_vars[target.name]
|
164
|
-
set_facts(target.name, data['facts']) unless @target_facts[target.name]
|
165
|
-
data['features']&.each { |feature| set_feature(target, feature) } unless @target_features[target.name]
|
166
|
-
unless @target_plugin_hooks[target.name]
|
167
|
-
set_plugin_hooks(target.name, @config.plugin_hooks.merge(data['plugin_hooks'] || {}))
|
131
|
+
# Add defaults for special 'localhost' target (currently just config and features)
|
132
|
+
if target.name == 'localhost'
|
133
|
+
data = Bolt::Inventory.localhost_defaults(data)
|
168
134
|
end
|
135
|
+
|
136
|
+
# Data from inventory
|
169
137
|
data['config'] = config_plugin(data['config'])
|
138
|
+
# Data from set_config (make sure to resolve plugins)
|
139
|
+
resolved_target_config = config_plugin(@targets[target.name]['config'] || {})
|
140
|
+
data['config'] = Bolt::Util.deep_merge(data['config'], resolved_target_config)
|
170
141
|
|
171
142
|
# Use Config object to ensure config section is treated consistently with config file
|
172
143
|
conf = @config.deep_clone
|
173
144
|
conf.update_from_inventory(data['config'])
|
174
145
|
conf.validate
|
175
146
|
|
176
|
-
target
|
147
|
+
# Recompute the target cached state with the merged data
|
148
|
+
update_target_state(target, conf.transport_conf, data)
|
177
149
|
|
178
150
|
unless target.transport.nil? || Bolt::TRANSPORTS.include?(target.transport.to_sym)
|
179
151
|
raise Bolt::UnknownTransportError.new(target.transport, target.uri)
|
@@ -183,6 +155,17 @@ module Bolt
|
|
183
155
|
end
|
184
156
|
private :update_target
|
185
157
|
|
158
|
+
# This algorithm for getting a flat list of targets is used several times.
|
159
|
+
def flat_target_list(targets)
|
160
|
+
target_array = expand_targets(targets)
|
161
|
+
if target_array.is_a? Array
|
162
|
+
target_array.flatten.uniq(&:name)
|
163
|
+
else
|
164
|
+
[target_array]
|
165
|
+
end
|
166
|
+
end
|
167
|
+
private :flat_target_list
|
168
|
+
|
186
169
|
# If target is a group name, expand it to the members of that group.
|
187
170
|
# Else match against targets in inventory by name or alias.
|
188
171
|
# If a wildcard string, error if no matches are found.
|
@@ -209,8 +192,7 @@ module Bolt
|
|
209
192
|
private :resolve_name
|
210
193
|
|
211
194
|
def expand_targets(targets)
|
212
|
-
if targets.is_a? Bolt::
|
213
|
-
targets.inventory = self
|
195
|
+
if targets.is_a? Bolt::Target2
|
214
196
|
targets
|
215
197
|
elsif targets.is_a? Array
|
216
198
|
targets.map { |tish| expand_targets(tish) }
|
@@ -219,102 +201,189 @@ module Bolt
|
|
219
201
|
targets.split(/[[:space:],]+/).reject(&:empty?).map do |name|
|
220
202
|
ts = resolve_name(name)
|
221
203
|
ts.map do |t|
|
222
|
-
target
|
223
|
-
|
224
|
-
target
|
204
|
+
# If the target exists, return it, otherwise create one
|
205
|
+
@targets[t] ? @targets[t]['self'] : create_target(t)
|
225
206
|
end
|
226
207
|
end
|
227
208
|
end
|
228
209
|
end
|
229
210
|
private :expand_targets
|
230
211
|
|
231
|
-
def
|
232
|
-
if
|
233
|
-
|
234
|
-
@
|
235
|
-
|
236
|
-
|
237
|
-
|
212
|
+
def add_target(current_group, target, desired_group)
|
213
|
+
if current_group.name == desired_group
|
214
|
+
current_group.add_target(target.target_data_hash)
|
215
|
+
@groups.validate
|
216
|
+
update_target(target)
|
217
|
+
return true
|
218
|
+
end
|
219
|
+
# Recurse on children Groups if not desired_group
|
220
|
+
current_group.groups.each do |child_group|
|
221
|
+
add_target(child_group, target, desired_group)
|
238
222
|
end
|
239
223
|
end
|
240
|
-
private :
|
224
|
+
private :add_target
|
241
225
|
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
226
|
+
# This is effectively the init method for Target2
|
227
|
+
def create_target(target_name, target_hash = nil)
|
228
|
+
# Prefer target hash, then data from inventoryfile, allow for uri only with empty hash
|
229
|
+
data = target_hash || @groups.target_collect(target_name) || {}
|
230
|
+
data = { 'uri' => target_name } if data['uri'].nil? && data['name'].nil?
|
231
|
+
data['uri_obj'] = Bolt::Inventory::Inventory2.parse_uri(data['uri'])
|
232
|
+
|
233
|
+
if data['uri'] && data['name'].nil?
|
234
|
+
data['name'] = data['uri']
|
235
|
+
data['safe_name'] = data['uri_obj'].omit(:password).to_str.sub(%r{^//}, '')
|
236
|
+
elsif data['name']
|
237
|
+
data['safe_name'] = data['name']
|
238
|
+
else
|
239
|
+
data['name'] = target_name
|
240
|
+
data['safe_name'] = if data['uri_obj']
|
241
|
+
data['uri_obj'].omit(:password).to_str.sub(%r{^//}, '')
|
242
|
+
else
|
243
|
+
target_name
|
244
|
+
end
|
245
|
+
end
|
246
|
+
unless data['name'].ascii_only?
|
247
|
+
raise ValidationError.new("Target name must be ASCII characters: #{data['name']}", nil)
|
246
248
|
end
|
249
|
+
# Data set on target itself (either in inventory, target.new or with set_config)
|
250
|
+
data['config'] ||= {}
|
251
|
+
data['vars'] ||= {}
|
252
|
+
data['facts'] ||= {}
|
253
|
+
data['features'] = data['features'] ? Set.new(data['features']) : Set.new
|
254
|
+
data['groups'] ||= []
|
255
|
+
data['options'] ||= {}
|
256
|
+
data['plugin_hooks'] ||= {}
|
257
|
+
data['target_alias'] ||= []
|
258
|
+
|
259
|
+
# Every call to update_target will rebuild this state based on merging together target, group, and config data
|
260
|
+
data['cached_state'] = {}
|
261
|
+
|
262
|
+
target = Target2.new(nil, data['name'])
|
263
|
+
target.inventory = self
|
264
|
+
data['self'] = target
|
265
|
+
@targets[data['name']] = data
|
266
|
+
target
|
247
267
|
end
|
248
|
-
private :
|
268
|
+
private :create_target
|
269
|
+
|
270
|
+
def create_target_from_plan(data)
|
271
|
+
t_name = data['name'] || data['uri']
|
249
272
|
|
250
|
-
|
251
|
-
if
|
252
|
-
@
|
253
|
-
|
273
|
+
# If target already exists, delete old and replace with new, otherwise add to new to all group
|
274
|
+
if @targets[t_name]
|
275
|
+
@targets.delete(t_name)
|
276
|
+
t = create_target(t_name, data)
|
277
|
+
update_target(t)
|
278
|
+
else
|
279
|
+
t = create_target(t_name, data)
|
280
|
+
update_target(t)
|
281
|
+
add_to_group([t], 'all')
|
254
282
|
end
|
283
|
+
t
|
255
284
|
end
|
256
|
-
private :set_plugin_hooks
|
257
285
|
|
258
|
-
def
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
features: current_group.features,
|
271
|
-
plugin_hooks: current_group.plugin_hooks }
|
272
|
-
data = inherit_data(track, current_group.name, current_group_data)
|
273
|
-
set_facts(t_name, @target_facts[t_name] ? data[:facts].merge(@target_facts[t_name]) : data[:facts])
|
274
|
-
set_vars_from_hash(t_name, @target_vars[t_name] ? data[:vars].merge(@target_vars[t_name]) : data[:vars])
|
275
|
-
data[:features].each do |feature|
|
276
|
-
set_feature(target, feature)
|
277
|
-
end
|
278
|
-
hook_data = @config.plugin_hooks.merge(data[:plugin_hooks])
|
279
|
-
hash = if @target_plugin_hooks[t_name]
|
280
|
-
hook_data.merge(@target_plugin_hooks[t_name])
|
281
|
-
else
|
282
|
-
hook_data
|
283
|
-
end
|
284
|
-
set_plugin_hooks(t_name, hash)
|
285
|
-
return true
|
286
|
+
def self.parse_uri(string)
|
287
|
+
require 'addressable/uri'
|
288
|
+
if string.nil?
|
289
|
+
nil
|
290
|
+
# Forbid empty uri
|
291
|
+
elsif string.empty?
|
292
|
+
raise Bolt::ParseError, "Could not parse target URI: URI is empty string"
|
293
|
+
elsif string =~ %r{^[^:]+://}
|
294
|
+
Addressable::URI.parse(string)
|
295
|
+
else
|
296
|
+
# Initialize with an empty scheme to ensure we parse the hostname correctly
|
297
|
+
Addressable::URI.parse("//#{string}")
|
286
298
|
end
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
299
|
+
rescue Addressable::URI::InvalidURIError => e
|
300
|
+
raise Bolt::ParseError, "Could not parse target URI: #{e.message}"
|
301
|
+
end
|
302
|
+
|
303
|
+
def set_var(target, var_hash)
|
304
|
+
@targets[target.name]['vars'] = @targets[target.name]['vars'].merge(var_hash)
|
305
|
+
update_target(target)
|
306
|
+
end
|
307
|
+
|
308
|
+
def vars(target)
|
309
|
+
@targets[target.name]['cached_state']['vars'] || {}
|
310
|
+
end
|
311
|
+
|
312
|
+
def add_facts(target, new_facts = {})
|
313
|
+
@targets[target.name]['facts'] = Bolt::Util.deep_merge(@targets[target.name]['facts'], new_facts)
|
314
|
+
update_target(target)
|
315
|
+
facts(target)
|
316
|
+
end
|
317
|
+
|
318
|
+
def facts(target)
|
319
|
+
@targets[target.name]['cached_state']['facts'] || {}
|
320
|
+
end
|
321
|
+
|
322
|
+
def set_feature(target, feature, value = true)
|
323
|
+
if value
|
324
|
+
@targets[target.name]['features'] << feature
|
325
|
+
else
|
326
|
+
@targets[target.name]['features'].delete(feature)
|
291
327
|
end
|
328
|
+
update_target(target)
|
292
329
|
end
|
293
|
-
private :add_target
|
294
330
|
|
295
|
-
def
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
data[:plugin_hooks] = track[name].plugin_hooks.merge(data[:plugin_hooks])
|
301
|
-
inherit_data(track, track[name].name, data)
|
331
|
+
def features(target)
|
332
|
+
if @targets[target.name]['cached_state']['features']
|
333
|
+
Set.new(@targets[target.name]['cached_state']['features'])
|
334
|
+
else
|
335
|
+
Set.new
|
302
336
|
end
|
303
|
-
data
|
304
337
|
end
|
305
|
-
private :inherit_data
|
306
338
|
|
307
|
-
def
|
308
|
-
|
309
|
-
|
310
|
-
name_opt['name'] = data['name'] if data['name']
|
339
|
+
def plugin_hooks(target)
|
340
|
+
@targets[target.name]['cached_state']['plugin_hooks'] || {}
|
341
|
+
end
|
311
342
|
|
312
|
-
|
313
|
-
|
314
|
-
|
343
|
+
def set_config(target, key_or_key_path, value)
|
344
|
+
config = key_or_key_path.empty? ? value : build_config_hash([key_or_key_path].flatten, value)
|
345
|
+
@targets[target.name]['config'] = @targets[target.name]['config'].merge(config)
|
346
|
+
update_target(target)
|
347
|
+
end
|
348
|
+
|
349
|
+
def target_config(target)
|
350
|
+
@targets[target.name]['cached_state']['config'] || {}
|
351
|
+
end
|
315
352
|
|
316
|
-
|
353
|
+
def build_config_hash(key_or_key_path, value)
|
354
|
+
# https://stackoverflow.com/questions/5095077/ruby-convert-array-to-nested-hash
|
355
|
+
key_or_key_path.reverse.inject(value) { |acc, key| { key => acc } }
|
356
|
+
end
|
357
|
+
private :build_config_hash
|
358
|
+
|
359
|
+
def update_target_state(target, conf, merged_data)
|
360
|
+
@targets[target.name]['protocol'] = conf[:transport]
|
361
|
+
t_conf = conf[:transports][target.transport.to_sym] || {}
|
362
|
+
@targets[target.name]['user'] = t_conf['user']
|
363
|
+
@targets[target.name]['password'] = t_conf['password']
|
364
|
+
@targets[target.name]['port'] = t_conf['port']
|
365
|
+
@targets[target.name]['host'] = t_conf['host']
|
366
|
+
@targets[target.name]['options'] = t_conf
|
367
|
+
|
368
|
+
@targets[target.name]['cached_state'] = merged_data
|
369
|
+
|
370
|
+
target_facts = @targets[target.name]['facts'] || {}
|
371
|
+
new_facts = merged_data['facts'] || {}
|
372
|
+
@targets[target.name]['cached_state']['facts'] = Bolt::Util.deep_merge(new_facts, target_facts)
|
373
|
+
|
374
|
+
target_vars = @targets[target.name]['vars'] || {}
|
375
|
+
new_vars = merged_data['vars'] || {}
|
376
|
+
@targets[target.name]['cached_state']['vars'] = new_vars.merge(target_vars)
|
377
|
+
|
378
|
+
target_features = Set.new(@targets[target.name]['features'])
|
379
|
+
new_features = Set.new(merged_data['features'])
|
380
|
+
@targets[target.name]['cached_state']['features'] = new_features.merge(target_features)
|
381
|
+
|
382
|
+
target_plugin_hooks = @targets[target.name]['plugin_hooks'] || {}
|
383
|
+
new_plugin_hooks = merged_data['plugin_hooks'] || {}
|
384
|
+
@targets[target.name]['cached_state']['plugin_hooks'] = new_plugin_hooks.merge(target_plugin_hooks)
|
317
385
|
end
|
386
|
+
private :update_target_state
|
318
387
|
end
|
319
388
|
end
|
320
389
|
end
|
data/lib/bolt/inventory.rb
CHANGED
@@ -139,9 +139,8 @@ module Bolt
|
|
139
139
|
end
|
140
140
|
end
|
141
141
|
|
142
|
-
def set_var(target,
|
143
|
-
|
144
|
-
set_vars_from_hash(target.name, data)
|
142
|
+
def set_var(target, var_hash)
|
143
|
+
set_vars_from_hash(target.name, var_hash)
|
145
144
|
end
|
146
145
|
|
147
146
|
def vars(target)
|
data/lib/bolt/pal/issues.rb
CHANGED
@@ -8,6 +8,12 @@ module Bolt
|
|
8
8
|
Puppet::Pops::Issues.issue :PLAN_OPERATION_NOT_SUPPORTED_WHEN_COMPILING, :action do
|
9
9
|
"Plan language function '#{action}' cannot be used from declarative manifest code or apply blocks"
|
10
10
|
end
|
11
|
+
|
12
|
+
# Inventory version 2
|
13
|
+
UNSUPPORTED_INVENTORY_VERSION =
|
14
|
+
Puppet::Pops::Issues.issue :UNSUPPORTED_INVENTORY_VERSION, :action do
|
15
|
+
"Plan language function '#{action}' cannot be used with Inventory v1"
|
16
|
+
end
|
11
17
|
end
|
12
18
|
end
|
13
19
|
end
|
data/lib/bolt/pal.rb
CHANGED
@@ -39,7 +39,7 @@ module Bolt
|
|
39
39
|
|
40
40
|
attr_reader :modulepath
|
41
41
|
|
42
|
-
def initialize(modulepath, hiera_config, max_compiles = Etc.nprocessors)
|
42
|
+
def initialize(modulepath, hiera_config, resource_types, max_compiles = Etc.nprocessors)
|
43
43
|
# Nothing works without initialized this global state. Reinitializing
|
44
44
|
# is safe and in practice only happens in tests
|
45
45
|
self.class.load_puppet
|
@@ -48,6 +48,7 @@ module Bolt
|
|
48
48
|
@modulepath = [BOLTLIB_PATH, *modulepath, MODULES_PATH]
|
49
49
|
@hiera_config = hiera_config
|
50
50
|
@max_compiles = max_compiles
|
51
|
+
@resource_types = resource_types
|
51
52
|
|
52
53
|
@logger = Logging.logger[self]
|
53
54
|
if modulepath && !modulepath.empty?
|
@@ -110,6 +111,22 @@ module Bolt
|
|
110
111
|
compiler.evaluate_string('type PlanResult = Boltlib::PlanResult')
|
111
112
|
end
|
112
113
|
|
114
|
+
# Register all resource types defined in $Boltdir/.resource_types as well as
|
115
|
+
# the built in types registered with the runtime_3_init method.
|
116
|
+
def register_resource_types(loaders)
|
117
|
+
static_loader = loaders.static_loader
|
118
|
+
static_loader.runtime_3_init
|
119
|
+
if File.directory?(@resource_types)
|
120
|
+
# Ruby 2.3 does not support Dir.children
|
121
|
+
(Dir.entries(@resource_types) - %w[. ..]).each do |resource_pp|
|
122
|
+
type_name_from_file = File.basename(resource_pp, '.pp').capitalize
|
123
|
+
typed_name = Puppet::Pops::Loader::TypedName.new(:type, type_name_from_file)
|
124
|
+
resource_type = Puppet::Pops::Types::TypeFactory.resource(type_name_from_file)
|
125
|
+
loaders.static_loader.set_entry(typed_name, resource_type)
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
113
130
|
# Runs a block in a PAL script compiler configured for Bolt. Catches
|
114
131
|
# exceptions thrown by the block and re-raises them ensuring they are
|
115
132
|
# Bolt::Errors since the script compiler block will squash all exceptions.
|
@@ -119,6 +136,7 @@ module Bolt
|
|
119
136
|
r = Puppet::Pal.in_tmp_environment('bolt', modulepath: @modulepath, facts: {}) do |pal|
|
120
137
|
pal.with_script_compiler do |compiler|
|
121
138
|
alias_types(compiler)
|
139
|
+
register_resource_types(Puppet.lookup(:loaders)) if @resource_types
|
122
140
|
begin
|
123
141
|
Puppet.override(yaml_plan_instantiator: Bolt::PAL::YamlPlan::Loader) do
|
124
142
|
yield compiler
|
@@ -351,6 +369,16 @@ module Bolt
|
|
351
369
|
end
|
352
370
|
end
|
353
371
|
|
372
|
+
def generate_types
|
373
|
+
require 'puppet/face/generate'
|
374
|
+
in_bolt_compiler do
|
375
|
+
generator = Puppet::Generate::Type
|
376
|
+
inputs = generator.find_inputs(:pcore)
|
377
|
+
FileUtils.mkdir_p(@resource_types)
|
378
|
+
generator.generate(inputs, @resource_types, true)
|
379
|
+
end
|
380
|
+
end
|
381
|
+
|
354
382
|
def run_task(task_name, targets, params, executor, inventory, description = nil)
|
355
383
|
in_task_compiler(executor, inventory) do |compiler|
|
356
384
|
params = params.merge('_bolt_api_call' => true, '_catch_errors' => true)
|
data/lib/bolt/plugin.rb
CHANGED
@@ -134,7 +134,7 @@ module Bolt
|
|
134
134
|
plugins
|
135
135
|
end
|
136
136
|
|
137
|
-
BUILTIN_PLUGINS = %w[task terraform pkcs7 prompt vault aws_inventory puppetdb].freeze
|
137
|
+
BUILTIN_PLUGINS = %w[task terraform pkcs7 prompt vault aws_inventory puppetdb azure_inventory].freeze
|
138
138
|
|
139
139
|
attr_reader :pal, :plugin_context
|
140
140
|
|
@@ -193,7 +193,7 @@ module Bolt
|
|
193
193
|
plugin = by_name(plugin_name)
|
194
194
|
raise PluginError::Unknown, plugin_name unless plugin
|
195
195
|
raise PluginError::UnsupportedHook.new(plugin_name, hook) unless plugin.hooks.include?(hook)
|
196
|
-
@analytics.report_bundled_content("Plugin #{hook}", plugin_name)
|
196
|
+
@analytics.report_bundled_content("Plugin #{hook}", plugin_name)
|
197
197
|
|
198
198
|
plugin.method(hook)
|
199
199
|
end
|
data/lib/bolt/secret/base.rb
CHANGED
@@ -36,7 +36,9 @@ module Bolt
|
|
36
36
|
def validate_resolve_reference(opts)
|
37
37
|
# TODO: Remove deprecation warning
|
38
38
|
if opts.include?('encrypted-value')
|
39
|
-
|
39
|
+
msg = "Parsing error: The 'encrypted-value' key is deprecated and can no longer be used. " \
|
40
|
+
"In your Bolt config files, please use 'encrypted_value' instead."
|
41
|
+
raise Bolt::ValidationError, msg
|
40
42
|
end
|
41
43
|
decode(opts['encrypted_value'])
|
42
44
|
end
|