bolt 1.41.0 → 1.42.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: bc1e64c9534b1225ee0b2e7d33082fc5c811a01b530910ca1885920d1ead4af3
4
- data.tar.gz: fc120c02dd62a691fc7acac412750329cbbf5e10a78c90402877463cf9f42d99
3
+ metadata.gz: d70e65622c7ae119fafb6212eda5fa66e517bf190f404d00f150d98efa616ce8
4
+ data.tar.gz: 9fdfbbf45efc6b1a3ec4f0364dfaf2d2682de8a30c3ab17b7893db9091da3e9f
5
5
  SHA512:
6
- metadata.gz: 378be37bc8b7ef4c0fc77ca2f3030a45da1d6f0cd3e3733ce8cb2ae0aeb26e34f5542e467397c9dfb56aa7e54765d983939fe7491c684af11b64dc195c8fc632
7
- data.tar.gz: 666ea5b5111b85f41243c1aefe495ff5b1b87e4dcf4e4dcd6b202397ade6dad252e202eaf3e3549558f669b0e0563e04ce2537b58f363cfea32ac6952eb3d234
6
+ metadata.gz: 3ba016ff367bf902b3a512ec7a6f3c46bac6fed6a16ef207400af12a741821a5aa5baa18b38e8dbbed201d555e71f88eafb38912e4acdb3e715362bb27ec8f51
7
+ data.tar.gz: a37fa6e6f3a703d3d2b7b00c578884a617578800c190105bfbc6398a5febdca5475fa96737f82fd0677b22f174932bf20fb30271964a65f959ebc6cea4dfce6f
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'bolt/error'
4
+
5
+ # Removes a target from the specified inventory group.
6
+ #
7
+ # The target is removed from all child groups and all parent groups where the target has
8
+ # not been explicitly defined. A target cannot be removed from the 'all' group.
9
+ #
10
+ # **NOTE:** Not available in apply block
11
+ Puppet::Functions.create_function(:remove_from_group) do
12
+ # @param target A pattern identifying a single target.
13
+ # @param group The name of the group to remove the target from.
14
+ # @example Remove Target from group.
15
+ # remove_from_group('foo@example.com', 'group1')
16
+ # @example Remove failing Targets from the rest of a plan
17
+ # $result = run_command(uptime, my_group, '_catch_errors' => true)
18
+ # $result.error_set.targets.each |$t| { remove_from_group($t, my_group) }
19
+ # run_command(next_command, my_group) # does not target the failing nodes.
20
+ dispatch :remove_from_group do
21
+ param 'Boltlib::TargetSpec', :target
22
+ param 'String[1]', :group
23
+ end
24
+
25
+ def remove_from_group(target, group)
26
+ unless Puppet[:tasks]
27
+ raise Puppet::ParseErrorWithIssue
28
+ .from_issue_and_stack(Bolt::PAL::Issues::PLAN_OPERATION_NOT_SUPPORTED_WHEN_COMPILING,
29
+ action: 'remove_from_group')
30
+ end
31
+
32
+ inventory = Puppet.lookup(:bolt_inventory)
33
+ executor = Puppet.lookup(:bolt_executor)
34
+ executor.report_function_call(self.class.name)
35
+
36
+ inventory.remove_from_group(inventory.get_targets(target), group)
37
+ end
38
+ end
@@ -23,30 +23,54 @@ module Bolt
23
23
  { flags: ACTION_OPTS + %w[noop execute compile-concurrency],
24
24
  banner: APPLY_HELP }
25
25
  when 'command'
26
- { flags: ACTION_OPTS,
27
- banner: COMMAND_HELP }
26
+ case action
27
+ when 'run'
28
+ { flags: ACTION_OPTS,
29
+ banner: COMMAND_RUN_HELP }
30
+ else
31
+ { flags: OPTIONS[:global],
32
+ banner: COMMAND_HELP }
33
+ end
28
34
  when 'file'
29
- { flags: ACTION_OPTS + %w[tmpdir],
30
- banner: FILE_HELP }
35
+ case action
36
+ when 'upload'
37
+ { flags: ACTION_OPTS + %w[tmpdir],
38
+ banner: FILE_UPLOAD_HELP }
39
+ else
40
+ { flags: OPTIONS[:global],
41
+ banner: FILE_HELP }
42
+ end
31
43
  when 'inventory'
32
- { flags: OPTIONS[:inventory] + OPTIONS[:global] + %w[format inventoryfile boltdir configfile detail],
33
- banner: INVENTORY_HELP }
44
+ case action
45
+ when 'show'
46
+ { flags: OPTIONS[:inventory] + OPTIONS[:global] + %w[format inventoryfile boltdir configfile detail],
47
+ banner: INVENTORY_SHOW_HELP }
48
+ else
49
+ { flags: OPTIONS[:global],
50
+ banner: INVENTORY_HELP }
51
+ end
34
52
  when 'group'
35
- { flags: OPTIONS[:global] + %w[format inventoryfile boltdir configfile],
36
- banner: GROUP_HELP }
53
+ case action
54
+ when 'show'
55
+ { flags: OPTIONS[:global] + %w[format inventoryfile boltdir configfile],
56
+ banner: GROUP_SHOW_HELP }
57
+ else
58
+ { flags: OPTIONS[:global],
59
+ banner: GROUP_HELP }
60
+ end
37
61
  when 'plan'
38
62
  case action
39
63
  when 'convert'
40
64
  { flags: OPTIONS[:global] + OPTIONS[:global_config_setters],
41
65
  banner: PLAN_CONVERT_HELP }
42
- when 'show'
43
- { flags: OPTIONS[:global] + OPTIONS[:global_config_setters],
44
- banner: PLAN_SHOW_HELP }
45
66
  when 'run'
