openbolt 5.0.0.rc1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (258) hide show
  1. checksums.yaml +7 -0
  2. data/Puppetfile +52 -0
  3. data/bolt-modules/boltlib/lib/puppet/datatypes/applyresult.rb +60 -0
  4. data/bolt-modules/boltlib/lib/puppet/datatypes/containerresult.rb +51 -0
  5. data/bolt-modules/boltlib/lib/puppet/datatypes/future.rb +25 -0
  6. data/bolt-modules/boltlib/lib/puppet/datatypes/resourceinstance.rb +71 -0
  7. data/bolt-modules/boltlib/lib/puppet/datatypes/result.rb +55 -0
  8. data/bolt-modules/boltlib/lib/puppet/datatypes/resultset.rb +65 -0
  9. data/bolt-modules/boltlib/lib/puppet/datatypes/target.rb +93 -0
  10. data/bolt-modules/boltlib/lib/puppet/functions/add_facts.rb +33 -0
  11. data/bolt-modules/boltlib/lib/puppet/functions/add_to_group.rb +38 -0
  12. data/bolt-modules/boltlib/lib/puppet/functions/apply_prep.rb +208 -0
  13. data/bolt-modules/boltlib/lib/puppet/functions/background.rb +62 -0
  14. data/bolt-modules/boltlib/lib/puppet/functions/catch_errors.rb +57 -0
  15. data/bolt-modules/boltlib/lib/puppet/functions/download_file.rb +130 -0
  16. data/bolt-modules/boltlib/lib/puppet/functions/facts.rb +31 -0
  17. data/bolt-modules/boltlib/lib/puppet/functions/fail_plan.rb +52 -0
  18. data/bolt-modules/boltlib/lib/puppet/functions/get_resources.rb +87 -0
  19. data/bolt-modules/boltlib/lib/puppet/functions/get_target.rb +34 -0
  20. data/bolt-modules/boltlib/lib/puppet/functions/get_targets.rb +35 -0
  21. data/bolt-modules/boltlib/lib/puppet/functions/parallelize.rb +74 -0
  22. data/bolt-modules/boltlib/lib/puppet/functions/puppetdb_command.rb +97 -0
  23. data/bolt-modules/boltlib/lib/puppet/functions/puppetdb_fact.rb +47 -0
  24. data/bolt-modules/boltlib/lib/puppet/functions/puppetdb_query.rb +52 -0
  25. data/bolt-modules/boltlib/lib/puppet/functions/remove_from_group.rb +40 -0
  26. data/bolt-modules/boltlib/lib/puppet/functions/resolve_references.rb +42 -0
  27. data/bolt-modules/boltlib/lib/puppet/functions/resource.rb +53 -0
  28. data/bolt-modules/boltlib/lib/puppet/functions/run_command.rb +106 -0
  29. data/bolt-modules/boltlib/lib/puppet/functions/run_container.rb +162 -0
  30. data/bolt-modules/boltlib/lib/puppet/functions/run_plan.rb +291 -0
  31. data/bolt-modules/boltlib/lib/puppet/functions/run_script.rb +145 -0
  32. data/bolt-modules/boltlib/lib/puppet/functions/run_task.rb +164 -0
  33. data/bolt-modules/boltlib/lib/puppet/functions/run_task_with.rb +211 -0
  34. data/bolt-modules/boltlib/lib/puppet/functions/set_config.rb +48 -0
  35. data/bolt-modules/boltlib/lib/puppet/functions/set_feature.rb +43 -0
  36. data/bolt-modules/boltlib/lib/puppet/functions/set_resources.rb +145 -0
  37. data/bolt-modules/boltlib/lib/puppet/functions/set_var.rb +38 -0
  38. data/bolt-modules/boltlib/lib/puppet/functions/upload_file.rb +101 -0
  39. data/bolt-modules/boltlib/lib/puppet/functions/vars.rb +29 -0
  40. data/bolt-modules/boltlib/lib/puppet/functions/wait.rb +131 -0
  41. data/bolt-modules/boltlib/lib/puppet/functions/wait_until_available.rb +59 -0
  42. data/bolt-modules/boltlib/lib/puppet/functions/without_default_logging.rb +39 -0
  43. data/bolt-modules/boltlib/lib/puppet/functions/write_file.rb +50 -0
  44. data/bolt-modules/boltlib/types/planresult.pp +18 -0
  45. data/bolt-modules/boltlib/types/targetspec.pp +7 -0
  46. data/bolt-modules/ctrl/lib/puppet/functions/ctrl/do_until.rb +42 -0
  47. data/bolt-modules/ctrl/lib/puppet/functions/ctrl/sleep.rb +20 -0
  48. data/bolt-modules/dir/lib/puppet/functions/dir/children.rb +35 -0
  49. data/bolt-modules/file/lib/puppet/functions/file/delete.rb +21 -0
  50. data/bolt-modules/file/lib/puppet/functions/file/exists.rb +28 -0
  51. data/bolt-modules/file/lib/puppet/functions/file/join.rb +20 -0
  52. data/bolt-modules/file/lib/puppet/functions/file/read.rb +33 -0
  53. data/bolt-modules/file/lib/puppet/functions/file/readable.rb +28 -0
  54. data/bolt-modules/file/lib/puppet/functions/file/write.rb +24 -0
  55. data/bolt-modules/log/lib/puppet/functions/log/debug.rb +39 -0
  56. data/bolt-modules/log/lib/puppet/functions/log/error.rb +40 -0
  57. data/bolt-modules/log/lib/puppet/functions/log/fatal.rb +40 -0
  58. data/bolt-modules/log/lib/puppet/functions/log/info.rb +39 -0
  59. data/bolt-modules/log/lib/puppet/functions/log/trace.rb +39 -0
  60. data/bolt-modules/log/lib/puppet/functions/log/warn.rb +41 -0
  61. data/bolt-modules/out/lib/puppet/functions/out/message.rb +36 -0
  62. data/bolt-modules/out/lib/puppet/functions/out/verbose.rb +35 -0
  63. data/bolt-modules/prompt/lib/puppet/functions/prompt/menu.rb +103 -0
  64. data/bolt-modules/prompt/lib/puppet/functions/prompt.rb +65 -0
  65. data/bolt-modules/system/lib/puppet/functions/system/env.rb +20 -0
  66. data/exe/bolt +17 -0
  67. data/guides/debugging.yaml +27 -0
  68. data/guides/inventory.yaml +23 -0
  69. data/guides/links.yaml +12 -0
  70. data/guides/logging.yaml +17 -0
  71. data/guides/module.yaml +18 -0
  72. data/guides/modulepath.yaml +24 -0
  73. data/guides/project.yaml +21 -0
  74. data/guides/targets.yaml +28 -0
  75. data/guides/transports.yaml +22 -0
  76. data/lib/bolt/analytics.rb +233 -0
  77. data/lib/bolt/application.rb +806 -0
  78. data/lib/bolt/applicator.rb +368 -0
  79. data/lib/bolt/apply_inventory.rb +93 -0
  80. data/lib/bolt/apply_result.rb +154 -0
  81. data/lib/bolt/apply_target.rb +90 -0
  82. data/lib/bolt/bolt_option_parser.rb +1226 -0
  83. data/lib/bolt/catalog/logging.rb +15 -0
  84. data/lib/bolt/catalog.rb +144 -0
  85. data/lib/bolt/cli.rb +949 -0
  86. data/lib/bolt/config/modulepath.rb +30 -0
  87. data/lib/bolt/config/options.rb +673 -0
  88. data/lib/bolt/config/transport/base.rb +133 -0
  89. data/lib/bolt/config/transport/docker.rb +34 -0
  90. data/lib/bolt/config/transport/jail.rb +33 -0
  91. data/lib/bolt/config/transport/local.rb +39 -0
  92. data/lib/bolt/config/transport/lxd.rb +34 -0
  93. data/lib/bolt/config/transport/options.rb +431 -0
  94. data/lib/bolt/config/transport/orch.rb +41 -0
  95. data/lib/bolt/config/transport/podman.rb +33 -0
  96. data/lib/bolt/config/transport/remote.rb +24 -0
  97. data/lib/bolt/config/transport/ssh.rb +138 -0
  98. data/lib/bolt/config/transport/winrm.rb +63 -0
  99. data/lib/bolt/config.rb +515 -0
  100. data/lib/bolt/container_result.rb +105 -0
  101. data/lib/bolt/error.rb +194 -0
  102. data/lib/bolt/executor.rb +539 -0
  103. data/lib/bolt/fiber_executor.rb +190 -0
  104. data/lib/bolt/inventory/group.rb +446 -0
  105. data/lib/bolt/inventory/inventory.rb +391 -0
  106. data/lib/bolt/inventory/options.rb +139 -0
  107. data/lib/bolt/inventory/target.rb +293 -0
  108. data/lib/bolt/inventory.rb +120 -0
  109. data/lib/bolt/logger.rb +252 -0
  110. data/lib/bolt/module.rb +54 -0
  111. data/lib/bolt/module_installer/installer.rb +44 -0
  112. data/lib/bolt/module_installer/puppetfile/forge_module.rb +54 -0
  113. data/lib/bolt/module_installer/puppetfile/git_module.rb +37 -0
  114. data/lib/bolt/module_installer/puppetfile/module.rb +26 -0
  115. data/lib/bolt/module_installer/puppetfile.rb +131 -0
  116. data/lib/bolt/module_installer/resolver.rb +129 -0
  117. data/lib/bolt/module_installer/specs/forge_spec.rb +91 -0
  118. data/lib/bolt/module_installer/specs/git_spec.rb +150 -0
  119. data/lib/bolt/module_installer/specs/id/base.rb +116 -0
  120. data/lib/bolt/module_installer/specs/id/gitclone.rb +120 -0
  121. data/lib/bolt/module_installer/specs/id/github.rb +90 -0
  122. data/lib/bolt/module_installer/specs/id/gitlab.rb +92 -0
  123. data/lib/bolt/module_installer/specs.rb +95 -0
  124. data/lib/bolt/module_installer.rb +208 -0
  125. data/lib/bolt/node/errors.rb +55 -0
  126. data/lib/bolt/node/output.rb +29 -0
  127. data/lib/bolt/outputter/human.rb +958 -0
  128. data/lib/bolt/outputter/json.rb +205 -0
  129. data/lib/bolt/outputter/logger.rb +76 -0
  130. data/lib/bolt/outputter/rainbow.rb +118 -0
  131. data/lib/bolt/outputter.rb +57 -0
  132. data/lib/bolt/pal/issues.rb +19 -0
  133. data/lib/bolt/pal/logging.rb +17 -0
  134. data/lib/bolt/pal/yaml_plan/evaluator.rb +83 -0
  135. data/lib/bolt/pal/yaml_plan/loader.rb +94 -0
  136. data/lib/bolt/pal/yaml_plan/parameter.rb +63 -0
  137. data/lib/bolt/pal/yaml_plan/step/command.rb +45 -0
  138. data/lib/bolt/pal/yaml_plan/step/download.rb +37 -0
  139. data/lib/bolt/pal/yaml_plan/step/eval.rb +42 -0
  140. data/lib/bolt/pal/yaml_plan/step/message.rb +31 -0
  141. data/lib/bolt/pal/yaml_plan/step/plan.rb +42 -0
  142. data/lib/bolt/pal/yaml_plan/step/resources.rb +170 -0
  143. data/lib/bolt/pal/yaml_plan/step/script.rb +62 -0
  144. data/lib/bolt/pal/yaml_plan/step/task.rb +42 -0
  145. data/lib/bolt/pal/yaml_plan/step/upload.rb +37 -0
  146. data/lib/bolt/pal/yaml_plan/step/verbose.rb +31 -0
  147. data/lib/bolt/pal/yaml_plan/step.rb +223 -0
  148. data/lib/bolt/pal/yaml_plan/transpiler.rb +90 -0
  149. data/lib/bolt/pal/yaml_plan.rb +172 -0
  150. data/lib/bolt/pal.rb +847 -0
  151. data/lib/bolt/plan_creator.rb +219 -0
  152. data/lib/bolt/plan_future.rb +86 -0
  153. data/lib/bolt/plan_result.rb +44 -0
  154. data/lib/bolt/plugin/cache.rb +76 -0
  155. data/lib/bolt/plugin/env_var.rb +54 -0
  156. data/lib/bolt/plugin/module.rb +276 -0
  157. data/lib/bolt/plugin/prompt.rb +36 -0
  158. data/lib/bolt/plugin/puppet_connect_data.rb +84 -0
  159. data/lib/bolt/plugin/puppetdb.rb +124 -0
  160. data/lib/bolt/plugin/task.rb +72 -0
  161. data/lib/bolt/plugin.rb +380 -0
  162. data/lib/bolt/project.rb +219 -0
  163. data/lib/bolt/project_manager/config_migrator.rb +113 -0
  164. data/lib/bolt/project_manager/inventory_migrator.rb +67 -0
  165. data/lib/bolt/project_manager/migrator.rb +39 -0
  166. data/lib/bolt/project_manager/module_migrator.rb +203 -0
  167. data/lib/bolt/project_manager.rb +221 -0
  168. data/lib/bolt/puppetdb/client.rb +153 -0
  169. data/lib/bolt/puppetdb/config.rb +176 -0
  170. data/lib/bolt/puppetdb/instance.rb +146 -0
  171. data/lib/bolt/puppetdb.rb +15 -0
  172. data/lib/bolt/r10k_log_proxy.rb +30 -0
  173. data/lib/bolt/rerun.rb +55 -0
  174. data/lib/bolt/resource_instance.rb +133 -0
  175. data/lib/bolt/result.rb +247 -0
  176. data/lib/bolt/result_set.rb +128 -0
  177. data/lib/bolt/shell/bash/tmpdir.rb +62 -0
  178. data/lib/bolt/shell/bash.rb +516 -0
  179. data/lib/bolt/shell/powershell/snippets.rb +181 -0
  180. data/lib/bolt/shell/powershell.rb +365 -0
  181. data/lib/bolt/shell.rb +105 -0
  182. data/lib/bolt/target.rb +174 -0
  183. data/lib/bolt/task/puppet_server.rb +27 -0
  184. data/lib/bolt/task/run.rb +55 -0
  185. data/lib/bolt/task.rb +163 -0
  186. data/lib/bolt/transport/base.rb +252 -0
  187. data/lib/bolt/transport/docker/connection.rb +150 -0
  188. data/lib/bolt/transport/docker.rb +23 -0
  189. data/lib/bolt/transport/jail/connection.rb +81 -0
  190. data/lib/bolt/transport/jail.rb +21 -0
  191. data/lib/bolt/transport/local/connection.rb +106 -0
  192. data/lib/bolt/transport/local.rb +20 -0
  193. data/lib/bolt/transport/lxd/connection.rb +115 -0
  194. data/lib/bolt/transport/lxd.rb +26 -0
  195. data/lib/bolt/transport/orch/connection.rb +111 -0
  196. data/lib/bolt/transport/orch.rb +271 -0
  197. data/lib/bolt/transport/podman/connection.rb +102 -0
  198. data/lib/bolt/transport/podman.rb +19 -0
  199. data/lib/bolt/transport/remote.rb +41 -0
  200. data/lib/bolt/transport/simple.rb +54 -0
  201. data/lib/bolt/transport/ssh/connection.rb +321 -0
  202. data/lib/bolt/transport/ssh/exec_connection.rb +140 -0
  203. data/lib/bolt/transport/ssh.rb +48 -0
  204. data/lib/bolt/transport/winrm/connection.rb +378 -0
  205. data/lib/bolt/transport/winrm.rb +33 -0
  206. data/lib/bolt/util/format.rb +68 -0
  207. data/lib/bolt/util/puppet_log_level.rb +21 -0
  208. data/lib/bolt/util.rb +465 -0
  209. data/lib/bolt/validator.rb +227 -0
  210. data/lib/bolt/version.rb +5 -0
  211. data/lib/bolt.rb +8 -0
  212. data/lib/bolt_server/acl.rb +39 -0
  213. data/lib/bolt_server/base_config.rb +112 -0
  214. data/lib/bolt_server/config.rb +64 -0
  215. data/lib/bolt_server/file_cache.rb +200 -0
  216. data/lib/bolt_server/request_error.rb +11 -0
  217. data/lib/bolt_server/schemas/action-check_node_connections.json +14 -0
  218. data/lib/bolt_server/schemas/action-run_command.json +12 -0
  219. data/lib/bolt_server/schemas/action-run_script.json +47 -0
  220. data/lib/bolt_server/schemas/action-run_task.json +20 -0
  221. data/lib/bolt_server/schemas/action-upload_file.json +47 -0
  222. data/lib/bolt_server/schemas/partials/target-any.json +10 -0
  223. data/lib/bolt_server/schemas/partials/target-ssh.json +88 -0
  224. data/lib/bolt_server/schemas/partials/target-winrm.json +67 -0
  225. data/lib/bolt_server/schemas/partials/task.json +94 -0
  226. data/lib/bolt_server/schemas/transport-ssh.json +25 -0
  227. data/lib/bolt_server/schemas/transport-winrm.json +19 -0
  228. data/lib/bolt_server/transport_app.rb +554 -0
  229. data/lib/bolt_spec/bolt_context.rb +226 -0
  230. data/lib/bolt_spec/plans/action_stubs/command_stub.rb +51 -0
  231. data/lib/bolt_spec/plans/action_stubs/download_stub.rb +66 -0
  232. data/lib/bolt_spec/plans/action_stubs/plan_stub.rb +55 -0
  233. data/lib/bolt_spec/plans/action_stubs/script_stub.rb +59 -0
  234. data/lib/bolt_spec/plans/action_stubs/task_stub.rb +57 -0
  235. data/lib/bolt_spec/plans/action_stubs/upload_stub.rb +65 -0
  236. data/lib/bolt_spec/plans/action_stubs.rb +196 -0
  237. data/lib/bolt_spec/plans/mock_executor.rb +361 -0
  238. data/lib/bolt_spec/plans/publish_stub.rb +49 -0
  239. data/lib/bolt_spec/plans.rb +190 -0
  240. data/lib/bolt_spec/run.rb +246 -0
  241. data/lib/logging_extensions/logging.rb +13 -0
  242. data/libexec/apply_catalog.rb +130 -0
  243. data/libexec/bolt_catalog +68 -0
  244. data/libexec/custom_facts.rb +63 -0
  245. data/libexec/query_resources.rb +75 -0
  246. data/modules/aggregate/lib/puppet/functions/aggregate/count.rb +21 -0
  247. data/modules/aggregate/lib/puppet/functions/aggregate/nodes.rb +22 -0
  248. data/modules/aggregate/lib/puppet/functions/aggregate/targets.rb +21 -0
  249. data/modules/aggregate/plans/count.pp +56 -0
  250. data/modules/aggregate/plans/targets.pp +56 -0
  251. data/modules/canary/lib/puppet/functions/canary/merge.rb +13 -0
  252. data/modules/canary/lib/puppet/functions/canary/random_split.rb +22 -0
  253. data/modules/canary/lib/puppet/functions/canary/skip.rb +25 -0
  254. data/modules/canary/plans/init.pp +100 -0
  255. data/modules/puppet_connect/plans/test_input_data.pp +94 -0
  256. data/modules/puppetdb_fact/plans/init.pp +20 -0
  257. data/resources/bolt_bash_completion.sh +214 -0
  258. metadata +735 -0
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'bolt/error'
4
+
5
+ # Parses common ways of referring to targets and returns an array of Targets.
6
+ #
7
+ # > **Note:** Not available in apply block
8
+ Puppet::Functions.create_function(:get_targets) do
9
+ # @param names A pattern or array of patterns identifying a set of targets.
10
+ # @return A list of unique Targets resolved from any target URIs and groups.
11
+ # @example Resolve a group
12
+ # get_targets('group1')
13
+ # @example Resolve a target URI
14
+ # get_targets('winrm://host2:54321')
15
+ # @example Resolve array of groups and/or target URIs
16
+ # get_targets(['host1', 'group1', 'winrm://host2:54321'])
17
+ # @example Resolve string consisting of a comma-separated list of groups and/or target URIs
18
+ # get_targets('host1,group1,winrm://host2:54321')
19
+ # @example Run on localhost
20
+ # get_targets('localhost')
21
+ dispatch :get_targets do
22
+ param 'Boltlib::TargetSpec', :names
23
+ return_type 'Array[Target]'
24
+ end
25
+
26
+ def get_targets(names)
27
+ inventory = Puppet.lookup(:bolt_inventory)
28
+ # Bolt executor not expected when invoked from apply block
29
+ executor = Puppet.lookup(:bolt_executor) { nil }
30
+ # Send Analytics Report
31
+ executor&.report_function_call(self.class.name)
32
+
33
+ inventory.get_targets(names)
34
+ end
35
+ end
@@ -0,0 +1,74 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Map a code block onto an array, where each array element executes in parallel.
4
+ # This function is experimental.
5
+ #
6
+ # > **Note:** Not available in apply block.
7
+ Puppet::Functions.create_function(:parallelize, Puppet::Functions::InternalFunction) do
8
+ # Map a block onto an array, where each array element executes in parallel.
9
+ # This function is experimental.
10
+ # @param data The array to apply the block to.
11
+ # @param block The code block to execute for each array element.
12
+ # @return [Array] An array of PlanResult objects. Each input from the input
13
+ # array returns a corresponding PlanResult object.
14
+ # @example Execute two tasks on two targets.
15
+ # $targets = get_targets(["host1", "host2"])
16
+ # $result = parallelize ($targets) |$t| {
17
+ # run_task('a', $t)
18
+ # run_task('b', $t)
19
+ # }
20
+ dispatch :parallelize do
21
+ scope_param
22
+ param 'Array[Any]', :data
23
+ block_param 'Callable[Any]', :block
24
+ return_type 'Array[Boltlib::PlanResult]'
25
+ end
26
+
27
+ def parallelize(scope, data, &block)
28
+ unless Puppet[:tasks]
29
+ raise Puppet::ParseErrorWithIssue
30
+ .from_issue_and_stack(Bolt::PAL::Issues::PLAN_OPERATION_NOT_SUPPORTED_WHEN_COMPILING, action: 'parallelize')
31
+ end
32
+
33
+ executor = Puppet.lookup(:bolt_executor)
34
+ executor.report_function_call(self.class.name)
35
+
36
+ futures = data.map do |object|
37
+ # We're going to immediately wait for these futures, *and* don't want
38
+ # their results to be returned as part of `wait()`, so use a 'dummy'
39
+ # value as the plan_id. This could also be nil, though in general we want
40
+ # to require Futures to have a plan stack so that they don't get lost.
41
+ executor.create_future(scope: scope, plan_id: 'parallel') do |newscope|
42
+ # Catch 'return' calls inside the block
43
+ result = catch(:return) do
44
+ # Add the object to the block parameters
45
+ args = { block.parameters[0][1].to_s => object }
46
+ # Execute the block. Individual plan steps in the block will yield
47
+ # the Fiber if they haven't finished, so all this needs to do is run
48
+ # the block.
49
+ block.closure.call_by_name_with_scope(newscope, args, true)
50
+ end
51
+
52
+ # If we got a return from the block, get its value
53
+ # Otherwise the result is the last line from the block
54
+ result = result.value if result.is_a?(Puppet::Pops::Evaluator::Return)
55
+
56
+ # Validate the result is a PlanResult
57
+ unless Puppet::Pops::Types::TypeParser.singleton.parse('Boltlib::PlanResult').instance?(result)
58
+ raise Bolt::InvalidParallelResult.new(result.to_s, *Puppet::Pops::PuppetStack.top_of_stack)
59
+ end
60
+
61
+ result
62
+ rescue Puppet::PreformattedError => e
63
+ if e.cause.is_a?(Bolt::Error)
64
+ e.cause
65
+ else
66
+ raise e
67
+ end
68
+ end
69
+ end
70
+
71
+ # We may eventually want parallelize to accept a timeout
72
+ executor.wait(futures)
73
+ end
74
+ end
@@ -0,0 +1,97 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'bolt/error'
4
+
5
+ # Send a command with a payload to PuppetDB.
6
+ #
7
+ # The `pdb_command` function only supports version 5 of the `replace_facts`
8
+ # command. Other commands might also work, but are not tested or supported
9
+ # by Bolt.
10
+ #
11
+ # See the [commands endpoint](https://puppet.com/docs/puppetdb/latest/api/command/v1/commands.html)
12
+ # documentation for more information about available commands and payload
13
+ # format.
14
+ #
15
+ # _This function is experimental and subject to change._
16
+ #
17
+ # > **Note:** Not available in apply block
18
+ #
19
+ Puppet::Functions.create_function(:puppetdb_command) do
20
+ # Send a command with a payload to PuppetDB.
21
+ #
22
+ # @param command The command to invoke.
23
+ # @param version The version of the command to invoke.
24
+ # @param payload The payload to the command.
25
+ # @return The UUID identifying the response sent by PuppetDB.
26
+ # @example Replace facts for a target
27
+ # $payload = {
28
+ # 'certname' => 'localhost',
29
+ # 'environment' => 'dev',
30
+ # 'producer' => 'bolt',
31
+ # 'producer_timestamp' => '1970-01-01',
32
+ # 'values' => { 'orchestrator' => 'bolt' }
33
+ # }
34
+ #
35
+ # puppetdb_command('replace_facts', 5, $payload)
36
+ dispatch :puppetdb_command do
37
+ param 'String[1]', :command
38
+ param 'Integer', :version
39
+ param 'Hash[Data, Data]', :payload
40
+ return_type 'String'
41
+ end
42
+
43
+ # Send a command with a payload to a named PuppetDB instance.
44
+ #
45
+ # @param command The command to invoke.
46
+ # @param version The version of the command to invoke.
47
+ # @param payload The payload to the command.
48
+ # @param instance The PuppetDB instance to send the command to.
49
+ # @return The UUID identifying the response sent by PuppetDB.
50
+ # @example Replace facts for a target using a named PuppetDB instance
51
+ # $payload = {
52
+ # 'certname' => 'localhost',
53
+ # 'environment' => 'dev',
54
+ # 'producer' => 'bolt',
55
+ # 'producer_timestamp' => '1970-01-01',
56
+ # 'values' => { 'orchestrator' => 'bolt' }
57
+ # }
58
+ #
59
+ # puppetdb_command('replace_facts', 5, $payload, 'instance-1')
60
+ dispatch :puppetdb_command_with_instance do
61
+ param 'String[1]', :command
62
+ param 'Integer', :version
63
+ param 'Hash[Data, Data]', :payload
64
+ param 'String', :instance
65
+ return_type 'String'
66
+ end
67
+
68
+ def puppetdb_command(command, version, payload)
69
+ puppetdb_command_with_instance(command, version, payload, nil)
70
+ end
71
+
72
+ def puppetdb_command_with_instance(command, version, payload, instance)
73
+ # Disallow in apply blocks.
74
+ unless Puppet[:tasks]
75
+ raise Puppet::ParseErrorWithIssue.from_issue_and_stack(
76
+ Bolt::PAL::Issues::PLAN_OPERATION_NOT_SUPPORTED_WHEN_COMPILING,
77
+ action: 'puppetdb_command'
78
+ )
79
+ end
80
+
81
+ # Send analytics report.
82
+ Puppet.lookup(:bolt_executor).report_function_call(self.class.name)
83
+
84
+ puppetdb_client = Puppet.lookup(:bolt_pdb_client)
85
+
86
+ # Error if the PDB client does not implement :send_command
87
+ unless puppetdb_client.respond_to?(:send_command)
88
+ raise Bolt::Error.new(
89
+ "PuppetDB client #{puppetdb_client.class} does not implement :send_command, "\
90
+ "unable to invoke command.",
91
+ 'bolt/pdb-command'
92
+ )
93
+ end
94
+
95
+ puppetdb_client.send_command(command, version, payload, instance)
96
+ end
97
+ end
@@ -0,0 +1,47 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'bolt/error'
4
+
5
+ # Collects facts based on a list of certnames.
6
+ #
7
+ # If a node is not found in PuppetDB, it's included in the returned hash with an empty facts hash.
8
+ # Otherwise, the node is included in the hash with a value that is a hash of its facts.
9
+ Puppet::Functions.create_function(:puppetdb_fact) do
10
+ # Collect facts from PuppetDB.
11
+ #
12
+ # @param certnames Array of certnames.
13
+ # @return A hash of certname to facts hash for each matched Target.
14
+ # @example Get facts for nodes
15
+ # puppetdb_fact(['app.example.com', 'db.example.com'])
16
+ dispatch :puppetdb_fact do
17
+ param 'Array[String]', :certnames
18
+ return_type 'Hash[String, Data]'
19
+ end
20
+
21
+ # Collects facts from a named PuppetDB instance.
22
+ #
23
+ # @param certnames Array of certnames.
24
+ # @param instance The PuppetDB instance to query.
25
+ # @return A hash of certname to facts hash for each matched Target.
26
+ # @example Get facts for nodes from a named PuppetDB instance
27
+ # puppetdb_fact(['app.example.com', 'db.example.com'], 'instance-1')
28
+ dispatch :puppetdb_fact_with_instance do
29
+ param 'Array[String]', :certnames
30
+ param 'String', :instance
31
+ return_type 'Hash[String, Data]'
32
+ end
33
+
34
+ def puppetdb_fact(certnames)
35
+ puppetdb_fact_with_instance(certnames, nil)
36
+ end
37
+
38
+ def puppetdb_fact_with_instance(certnames, instance)
39
+ puppetdb_client = Puppet.lookup(:bolt_pdb_client)
40
+ # Bolt executor not expected when invoked from apply block
41
+ executor = Puppet.lookup(:bolt_executor) { nil }
42
+ # Send Analytics Report
43
+ executor&.report_function_call(self.class.name)
44
+
45
+ puppetdb_client.facts_for_node(certnames, instance)
46
+ end
47
+ end
@@ -0,0 +1,52 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'bolt/error'
4
+
5
+ # Makes a query to [puppetdb](https://puppet.com/docs/puppetdb/latest/index.html)
6
+ # using Bolt's PuppetDB client.
7
+ Puppet::Functions.create_function(:puppetdb_query) do
8
+ # rubocop:disable Layout/LineLength
9
+ # Make a query to PuppetDB.
10
+ #
11
+ # @param query A PQL query.
12
+ # Learn more about [Puppet's query language](https://puppet.com/docs/puppetdb/latest/api/query/tutorial-pql.html), PQL.
13
+ # @return Results of the PuppetDB query.
14
+ # @example Request certnames for all nodes
15
+ # puppetdb_query('nodes[certname] {}')
16
+ # rubocop:enable Layout/LineLength
17
+ dispatch :make_query do
18
+ param 'Variant[String, Array[Data]]', :query
19
+ return_type 'Array[Data]'
20
+ end
21
+
22
+ # rubocop:disable Layout/LineLength
23
+ # Make a query to a named PuppetDB instance.
24
+ #
25
+ # @param query A PQL query.
26
+ # Learn more about [Puppet's query language](https://puppet.com/docs/puppetdb/latest/api/query/tutorial-pql.html), PQL.
27
+ # @param instance The PuppetDB instance to query.
28
+ # @return Results of the PuppetDB query.
29
+ # @example Request certnames for all nodes using a named PuppetDB instance
30
+ # puppetdb_query('nodes[certname] {}', 'instance-1')
31
+ # rubocop:enable Layout/LineLength
32
+ dispatch :make_query_with_instance do
33
+ param 'Variant[String, Array[Data]]', :query
34
+ param 'String', :instance
35
+ return_type 'Array[Data]'
36
+ end
37
+ # The query type could be more specific ASTQuery = Array[Variant[String, ASTQuery]]
38
+
39
+ def make_query(query)
40
+ make_query_with_instance(query, nil)
41
+ end
42
+
43
+ def make_query_with_instance(query, instance)
44
+ puppetdb_client = Puppet.lookup(:bolt_pdb_client)
45
+ # Bolt executor not expected when invoked from apply block
46
+ executor = Puppet.lookup(:bolt_executor) { nil }
47
+ # Send Analytics Report
48
+ executor&.report_function_call(self.class.name)
49
+
50
+ puppetdb_client.make_query(query, nil, instance)
51
+ end
52
+ end
@@ -0,0 +1,40 @@
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
+ # @return [nil]
15
+ # @example Remove Target from group.
16
+ # remove_from_group('foo@example.com', 'group1')
17
+ # @example Remove failing Targets from the rest of a plan
18
+ # $result = run_command(uptime, my_group, '_catch_errors' => true)
19
+ # $result.error_set.targets.each |$t| { remove_from_group($t, my_group) }
20
+ # run_command(next_command, my_group) # does not target the failing nodes.
21
+ dispatch :remove_from_group do
22
+ param 'Boltlib::TargetSpec', :target
23
+ param 'String[1]', :group
24
+ end
25
+
26
+ def remove_from_group(target, group)
27
+ unless Puppet[:tasks]
28
+ raise Puppet::ParseErrorWithIssue
29
+ .from_issue_and_stack(Bolt::PAL::Issues::PLAN_OPERATION_NOT_SUPPORTED_WHEN_COMPILING,
30
+ action: 'remove_from_group')
31
+ end
32
+
33
+ inventory = Puppet.lookup(:bolt_inventory)
34
+ executor = Puppet.lookup(:bolt_executor)
35
+ # Send Analytics Report
36
+ executor.report_function_call(self.class.name)
37
+
38
+ inventory.remove_from_group(inventory.get_targets(target), group)
39
+ end
40
+ end
@@ -0,0 +1,42 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'bolt/error'
4
+
5
+ # Evaluates all `_plugin` references in a hash and returns the resolved reference data.
6
+ Puppet::Functions.create_function(:resolve_references) do
7
+ # Resolve references.
8
+ # @param references A hash of reference data to resolve.
9
+ # @return A hash of resolved reference data.
10
+ # @example Resolve a hash of reference data
11
+ # $references = {
12
+ # "targets" => [
13
+ # "_plugin" => "terraform",
14
+ # "dir" => "path/to/terraform/project",
15
+ # "resource_type" => "aws_instance.web",
16
+ # "uri" => "public_ip"
17
+ # ]
18
+ # }
19
+ #
20
+ # resolve_references($references)
21
+ dispatch :resolve_references do
22
+ param 'Data', :references
23
+ return_type 'Data'
24
+ end
25
+
26
+ def resolve_references(references)
27
+ unless Puppet[:tasks]
28
+ raise Puppet::ParseErrorWithIssue
29
+ .from_issue_and_stack(
30
+ Bolt::PAL::Issues::PLAN_OPERATION_NOT_SUPPORTED_WHEN_COMPILING,
31
+ action: 'resolve_references'
32
+ )
33
+ end
34
+
35
+ executor = Puppet.lookup(:bolt_executor)
36
+ # Send Analytics Report
37
+ executor.report_function_call(self.class.name)
38
+
39
+ plugins = Puppet.lookup(:bolt_inventory).plugins
40
+ plugins.resolve_references(references)
41
+ end
42
+ end
@@ -0,0 +1,53 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Lookup a resource in the target's data.
4
+ #
5
+ # For more information about resources see [the
6
+ # documentation](https://puppet.com/docs/puppet/latest/lang_resources.html).
7
+ #
8
+ # > **Note:** The `ResourceInstance` data type is under active development and is subject to
9
+ # change. You can read more about the data type in the [experimental features
10
+ # documentation](experimental_features.md#resourceinstance-data-type).
11
+ Puppet::Functions.create_function(:resource) do
12
+ # Lookup a resource in the target's data.
13
+ # @param target The Target object to add resources to. See {get_targets}.
14
+ # @param type The type of the resource
15
+ # @param title The title of the resource
16
+ # @return The ResourceInstance if found, or Undef
17
+ # @example Get the openssl package resource
18
+ # $target.apply_prep
19
+ # $resources = $target.get_resources(Package).first['resources']
20
+ # $target.set_resources($resources)
21
+ # $openssl = $target.resource('Package', 'openssl')
22
+ dispatch :resource do
23
+ param 'Target', :target
24
+ param 'Type[Resource]', :type
25
+ param 'String[1]', :title
26
+ return_type 'Optional[ResourceInstance]'
27
+ end
28
+
29
+ # Lookup a resource in the target's data, referring to resource as a string
30
+ # @param target The Target object to add resources to. See {get_targets}.
31
+ # @param type The type of the resource
32
+ # @param title The title of the resource
33
+ # @return The ResourceInstance if found, or Undef
34
+ dispatch :resource_from_string do
35
+ param 'Target', :target
36
+ param 'String[1]', :type
37
+ param 'String[1]', :title
38
+ return_type 'Optional[ResourceInstance]'
39
+ end
40
+
41
+ def resource(target, type, title)
42
+ inventory = Puppet.lookup(:bolt_inventory)
43
+ executor = Puppet.lookup(:bolt_executor) { nil }
44
+ # Send Analytics Report
45
+ executor&.report_function_call(self.class.name)
46
+
47
+ inventory.resource(target, type, title)
48
+ end
49
+
50
+ def resource_from_string(target, type, title)
51
+ resource(target, type, title)
52
+ end
53
+ end
@@ -0,0 +1,106 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'bolt/error'
4
+ require 'json'
5
+
6
+ # Runs a command on the given set of targets and returns the result from each command execution.
7
+ # This function does nothing if the list of targets is empty.
8
+ #
9
+ # > **Note:** Not available in apply block
10
+ Puppet::Functions.create_function(:run_command) do
11
+ # Run a command.
12
+ # @param command A command to run on target.
13
+ # @param targets A pattern identifying zero or more targets. See {get_targets} for accepted patterns.
14
+ # @param options A hash of additional options.
15
+ # @option options [Boolean] _catch_errors Whether to catch raised errors.
16
+ # @option options [String] _run_as User to run as using privilege escalation.
17
+ # @option options [Hash[String, Any]] _env_vars Map of environment variables to set
18
+ # @return A list of results, one entry per target.
19
+ # @example Run a command on targets
20
+ # run_command('hostname', $targets, '_catch_errors' => true)
21
+ dispatch :run_command do
22
+ param 'String[1]', :command
23
+ param 'Boltlib::TargetSpec', :targets
24
+ optional_param 'Hash[String[1], Any]', :options
25
+ return_type 'ResultSet'
26
+ end
27
+
28
+ # Run a command, logging the provided description.
29
+ # @param command A command to run on target.
30
+ # @param targets A pattern identifying zero or more targets. See {get_targets} for accepted patterns.
31
+ # @param description A description to be output when calling this function.
32
+ # @param options A hash of additional options.
33
+ # @option options [Boolean] _catch_errors Whether to catch raised errors.
34
+ # @option options [String] _run_as User to run as using privilege escalation.
35
+ # @option options [Hash[String, Any]] _env_vars Map of environment variables to set
36
+ # @return A list of results, one entry per target.
37
+ # @example Run a command on targets
38
+ # run_command('hostname', $targets, 'Get hostname')
39
+ dispatch :run_command_with_description do
40
+ param 'String[1]', :command
41
+ param 'Boltlib::TargetSpec', :targets
42
+ param 'String', :description
43
+ optional_param 'Hash[String[1], Any]', :options
44
+ return_type 'ResultSet'
45
+ end
46
+
47
+ def run_command(command, targets, options = {})
48
+ run_command_with_description(command, targets, nil, options)
49
+ end
50
+
51
+ def run_command_with_description(command, targets, description = nil, options = {})
52
+ unless Puppet[:tasks]
53
+ raise Puppet::ParseErrorWithIssue
54
+ .from_issue_and_stack(Bolt::PAL::Issues::PLAN_OPERATION_NOT_SUPPORTED_WHEN_COMPILING, action: 'run_command')
55
+ end
56
+
57
+ options = options.transform_keys { |k| k.sub(/^_/, '').to_sym }
58
+ options[:description] = description if description
59
+
60
+ # Ensure env_vars is a hash and that each hash value is transformed to JSON
61
+ # so we don't accidentally pass Ruby-style data to the target.
62
+ if options[:env_vars]
63
+ unless options[:env_vars].is_a?(Hash)
64
+ raise Bolt::ValidationError, "Option 'env_vars' must be a hash"
65
+ end
66
+
67
+ if (bad_keys = options[:env_vars].keys.reject { |k| k.is_a?(String) }).any?
68
+ raise Bolt::ValidationError,
69
+ "Keys for option 'env_vars' must be strings: #{bad_keys.map(&:inspect).join(', ')}"
70
+ end
71
+
72
+ options[:env_vars] = options[:env_vars].transform_values do |val|
73
+ [Array, Hash].include?(val.class) ? val.to_json : val
74
+ end
75
+ end
76
+
77
+ executor = Puppet.lookup(:bolt_executor)
78
+ inventory = Puppet.lookup(:bolt_inventory)
79
+
80
+ # Send Analytics Report
81
+ executor.report_function_call(self.class.name)
82
+
83
+ # Ensure that given targets are all Target instances
84
+ targets = inventory.get_targets(targets)
85
+
86
+ if targets.empty?
87
+ call_function('debug', "Simulating run_command('#{command}') - no targets given - no action taken")
88
+ Bolt::ResultSet.new([])
89
+ else
90
+ file_line = Puppet::Pops::PuppetStack.top_of_stack
91
+ r = if executor.in_parallel?
92
+ executor.run_in_thread do
93
+ executor.run_command(targets, command, options, file_line)
94
+ end
95
+ else
96
+ executor.run_command(targets, command, options, file_line)
97
+ end
98
+
99
+ if !r.ok && !options[:catch_errors]
100
+ raise Bolt::RunFailure.new(r, 'run_command', command)
101
+ end
102
+
103
+ r
104
+ end
105
+ end
106
+ end