46
67
  { flags: ACTION_OPTS + %w[params compile-concurrency tmpdir],
47
68
  banner: PLAN_RUN_HELP }
69
+ when 'show'
70
+ { flags: OPTIONS[:global] + OPTIONS[:global_config_setters],
71
+ banner: PLAN_SHOW_HELP }
48
72
  else
49
- { flags: ACTION_OPTS + %w[params compile-concurrency tmpdir],
73
+ { flags: OPTIONS[:global],
50
74
  banner: PLAN_HELP }
51
75
  end
52
76
  when 'project'
@@ -73,25 +97,43 @@ module Bolt
73
97
  { flags: OPTIONS[:global] + OPTIONS[:global_config_setters],
74
98
  banner: PUPPETFILE_GENERATETYPES_HELP }
75
99
  else
76
- { flags: OPTIONS[:global] + OPTIONS[:global_config_setters],
100
+ { flags: OPTIONS[:global],
77
101
  banner: PUPPETFILE_HELP }
78
102
  end
79
103
  when 'script'
80
- { flags: ACTION_OPTS + %w[tmpdir],
81
- banner: SCRIPT_HELP }
104
+ case action
105
+ when 'run'
106
+ { flags: ACTION_OPTS + %w[tmpdir],
107
+ banner: SCRIPT_RUN_HELP }
108
+ else
109
+ { flags: OPTIONS[:global],
110
+ banner: SCRIPT_HELP }
111
+ end
82
112
  when 'secret'
83
- { flags: OPTIONS[:global] + OPTIONS[:global_config_setters] + %w[plugin],
84
- banner: SECRET_HELP }
113
+ case action
114
+ when 'createkeys'
115
+ { flags: OPTIONS[:global] + OPTIONS[:global_config_setters] + %w[plugin],
116
+ banner: SECRET_CREATEKEYS_HELP }
117
+ when 'decrypt'
118
+ { flags: OPTIONS[:global] + OPTIONS[:global_config_setters] + %w[plugin],
119
+ banner: SECRET_DECRYPT_HELP }
120
+ when 'encrypt'
121
+ { flags: OPTIONS[:global] + OPTIONS[:global_config_setters] + %w[plugin],
122
+ banner: SECRET_ENCRYPT_HELP }
123
+ else
124
+ { flags: OPTIONS[:global],
125
+ banner: SECRET_HELP }
126
+ end
85
127
  when 'task'
86
128
  case action
87
- when 'show'
88
- { flags: OPTIONS[:global] + OPTIONS[:global_config_setters],
89
- banner: TASK_SHOW_HELP }
90
129
  when 'run'
91
130
  { flags: ACTION_OPTS + %w[params tmpdir],
92
131
  banner: TASK_RUN_HELP }
132
+ when 'show'
133
+ { flags: OPTIONS[:global] + OPTIONS[:global_config_setters],
134
+ banner: TASK_SHOW_HELP }
93
135
  else
94
- { flags: ACTION_OPTS + %w[params tmpdir],
136
+ { flags: OPTIONS[:global],
95
137
  banner: TASK_HELP }
96
138
  end
97
139
  else
@@ -100,258 +142,454 @@ module Bolt
100
142
  end
101
143
  end
102
144
 
103
- def self.examples(cmd, desc)
104
- <<~EXAMP
105
- #{desc} a Windows host via WinRM, providing for the password
106
- bolt #{cmd} -n winrm://winhost -u Administrator -p
107
- #{desc} the local machine, a Linux host via SSH, and hosts from a group specified in an inventory file
108
- bolt #{cmd} -n localhost,nixhost,node_group
109
- #{desc} Windows hosts queried from PuppetDB via WinRM as a domain user, prompting for the password
110
- bolt #{cmd} -q 'inventory[certname] { facts.os.family = "windows" }' --transport winrm -u 'domain\\Administrator' -p
111
- EXAMP
112
- end
113
-
114
145
  BANNER = <<~HELP
115
- Usage: bolt <subcommand> <action>
116
-
117
- Available subcommands:
118
- bolt command run <command> Run a command remotely
119
- bolt file upload <src> <dest> Upload a local file or directory
120
- bolt script run <script> Upload a local script and run it remotely
121
- bolt task show Show list of available tasks
122
- bolt task show <task> Show documentation for task
123
- bolt task run <task> [params] Run a Puppet task
124
- bolt plan convert <plan_path> Convert a YAML plan to a Puppet plan
125
- bolt plan show Show list of available plans
126
- bolt plan show <plan> Show details for plan
127
- bolt plan run <plan> [params] Run a Puppet task plan
128
- bolt apply <manifest> Apply Puppet manifest code
129
- bolt puppetfile install Install modules from a Puppetfile into a Boltdir
130
- bolt puppetfile show-modules List modules available to Bolt
131
- bolt secret createkeys Create new encryption keys
132
- bolt secret encrypt <plaintext> Encrypt a value
133
- bolt secret decrypt <encrypted> Decrypt a value
134
- bolt inventory show Show the list of targets an action would run on
135
- bolt group show Show the list of groups in the inventory
136
- bolt project init Create a new Bolt project
137
- bolt project migrate Migrate a Bolt project to the latest version
138
-
139
- Run `bolt <subcommand> --help` to view specific examples.
140
-
141
- Available options are:
146
+ NAME
147
+ bolt
148
+
149
+ USAGE
150
+ bolt <subcommand> [action] [options]
151
+
152
+ DESCRIPTION
153
+ Bolt is an orchestration tool that automates the manual work it takes to
154
+ maintain your infrastructure.
155
+
156
+ SUBCOMMANDS
157
+ apply Apply Puppet manifest code
158
+ command Run a command remotely
159
+ file Upload a local file or directory
160
+ group Show the list of groups in the inventory
161
+ inventory Show the list of targets an action would run on
162
+ plan Convert, show, and run Bolt plans
163
+ project Create and migrate Bolt projects
164
+ puppetfile Install and list modules and generate type references
165
+ script Upload a local script and run it remotely
166
+ secret Create encryption keys and encrypt and decrypt values
167
+ task Show and run Bolt tasks
142
168
  HELP
143
169
 
144
- TASK_HELP = <<~HELP
145
- Usage: bolt task <action> <task> [parameters]
170
+ APPLY_HELP = <<~HELP
171
+ NAME
172
+ apply
146
173
 
147
- Available actions are:
148
- show Show list of available tasks
149
- show <task> Show documentation for task
150
- run <task> Run a Puppet task
174
+ USAGE
175
+ bolt apply <manifest.pp> [options]
151
176
 
152
- Parameters are of the form <parameter>=<value>.
177
+ DESCRIPTION
178
+ Apply Puppet manifest code on the specified targets.
153
179
 
154
- #{examples('task run facts', 'run facter on')}
155
- Available options are:
180
+ EXAMPLES
181
+ bolt apply manifest.pp --targets target1,target2
156
182
  HELP
157
183
 
158
- TASK_SHOW_HELP = <<~HELP
159
- Usage: bolt task show <task>
184
+ COMMAND_HELP = <<~HELP
185
+ NAME
186
+ command
160
187
 
161
- Available actions are:
162
- show Show list of available tasks
163
- show <task> Show documentation for task
188
+ USAGE
189
+ bolt command <action> [options]
164
190
 
165
- Available options are:
191
+ DESCRIPTION
192
+ Run a command on the specified targets.
193
+
194
+ ACTIONS
195
+ run Run a command on the specified targets.
166
196
  HELP
167
197
 
168
- TASK_RUN_HELP = <<~HELP
169
- Usage: bolt task run <task> [parameters]
198
+ COMMAND_RUN_HELP = <<~HELP
199
+ NAME
200
+ run
170
201
 
171
- Parameters are of the form <parameter>=<value>.
202
+ USAGE
203
+ bolt command run <command> [options]
172
204
 
173
- #{examples('task run facts', 'run facter on')}
174
- Available options are:
205
+ DESCRIPTION
206
+ Run a command on the specified targets.
207
+
208
+ EXAMPLES
209
+ bolt command run 'uptime' -t target1,target2
175
210
  HELP
176
211
 
177
- COMMAND_HELP = <<~HELP
178
- Usage: bolt command <action> <command>
212
+ FILE_HELP = <<~HELP
213
+ NAME
214
+ file
215
+
216
+ USAGE
217
+ bolt file <action> [options]
179
218
 
180
- Available actions are:
181
- run Run a command remotely
219
+ DESCRIPTION
220
+ Upload a local file or directory
182
221
 
183
- #{examples('command run hostname', 'run hostname on')}
184
- Available options are:
222
+ ACTIONS
223
+ upload Upload a local file or directory
185
224
  HELP
186
225
 
187
- SCRIPT_HELP = <<~HELP
188
- Usage: bolt script <action> <script> [[arg1] ... [argN]]
226
+ FILE_UPLOAD_HELP = <<~HELP
227
+ NAME
228
+ upload
229
+
230
+ USAGE
231
+ bolt file upload <src> <dest> [options]
232
+
233
+ DESCRIPTION
234
+ Upload a local file or directory.
235
+
236
+ EXAMPLES
237
+ bolt file upload /tmp/source /etc/profile.d/login.sh -t target1
238
+ HELP
239
+
240
+ GROUP_HELP = <<~HELP
241
+ NAME
242
+ group
189
243
 
190
- Available actions are:
191
- run Upload a local script and run it remotely
244
+ USAGE
245
+ bolt group <action> [options]
192
246
 
193
- #{examples('script run my_script.ps1 some args', 'run a script on')}
194
- Available options are:
247
+ DESCRIPTION
248
+ Show the list of groups in the inventory.
249
+
250
+ ACTIONS
251
+ show Show the list of groups in the inventory
252
+ HELP
253
+
254
+ GROUP_SHOW_HELP = <<~HELP
255
+ NAME
256
+ show
257
+
258
+ USAGE
259
+ bolt group show [options]
260
+
261
+ DESCRIPTION
262
+ Show the list of groups in the inventory.
263
+ HELP
264
+
265
+ INVENTORY_HELP = <<~HELP
266
+ NAME
267
+ inventory
268
+
269
+ USAGE
270
+ bolt inventory <action> [options]
271
+
272
+ DESCRIPTION
273
+ Show the list of targets an action would run on.
274
+
275
+ ACTIONS
276
+ show Show the list of targets an action would run on
277
+ HELP
278
+
279
+ INVENTORY_SHOW_HELP = <<~HELP
280
+ NAME
281
+ show
282
+
283
+ USAGE
284
+ bolt inventory show [options]
285
+
286
+ DESCRIPTION
287
+ Show the list of targets an action would run on.
195
288
  HELP
196
289
 
197
290
  PLAN_HELP = <<~HELP
198
- Usage: bolt plan <action> <plan> [parameters]
291
+ NAME
292
+ plan
199
293
 
200
- Available actions are:
201
- convert <plan_path> Convert a YAML plan to a Puppet plan
202
- show Show list of available plans
203
- show <plan> Show details for plan
204
- run Run a Puppet task plan
294
+ USAGE
295
+ bolt plan <action> [parameters] [options]
205
296
 
206
- Parameters are of the form <parameter>=<value>.
297
+ DESCRIPTION
298
+ Convert, show, and run Bolt plans.
207
299
 
208
- #{examples('plan run canary command=hostname', 'run the canary plan on')}
209
- Available options are:
300
+ ACTIONS
301
+ convert Convert a YAML plan to a Bolt plan
302
+ run Run a plan on the specified targets
303
+ show Show available plans and plan documentation
210
304
  HELP
211
305
 
212
306
  PLAN_CONVERT_HELP = <<~HELP
213
- Usage: bolt plan convert <plan_path>
307
+ NAME
308
+ convert
309
+
310
+ USAGE
311
+ bolt plan convert <path> [options]
214
312
 
215
- Available options are:
313
+ DESCRIPTION
314
+ Convert a YAML plan to a Bolt plan.
315
+
316
+ Converting a YAML plan may result in a plan that is syntactically
317
+ correct but has different behavior. Always verify a converted plan's
318
+ functionality.
319
+
320
+ EXAMPLES
321
+ bolt plan convert path/to/plan/myplan.yaml
322
+ HELP
323
+
324
+ PLAN_RUN_HELP = <<~HELP
325
+ NAME
326
+ run
327
+
328
+ USAGE
329
+ bolt plan run <plan> [parameters] [options]
330
+
331
+ DESCRIPTION
332
+ Run a plan on the specified targets.
333
+
334
+ EXAMPLES
335
+ bolt plan run canary --targets target1,target2 command=hostname
216
336
  HELP
217
337
 
218
338
  PLAN_SHOW_HELP = <<~HELP
219
- Usage: bolt plan show <plan>
339
+ NAME
340
+ show
220
341
 
221
- Available actions are:
222
- show Show list of available plans
223
- show <plan> Show details for plan
342
+ USAGE
343
+ bolt plan show [plan] [options]
224
344
 
225
- Available options are:
345
+ DESCRIPTION
346
+ Show available plans and plan documentation.
347
+
348
+ Omitting the name of a plan will display a list of plans available
349
+ in the Bolt project.
350
+
351
+ Providing the name of a plan will display detailed documentation for
352
+ the plan, including a list of available parameters.
353
+
354
+ EXAMPLES
355
+ Display a list of available tasks
356
+ bolt plan show
357
+ Display documentation for the canary task
358
+ bolt plan show aggregate::count
226
359
  HELP
227
360
 
228
- PLAN_RUN_HELP = <<~HELP
229
- Usage: bolt plan run <plan> [parameters]
361
+ PROJECT_HELP = <<~HELP
362
+ NAME
363
+ project
230
364
 
231
- Parameters are of the form <parameter>=<value>.
365
+ USAGE
366
+ bolt project <action> [options]
232
367
 
233
- #{examples('plan run canary command=hostname', 'run the canary plan on')}
234
- Available options are:
368
+ DESCRIPTION
369
+ Create and migrate Bolt projects
370
+
371
+ ACTIONS
372
+ init Create a new Bolt project
373
+ migrate Migrate a Bolt project to the latest version
235
374
  HELP
236
375
 
237
- FILE_HELP = <<~HELP
238
- Usage: bolt file <action>
376
+ PROJECT_INIT_HELP = <<~HELP
377
+ NAME
378
+ init
379
+
380
+ USAGE
381
+ bolt project init [directory] [options]
382
+
383
+ DESCRIPTION
384
+ Create a new Bolt project.
239
385
 
240
- Available actions are:
241
- upload <src> <dest> Upload local file or directory <src> to <dest> on each node
386
+ Specify a directory to create a Bolt project in. Defaults to the
387
+ curent working directory.
242
388
 
243
- #{examples('file upload /tmp/source /etc/profile.d/login.sh', 'upload a file to')}
244
- Available options are:
389
+ EXAMPLES
390
+ Create a new Bolt project in the current working directory.
391
+ bolt project init
392
+ Create a new Bolt project at a specified path.
393
+ bolt project init ~/path/to/project
394
+ HELP
395
+
396
+ PROJECT_MIGRATE_HELP = <<~HELP
397
+ NAME
398
+ migrate
399
+
400
+ USAGE
401
+ bolt project migrate [options]
402
+
403
+ DESCRIPTION
404
+ Migrate a Bolt project to the latest version.
405
+
406
+ Loads a Bolt project's inventory file and migrates it to the latest version. The
407
+ inventory file is modified in place and will not preserve comments or formatting.
245
408
  HELP
246
409
 
247
410
  PUPPETFILE_HELP = <<~HELP
248
- Usage: bolt puppetfile <action>
411
+ NAME
412
+ puppetfile
413
+
414
+ USAGE
415
+ bolt puppetfile <action> [options]
416
+
417
+ DESCRIPTION
418
+ Install and list modules and generate type references
419
+
420
+ ACTIONS
421
+ generate-types Generate type references to register in plans
422
+ install Install modules from a Puppetfile into a Boltdir
423
+ show-modules List modules available to the Bolt project
424
+ HELP
249
425
 
250
- Available actions are:
251
- install Install modules from a Puppetfile into a Boltdir
252
- show-modules List modules available to Bolt
253
- generate-types Generate type references to register in Plans
426
+ PUPPETFILE_GENERATETYPES_HELP = <<~HELP
427
+ NAME
428
+ generate-types
254
429
 
255
- Install modules into the local Boltdir
256
- bolt puppetfile install
430
+ USAGE
431
+ bolt puppetfile generate-types [options]
257
432
 
258
- Available options are:
433
+ DESCRIPTION
434
+ Generate type references to register in plans.
259
435
  HELP
260
436
 
261
437
  PUPPETFILE_INSTALL_HELP = <<~HELP
262
- Usage: bolt puppetfile install
438
+ NAME
439
+ install
263
440
 
264
- Install modules into the local Boltdir
265
- bolt puppetfile install
441
+ USAGE
442
+ bolt puppetfile install [options]
266
443
 
267
- Available options are:
444
+ DESCRIPTION
445
+ Install modules from a Puppetfile into a Boltdir
268
446
  HELP
269
447
 
270
448
  PUPPETFILE_SHOWMODULES_HELP = <<~HELP
271
- Usage: bolt puppetfile show-modules
449
+ NAME
450
+ show-modules
272
451
 
273
- List modules available to Bolt
274
- bolt puppetfile show-modules
452
+ USAGE
453
+ bolt puppetfile show-modules [options]
275
454
 
276
- Available options are:
455
+ DESCRIPTION
456
+ List modules available to the Bolt project.
277
457
  HELP
278
458
 
279
- PUPPETFILE_GENERATETYPES_HELP = <<~HELP
280
- Usage: bolt puppetfile generate-types
459
+ SCRIPT_HELP = <<~HELP
460
+ NAME
461
+ script
281
462
 
282
- Generate type references to register in Plans
283
- bolt puppetfile generate-types
463
+ USAGE
464
+ bolt script <action> [options]
284
465
 
285
- Available options are:
466
+ DESCRIPTION
467
+ Run a script on the specified targets.
468
+
469
+ ACTIONS
470
+ run Run a script on the specified targets.
286
471
  HELP
287
472
 
288
- APPLY_HELP = <<~HELP
289
- Usage: bolt apply <manifest.pp>
473
+ SCRIPT_RUN_HELP = <<~HELP
474
+ NAME
475
+ run
476
+
477
+ USAGE
478
+ bolt script run <script> [arguments] [options]
479
+
480
+ DESCRIPTION
481
+ Run a script on the specified targets.
482
+
483
+ Arguments passed to a script are passed literally and are not interpolated
484
+ by the shell. Any arguments containing spaces or special characters should
485
+ be quoted.
486
+
487
+ EXAMPLES
488
+ bolt script run myscript.sh 'echo hello' --targets target1,target2
489
+ HELP
490
+
491
+ SECRET_HELP = <<~HELP
492
+ NAME
493
+ secret
290
494
 
291
- #{examples('apply site.pp', 'apply a manifest on')}
292
- bolt apply site.pp --nodes foo.example.com,bar.example.com
495
+ USAGE
496
+ bolt secret <action> [options]
293
497
 
294
- Available options are:
498
+ DESCRIPTION
499
+ Create encryption keys and encrypt and decrypt values.
500
+
501
+ ACTIONS
502
+ createkeys Create new encryption keys
503
+ encrypt Encrypt a value
504
+ decrypt Decrypt a value
505
+ HELP
506
+
507
+ SECRET_CREATEKEYS_HELP = <<~HELP
508
+ NAME
509
+ createkeys
510
+
511
+ USAGE
512
+ bolt secret createkeys [options]
513
+
514
+ DESCRIPTION
515
+ Create new encryption keys.
516
+ HELP
517
+
518
+ SECRET_DECRYPT_HELP = <<~HELP
519
+ NAME
520
+ decrypt
521
+
522
+ USAGE
523
+ bolt secret decrypt <ciphertext> [options]
524
+
525
+ DESCRIPTION
526
+ Decrypt a value.
295
527
  HELP
296
528
 
297
- SECRET_HELP = <<~SECRET_HELP
298
- Usage: bolt secret <action> <value>
299
- Manage secrets for inventory and hiera data.
529
+ SECRET_ENCRYPT_HELP = <<~HELP
530
+ NAME
531
+ encrypt
300
532
 
301
- Available actions are:
302
- createkeys Create new encryption keys
303
- encrypt Encrypt a value
304
- decrypt Decrypt a value
533
+ USAGE
534
+ bolt secret encrypt <plaintext> [options]
305
535
 
306
- Available options are:
307
- SECRET_HELP
536
+ DESCRIPTION
537
+ Encrypt a value.
538
+ HELP
308
539
 
309
- INVENTORY_HELP = <<~INVENTORY_HELP
310
- Usage: bolt inventory <action>
540
+ TASK_HELP = <<~HELP
541
+ NAME
542
+ task
311
543
 
312
- Available actions are:
313
- show Show the list of targets an action would run on
544
+ USAGE
545
+ bolt task <action> [options]
314
546
 
315
- Available options are:
316
- INVENTORY_HELP
547
+ DESCRIPTION
548
+ Show and run Bolt tasks.
317
549
 
318
- GROUP_HELP = <<~GROUP_HELP
319
- Usage: bolt group <action>
550
+ ACTIONS
551
+ run Run a Bolt task
552
+ show Show available tasks and task documentation
553
+ HELP
320
554
 
321
- Available actions are:
322
- show Show the list of groups in the inventory
555
+ TASK_RUN_HELP = <<~HELP
556
+ NAME
557
+ run
323
558
 
324
- Available options are:
325
- GROUP_HELP
559
+ USAGE
560
+ bolt task run <task> [parameters] [options]
326
561
 
327
- PROJECT_HELP = <<~PROJECT_HELP
328
- Usage: bolt project <action>
562
+ DESCRIPTION
563
+ Run a task on the specified targets.
329
564
 
330
- Available actions are:
331
- init Create a new Bolt project
332
- migrate Migrate a Bolt project to the latest version
565
+ Parameters take the form <parameter>=<value>.
333
566
 
334
- Available options are:
335
- PROJECT_HELP
567
+ EXAMPLES
568
+ bolt task run package --targets target1,target2 action=status name=bash
569
+ HELP
336
570
 
337
- PROJECT_INIT_HELP = <<~PROJECT_INIT_HELP
338
- Usage: bolt project init [directory]
571
+ TASK_SHOW_HELP = <<~HELP
572
+ NAME
573
+ show
339
574
 
340
- Create a new Bolt project.
341
- Specify a directory to create the Bolt project in. Defaults to the current working directory.
575
+ USAGE
576
+ bolt task show [task] [options]
342
577
 
343
- Available options are:
344
- PROJECT_INIT_HELP
578
+ DESCRIPTION
579
+ Show available tasks and task documentation.
345
580
 
346
- PROJECT_MIGRATE_HELP = <<~PROJECT_MIGRATE_HELP
347
- Usage: bolt project migrate
581
+ Omitting the name of a task will display a list of tasks available
582
+ in the Bolt project.
348
583
 
349
- Migrate a Bolt project to the latest version.
350
- Loads a Bolt project's inventory file and migrates it to the latest version. The
351
- inventory file is modified in place and will not preserve comments or formatting.
584
+ Providing the name of a task will display detailed documentation for
585
+ the task, including a list of available parameters.
352
586
 
353
- Available options are:
354
- PROJECT_MIGRATE_HELP
587
+ EXAMPLES
588
+ Display a list of available tasks
589
+ bolt task show
590
+ Display documentation for the canary task
591
+ bolt task show canary
592
+ HELP
355
593
 
356
594
  attr_reader :warnings
357
595
  def initialize(options)
@@ -360,6 +598,7 @@ module Bolt
360
598
  @options = options
361
599
  @warnings = []
362
600
 
601
+ separator "\nINVENTORY OPTIONS"
363
602
  define('-n', '--nodes NODES',
364
603
  'Alias for --targets',
365
604
  'Deprecated in favor of --targets') do |nodes|
@@ -407,7 +646,7 @@ module Bolt
407
646
  @options[:detail] = detail
408
647
  end
409
648
 
410
- separator "\nAuthentication:"
649
+ separator "\nAUTHENTICATION OPTIONS"
411
650
  define('-u', '--user USER', 'User to authenticate as') do |user|
412
651
  @options[:user] = user
413
652
  end
@@ -442,7 +681,7 @@ module Bolt
442
681
  @options[:'ssl-verify'] = ssl_verify
443
682
  end
444
683
 
445
- separator "\nEscalation:"
684
+ separator "\nESCALATION OPTIONS"
446
685
  define('--run-as USER', 'User to run as using privilege escalation') do |user|
447
686
  @options[:'run-as'] = user
448
687
  end
@@ -465,7 +704,7 @@ module Bolt
465
704
  STDERR.puts
466
705
  end
467
706
 
468
- separator "\nRun context:"
707
+ separator "\nRUN CONTEXT OPTIONS"
469
708
  define('-c', '--concurrency CONCURRENCY', Integer,
470
709
  'Maximum number of simultaneous connections (default: 100)') do |concurrency|
471
710
  @options[:concurrency] = concurrency
@@ -502,7 +741,7 @@ module Bolt
502
741
  @options[:'save-rerun'] = save
503
742
  end
504
743
 
505
- separator "\nTransports:"
744
+ separator "\nTRANSPORT OPTIONS"
506
745
  define('--transport TRANSPORT', TRANSPORTS.keys.map(&:to_s),
507
746
  "Specify a default transport: #{TRANSPORTS.keys.join(', ')}") do |t|
508
747
  @options[:transport] = t
@@ -517,7 +756,7 @@ module Bolt
517
756
  @options[:tmpdir] = tmpdir
518
757
  end
519
758
 
520
- separator "\nDisplay:"
759
+ separator "\nDISPLAY OPTIONS"
521
760
  define('--format FORMAT', 'Output format to use: human or json') do |format|
522
761
  @options[:format] = format
523
762
  end
@@ -531,7 +770,7 @@ module Bolt
531
770
  @options[:trace] = true
532
771
  end
533
772
 
534
- separator "\nGlobal:"
773
+ separator "\nGLOBAL OPTIONS"
535
774
  define('-h', '--help', 'Display help') do |_|
536
775
  @options[:help] = true
537
776
  end
@@ -140,6 +140,23 @@ module Bolt
140
140
  end
141
141
  end
142
142
 
143
+ def remove_from_group(target, desired_group)
144
+ unless target.length == 1
145
+ raise ValidationError.new("'remove_from_group' expects a single Target, got #{target.length}", nil)
146
+ end
147
+
148
+ if desired_group == 'all'
149
+ raise ValidationError.new("Cannot remove Target from Group 'all'", nil)
150
+ end
151
+
152
+ if group_names.include?(desired_group)
153
+ invalidate_group_cache!(target.first)
154
+ remove_node(@groups, target.first, desired_group)
155
+ else
156
+ raise ValidationError.new("Group #{desired_group} does not exist in inventory", nil)
157
+ end
158
+ end
159
+
143
160
  def set_var(target, var_hash)
144
161
  set_vars_from_hash(target.name, var_hash)
145
162
  end
@@ -329,30 +346,30 @@ module Bolt
329
346
  end
330
347
  private :set_plugin_hooks
331
348
 
349
+ def remove_node(current_group, target, desired_group, track = { 'all' => nil })
350
+ # Remove the target from the group
351
+ if current_group.name == desired_group
352
+ current_group.nodes.delete(target.name)
353
+ # If the target remains in the group, add the group data to the cache
354
+ elsif current_group.node_names.include?(target.name)
355
+ add_group_data_to_cache(current_group, target, track)
356
+ end
357
+ current_group.groups.each do |child_group|
358
+ # If target was in current group, remove it from all child groups
359
+ desired_group = child_group.name if current_group.name == desired_group
360
+ track[child_group.name] = current_group
361
+ remove_node(child_group, target, desired_group)
362
+ end
363
+ end
364
+ private :remove_node
365
+
332
366
  def add_node(current_group, target, desired_group, track = { 'all' => nil })
333
367
  if current_group.name == desired_group
334
368
  # Group to add to is found
335
369
  t_name = target.name
336
370
  # Add target to nodes hash
337
371
  current_group.nodes[t_name] = { 'name' => t_name }.merge(target.options)
338
- # Inherit facts, vars, and features from hierarchy
339
- current_group_data = { facts: current_group.facts,
340
- vars: current_group.vars,
341
- features: current_group.features,
342
- plugin_hooks: current_group.plugin_hooks }
343
- data = inherit_data(track, current_group.name, current_group_data)
344
- set_facts(t_name, @target_facts[t_name] ? data[:facts].merge(@target_facts[t_name]) : data[:facts])
345
- set_vars_from_hash(t_name, @target_vars[t_name] ? data[:vars].merge(@target_vars[t_name]) : data[:vars])
346
- data[:features].each do |feature|
347
- set_feature(target, feature)
348
- end
349
- hook_data = @config.plugin_hooks.merge(data[:plugin_hooks])
350
- hash = if @target_plugin_hooks[t_name]
351
- hook_data.merge(@target_plugin_hooks[t_name])
352
- else
353
- hook_data
354
- end
355
- set_plugin_hooks(t_name, hash)
372
+ add_group_data_to_cache(current_group, target, track)
356
373
  return true
357
374
  end
358
375
  # Recurse on children Groups if not desired_group
@@ -363,6 +380,28 @@ module Bolt
363
380
  end
364
381
  private :add_node
365
382
 
383
+ def add_group_data_to_cache(current_group, target, track)
384
+ t_name = target.name
385
+ current_group_data = { facts: current_group.facts,
386
+ vars: current_group.vars,
387
+ features: current_group.features,
388
+ plugin_hooks: current_group.plugin_hooks }
389
+ data = inherit_data(track, current_group.name, current_group_data)
390
+ set_facts(t_name, @target_facts[t_name] ? data[:facts].merge(@target_facts[t_name]) : data[:facts])
391
+ set_vars_from_hash(t_name, @target_vars[t_name] ? data[:vars].merge(@target_vars[t_name]) : data[:vars])
392
+ data[:features].each do |feature|
393
+ set_feature(target, feature)
394
+ end
395
+ hook_data = @config.plugin_hooks.merge(data[:plugin_hooks])
396
+ hash = if @target_plugin_hooks[t_name]
397
+ hook_data.merge(@target_plugin_hooks[t_name])
398
+ else
399
+ hook_data
400
+ end
401
+ set_plugin_hooks(t_name, hash)
402
+ end
403
+ private :add_group_data_to_cache
404
+
366
405
  def inherit_data(track, name, data)
367
406
  unless track[name].nil?
368
407
  data[:facts] = track[name].facts.merge(data[:facts])
@@ -374,5 +413,13 @@ module Bolt
374
413
  data
375
414
  end
376
415
  private :inherit_data
416
+
417
+ def invalidate_group_cache!(target)
418
+ @target_facts.delete(target.name)
419
+ @target_features.delete(target.name)
420
+ @target_vars.delete(target.name)
421
+ @target_plugin_hooks.delete(target.name)
422
+ end
423
+ private :invalidate_group_cache!
377
424
  end
378
425
  end
@@ -142,6 +142,11 @@ module Bolt
142
142
  @unresolved_targets[t_name] = target
143
143
  end
144
144
 
145
+ def remove_target(target)
146
+ @resolved_targets.delete(target.name)
147
+ @unresolved_targets.delete(target.name)
148
+ end
149
+
145
150
  def add_target(target)
146
151
  @resolved_targets[target.name] = { 'name' => target.name }
147
152
  end
@@ -136,6 +136,22 @@ module Bolt
136
136
  end
137
137
  private :expand_targets
138
138
 
139
+ def remove_target(current_group, target, desired_group)
140
+ if current_group.name == desired_group
141
+ current_group.remove_target(target)
142
+ target.invalidate_group_cache!
143
+ end
144
+ current_group.groups.each do |child_group|
145
+ # If target was in current group, remove it from all child groups
146
+ if current_group.name == desired_group
147
+ remove_target(child_group, target, child_group.name)
148
+ else
149
+ remove_target(child_group, target, desired_group)
150
+ end
151
+ end
152
+ end
153
+ private :remove_target
154
+
139
155
  def add_target(current_group, target, desired_group)
140
156
  if current_group.name == desired_group
141
157
  current_group.add_target(target)
@@ -201,6 +217,22 @@ module Bolt
201
217
  end
202
218
  end
203
219
 
220
+ def remove_from_group(target, desired_group)
221
+ unless target.length == 1
222
+ raise ValidationError.new("'remove_from_group' expects a single Target, got #{target.length}", nil)
223
+ end
224
+
225
+ if desired_group == 'all'
226
+ raise ValidationError.new("Cannot remove Target from Group 'all'", nil)
227
+ end
228
+
229
+ if group_names.include?(desired_group)
230
+ remove_target(@groups, @targets[target.first.name], desired_group)
231
+ else
232
+ raise ValidationError.new("Group #{desired_group} does not exist in inventory", nil)
233
+ end
234
+ end
235
+
204
236
  def add_to_group(targets, desired_group)
205
237
  if group_names.include?(desired_group)
206
238
  targets.each do |target|
@@ -312,8 +312,10 @@ module Bolt
312
312
 
313
313
  # If it's a Puppet language plan, use strings to extract data. The only
314
314
  # way to tell is to check which filename exists in the module.
315
- plan_file = plan_name.split('::', 2)[1] || 'init'
316
- pp_path = File.join(mod, 'plans', "#{plan_file}.pp")
315
+ plan_subpath = File.join(plan_name.split('::').drop(1))
316
+ plan_subpath = 'init' if plan_subpath.empty?
317
+
318
+ pp_path = File.join(mod, 'plans', "#{plan_subpath}.pp")
317
319
  if File.exist?(pp_path)
318
320
  require 'puppet-strings'
319
321
  require 'puppet-strings/yard'
@@ -346,7 +348,7 @@ module Bolt
346
348
 
347
349
  # If it's a YAML plan, fall back to limited data
348
350
  else
349
- yaml_path = File.join(mod, 'plans', "#{plan_file}.yaml")
351
+ yaml_path = File.join(mod, 'plans', "#{plan_subpath}.yaml")
350
352
  plan_content = File.read(yaml_path)
351
353
  plan = Bolt::PAL::YamlPlan::Loader.from_string(plan_name, plan_content, yaml_path)
352
354
 
@@ -9,19 +9,22 @@ module Bolt
9
9
  if !ENV['HOME'].nil?
10
10
  DEFAULT_TOKEN = File.expand_path('~/.puppetlabs/token')
11
11
  DEFAULT_CONFIG = { user: File.expand_path('~/.puppetlabs/client-tools/puppetdb.conf'),
12
- global: '/etc/puppetlabs/client-tools/puppetdb.conf',
13
- win_global: 'C:/ProgramData/PuppetLabs/client-tools/puppetdb.conf' }.freeze
12
+ global: '/etc/puppetlabs/client-tools/puppetdb.conf' }.freeze
14
13
  else
15
14
  DEFAULT_TOKEN = Bolt::Util.windows? ? 'nul' : '/dev/null'
16
15
  DEFAULT_CONFIG = { user: '/etc/puppetlabs/puppet/puppetdb.conf',
17
- global: '/etc/puppetlabs/puppet/puppetdb.conf',
18
- win_global: 'C:/ProgramData/PuppetLabs/client-tools/puppetdb.conf' }.freeze
16
+ global: '/etc/puppetlabs/puppet/puppetdb.conf' }.freeze
19
17
 
20
18
  end
21
19
 
20
+ def self.default_windows_config
21
+ require 'win32/dir'
22
+ File.expand_path(File.join(Dir::COMMON_APPDATA, 'PuppetLabs/client-tools/puppetdb.conf'))
23
+ end
24
+
22
25
  def self.load_config(filename, options, boltdir_path = nil)
23
26
  config = {}
24
- global_path = Bolt::Util.windows? ? DEFAULT_CONFIG[:win_global] : DEFAULT_CONFIG[:global]
27
+ global_path = Bolt::Util.windows? ? default_windows_config : DEFAULT_CONFIG[:global]
25
28
  if filename
26
29
  if File.exist?(filename)
27
30
  config = JSON.parse(File.read(filename))
@@ -8,9 +8,8 @@ module Bolt
8
8
  attr_reader :target, :value, :action, :object
9
9
 
10
10
  def self.from_exception(target, exception)
11
- @exception = exception
12
- if @exception.is_a?(Bolt::Error)
13
- error = @exception.to_h
11
+ if exception.is_a?(Bolt::Error)
12
+ error = exception.to_h
14
13
  else
15
14
  error = {
16
15
  'kind' => 'puppetlabs.tasks/exception-error',
@@ -34,6 +34,11 @@ module Bolt
34
34
  @transport_logger = transport_logger
35
35
  @logger.debug("Initializing ssh connection to #{@target.safe_name}")
36
36
 
37
+ @sudo_password = @target.options['sudo-password']
38
+ # rubocop:disable Style/GlobalVars
39
+ @sudo_password ||= @target.options['password'] if $future
40
+ # rubocop:enable Style/GlobalVars
41
+
37
42
  if target.options['private-key']&.instance_of?(String)
38
43
  begin
39
44
  Bolt::Util.validate_file('ssh key', target.options['private-key'])
@@ -148,8 +153,8 @@ module Bolt
148
153
 
149
154
  def handled_sudo(channel, data, stdin)
150
155
  if data.lines.include?(Sudoable.sudo_prompt)
151
- if target.options['sudo-password']
152
- channel.send_data("#{target.options['sudo-password']}\n")
156
+ if @sudo_password
157
+ channel.send_data("#{@sudo_password}\n")
153
158
  channel.wait
154
159
  return true
155
160
  else
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Bolt
4
- VERSION = '1.41.0'
4
+ VERSION = '1.42.0'
5
5
  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: 1.41.0
4
+ version: 1.42.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Puppet
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2019-12-03 00:00:00.000000000 Z
11
+ date: 2019-12-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: addressable
@@ -349,6 +349,7 @@ files:
349
349
  - bolt-modules/boltlib/lib/puppet/functions/get_targets.rb
350
350
  - bolt-modules/boltlib/lib/puppet/functions/puppetdb_fact.rb
351
351
  - bolt-modules/boltlib/lib/puppet/functions/puppetdb_query.rb
352
+ - bolt-modules/boltlib/lib/puppet/functions/remove_from_group.rb
352
353
  - bolt-modules/boltlib/lib/puppet/functions/resolve_references.rb
353
354
  - bolt-modules/boltlib/lib/puppet/functions/run_command.rb
354
355
  - bolt-modules/boltlib/lib/puppet/functions/run_plan.rb