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,63 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Bolt
4
+ class PAL
5
+ class YamlPlan
6
+ class Parameter
7
+ attr_reader :name, :value, :type_expr, :description
8
+
9
+ PARAMETER_KEYS = Set['type', 'default', 'description']
10
+
11
+ def initialize(param, definition)
12
+ definition ||= {}
13
+ validate_param(param, definition)
14
+
15
+ @name = param
16
+ @value = definition['default']
17
+ @type_expr = Puppet::Pops::Types::TypeParser.singleton.parse(definition['type']) if definition['type']
18
+ @description = definition['description']
19
+ end
20
+
21
+ def validate_param(param, definition)
22
+ unless param.is_a?(String) && param.match?(Bolt::PAL::YamlPlan::VAR_NAME_PATTERN)
23
+ raise Bolt::Error.new("Invalid parameter name #{param.inspect}", "bolt/invalid-plan")
24
+ end
25
+
26
+ definition_keys = definition.keys.to_set
27
+ unless PARAMETER_KEYS.superset?(definition_keys)
28
+ invalid_keys = definition_keys - PARAMETER_KEYS
29
+ raise Bolt::Error.new("Plan parameter #{param.inspect} contains illegal key(s)" \
30
+ " #{invalid_keys.to_a.inspect}",
31
+ "bolt/invalid-plan")
32
+ end
33
+ end
34
+
35
+ def captures_rest
36
+ false
37
+ end
38
+
39
+ def transpile
40
+ result = String.new
41
+ result << "\n\s\s"
42
+
43
+ # Param type
44
+ if @type_expr.respond_to?(:type_string)
45
+ result << @type_expr.type_string + " "
46
+ elsif !@type_expr.nil?
47
+ result << @type_expr.to_s + " "
48
+ end
49
+
50
+ # Param name
51
+ result << "$#{@name}"
52
+
53
+ # Param default
54
+ if @value
55
+ default = @type_expr.to_s =~ /String/ ? "'#{@value}'" : @value
56
+ result << " = #{default}"
57
+ end
58
+ result
59
+ end
60
+ end
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,45 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Bolt
4
+ class PAL
5
+ class YamlPlan
6
+ class Step
7
+ class Command < Step
8
+ def self.option_keys
9
+ Set['catch_errors', 'env_vars', 'run_as']
10
+ end
11
+
12
+ def self.required_keys
13
+ Set['command', 'targets']
14
+ end
15
+
16
+ def self.validate_step_keys(body, number)
17
+ super
18
+
19
+ if body.key?('env_vars') && ![Hash, String].include?(body['env_vars'].class)
20
+ raise StepError.new('env_vars key must be a hash or evaluable string', body['name'], number)
21
+ end
22
+ end
23
+
24
+ # Returns an array of arguments to pass to the step's function call
25
+ #
26
+ private def format_args(body)
27
+ opts = format_options(body)
28
+
29
+ args = [body['command'], body['targets']]
30
+ args << body['description'] if body['description']
31
+ args << opts if opts.any?
32
+
33
+ args
34
+ end
35
+
36
+ # Returns the function corresponding to the step
37
+ #
38
+ private def function
39
+ 'run_command'
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,37 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Bolt
4
+ class PAL
5
+ class YamlPlan
6
+ class Step
7
+ class Download < Step
8
+ def self.option_keys
9
+ Set['catch_errors', 'run_as']
10
+ end
11
+
12
+ def self.required_keys
13
+ Set['download', 'destination', 'targets']
14
+ end
15
+
16
+ # Returns an array of arguments to pass to the step's function call
17
+ #
18
+ private def format_args(body)
19
+ opts = format_options(body)
20
+
21
+ args = [body['download'], body['destination'], body['targets']]
22
+ args << body['description'] if body['description']
23
+ args << opts if opts.any?
24
+
25
+ args
26
+ end
27
+
28
+ # Returns the function corresponding to the step
29
+ #
30
+ private def function
31
+ 'download_file'
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,42 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Bolt
4
+ class PAL
5
+ class YamlPlan
6
+ class Step
7
+ class Eval < Step
8
+ def self.required_keys
9
+ Set['eval']
10
+ end
11
+
12
+ # Evaluates the step
13
+ #
14
+ def evaluate(scope, evaluator)
15
+ evaluated = evaluator.evaluate_code_blocks(scope, body)
16
+ evaluated['eval']
17
+ end
18
+
19
+ # Transpiles the step into the plan language
20
+ #
21
+ def transpile
22
+ code = String.new(" ")
23
+ code << "$#{body['name']} = " if body['name']
24
+
25
+ code_body = Bolt::Util.to_code(body['eval']) || 'undef'
26
+
27
+ # If we're trying to assign the result of a multi-line eval to a name
28
+ # variable, we need to wrap it in `with()`.
29
+ if body['name'] && code_body.lines.count > 1
30
+ indented = code_body.gsub(/\n/, "\n ").chomp(" ")
31
+ code << "with() || {\n #{indented}}"
32
+ else
33
+ code << code_body
34
+ end
35
+
36
+ code << "\n"
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Bolt
4
+ class PAL
5
+ class YamlPlan
6
+ class Step
7
+ class Message < Step
8
+ def self.allowed_keys
9
+ super + Set['message']
10
+ end
11
+
12
+ def self.required_keys
13
+ Set['message']
14
+ end
15
+
16
+ # Returns an array of arguments to pass to the step's function call
17
+ #
18
+ private def format_args(body)
19
+ [body['message']]
20
+ end
21
+
22
+ # Returns the function corresponding to the step
23
+ #
24
+ private def function
25
+ 'out::message'
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,42 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Bolt
4
+ class PAL
5
+ class YamlPlan
6
+ class Step
7
+ class Plan < Step
8
+ def self.allowed_keys
9
+ super + Set['parameters']
10
+ end
11
+
12
+ def self.option_keys
13
+ Set['catch_errors', 'run_as']
14
+ end
15
+
16
+ def self.required_keys
17
+ Set['plan']
18
+ end
19
+
20
+ # Returns an array of arguments to pass to the step's function call
21
+ #
22
+ private def format_args(body)
23
+ opts = format_options(body)
24
+ params = (body['parameters'] || {}).merge(opts)
25
+
26
+ args = [body['plan']]
27
+ args << body['targets'] if body['targets']
28
+ args << params if params.any?
29
+
30
+ args
31
+ end
32
+
33
+ # Returns the function corresponding to the step
34
+ #
35
+ private def function
36
+ 'run_plan'
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,170 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Bolt
4
+ class PAL
5
+ class YamlPlan
6
+ class Step
7
+ class Resources < Step
8
+ def self.option_keys
9
+ Set['catch_errors', 'description', 'noop', 'run_as']
10
+ end
11
+
12
+ def self.required_keys
13
+ Set['resources', 'targets']
14
+ end
15
+
16
+ def initialize(body)
17
+ super
18
+ @body['resources'] = normalize_resources(@body['resources'])
19
+ end
20
+
21
+ # Returns an array of arguments to pass to the apply function call
22
+ #
23
+ private def format_args(body)
24
+ opts = format_options(body)
25
+
26
+ args = [body['targets']]
27
+ args << opts if opts.any?
28
+
29
+ args
30
+ end
31
+
32
+ def evaluate(scope, evaluator)
33
+ evaluated = evaluator.evaluate_code_blocks(scope, body)
34
+
35
+ scope.call_function('apply_prep', evaluated['targets'])
36
+
37
+ apply_args = format_args(evaluated)
38
+ manifest = generate_manifest(evaluated['resources'])
39
+ apply_manifest(scope, apply_args, manifest)
40
+ end
41
+
42
+ # Generates a manifest from the resources
43
+ #
44
+ private def generate_manifest(resources)
45
+ # inspect returns the Ruby representation of the resource hashes,
46
+ # which happens to be the same as the Puppet representation
47
+ puppet_resources = resources.inspect
48
+
49
+ # Because the :tasks setting globally controls which mode the parser
50
+ # is in, we need to make this snippet of non-tasks manifest code
51
+ # parseable in tasks mode. The way to do that is by putting it in an
52
+ # apply statement and taking the body.
53
+ <<~MANIFEST
54
+ apply('placeholder') {
55
+ $resources = #{puppet_resources}
56
+ $resources.each |$res| {
57
+ Resource[$res['type']] { $res['title']:
58
+ * => $res['parameters'],
59
+ }
60
+ }
61
+
62
+ # Add relationships if there is more than one resource
63
+ if $resources.length > 1 {
64
+ ($resources.length - 1).each |$index| {
65
+ $lhs = $resources[$index]
66
+ $rhs = $resources[$index+1]
67
+ $lhs_resource = Resource[$lhs['type'] , $lhs['title']]
68
+ $rhs_resource = Resource[$rhs['type'] , $rhs['title']]
69
+ $lhs_resource -> $rhs_resource
70
+ }
71
+ }
72
+ }
73
+ MANIFEST
74
+ end
75
+
76
+ # Applies the manifest block on the targets
77
+ #
78
+ private def apply_manifest(scope, args, manifest)
79
+ ast = self.class.parse_code_string(manifest)
80
+ apply_block = ast.body.body
81
+ applicator = Puppet.lookup(:apply_executor)
82
+ applicator.apply(args, apply_block, scope)
83
+ end
84
+
85
+ def self.validate(body, step_number)
86
+ super
87
+
88
+ body['resources'].each do |resource|
89
+ if resource['type'] || resource['title']
90
+ if !resource['type']
91
+ err = "Resource declaration must include type key if title key is set"
92
+ raise StepError.new(err, body['name'], step_number)
93
+ elsif !resource['title']
94
+ err = "Resource declaration must include title key if type key is set"
95
+ raise StepError.new(err, body['name'], step_number)
96
+ end
97
+ else
98
+ type_keys = (resource.keys - ['parameters'])
99
+ if type_keys.empty?
100
+ err = "Resource declaration is missing a type"
101
+ raise StepError.new(err, body['name'], step_number)
102
+ elsif type_keys.length > 1
103
+ err = "Resource declaration has ambiguous type: could be #{type_keys.join(' or ')}"
104
+ raise StepError.new(err, body['name'], step_number)
105
+ end
106
+ end
107
+ end
108
+ end
109
+
110
+ # Normalizes the resources so they are in a format compatible with apply blocks
111
+ # What if this comes from a code block?
112
+ #
113
+ private def normalize_resources(resources)
114
+ resources.map do |resource|
115
+ if resource['type'] && resource['title']
116
+ type = resource['type']
117
+ title = resource['title']
118
+ else
119
+ type, = (resource.keys - ['parameters'])
120
+ title = resource[type]
121
+ end
122
+
123
+ { 'type' => type, 'title' => title, 'parameters' => resource['parameters'] || {} }
124
+ end
125
+ end
126
+
127
+ def transpile
128
+ code = StringIO.new
129
+
130
+ code.print " "
131
+ code << function_call('apply_prep', [body['targets']])
132
+ code.print "\n"
133
+
134
+ code.print " "
135
+ code.print "$#{body['name']} = " if body['name']
136
+
137
+ code << function_call('apply', format_args(body))
138
+
139
+ code.print " {\n"
140
+
141
+ declarations = body['resources'].map do |resource|
142
+ type = resource['type'].is_a?(EvaluableString) ? resource['type'].value : resource['type']
143
+ title = Bolt::Util.to_code(resource['title'])
144
+ parameters = resource['parameters'].transform_values do |val|
145
+ Bolt::Util.to_code(val)
146
+ end
147
+
148
+ resource_str = StringIO.new
149
+ if parameters.empty?
150
+ resource_str.puts " #{type} { #{title}: }"
151
+ else
152
+ resource_str.puts " #{type} { #{title}:"
153
+ parameters.each do |key, val|
154
+ resource_str.puts " #{key} => #{val},"
155
+ end
156
+ resource_str.puts " }"
157
+ end
158
+ resource_str.string
159
+ end
160
+
161
+ code.puts declarations.join(" ->\n")
162
+
163
+ code.puts " }\n"
164
+ code.string
165
+ end
166
+ end
167
+ end
168
+ end
169
+ end
170
+ end
@@ -0,0 +1,62 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Bolt
4
+ class PAL
5
+ class YamlPlan
6
+ class Step
7
+ class Script < Step
8
+ def self.allowed_keys
9
+ super + Set['arguments', 'pwsh_params']
10
+ end
11
+
12
+ def self.option_keys
13
+ Set['catch_errors', 'env_vars', 'run_as']
14
+ end
15
+
16
+ def self.required_keys
17
+ Set['script', 'targets']
18
+ end
19
+
20
+ def self.validate_step_keys(body, number)
21
+ super
22
+
23
+ if body.key?('arguments') && !body['arguments'].nil? && !body['arguments'].is_a?(Array)
24
+ raise StepError.new('arguments key must be an array', body['name'], number)
25
+ end
26
+
27
+ if body.key?('pwsh_params') && !body['pwsh_params'].nil? && !body['pwsh_params'].is_a?(Hash)
28
+ raise StepError.new('pwsh_params key must be a hash', body['name'], number)
29
+ end
30
+
31
+ if body.key?('env_vars') && ![Hash, String].include?(body['env_vars'].class)
32
+ raise StepError.new('env_vars key must be a hash or evaluable string', body['name'], number)
33
+ end
34
+ end
35
+
36
+ # Returns an array of arguments to pass to the step's function call
37
+ #
38
+ private def format_args(body)
39
+ args = body['arguments'] || []
40
+ pwsh_params = body['pwsh_params'] || {}
41
+
42
+ opts = format_options(body)
43
+ opts = opts.merge('arguments' => args) if args.any?
44
+ opts = opts.merge('pwsh_params' => pwsh_params) if pwsh_params.any?
45
+
46
+ args = [body['script'], body['targets']]
47
+ args << body['description'] if body['description']
48
+ args << opts if opts.any?
49
+
50
+ args
51
+ end
52
+
53
+ # Returns the function corresponding to the step
54
+ #
55
+ private def function
56
+ 'run_script'
57
+ end
58
+ end
59
+ end
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,42 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Bolt
4
+ class PAL
5
+ class YamlPlan
6
+ class Step
7
+ class Task < Step
8
+ def self.allowed_keys
9
+ super + Set['parameters']
10
+ end
11
+
12
+ def self.option_keys
13
+ Set['catch_errors', 'noop', 'run_as']
14
+ end
15
+
16
+ def self.required_keys
17
+ Set['targets', 'task']
18
+ end
19
+
20
+ # Returns an array of arguments to pass to the step's function call
21
+ #
22
+ private def format_args(body)
23
+ opts = format_options(body)
24
+ params = (body['parameters'] || {}).merge(opts)
25
+
26
+ args = [body['task'], body['targets']]
27
+ args << body['description'] if body['description']
28
+ args << params if params.any?
29
+
30
+ args
31
+ end
32
+
33
+ # Returns the function corresponding to the step
34
+ #
35
+ private def function
36
+ 'run_task'
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,37 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Bolt
4
+ class PAL
5
+ class YamlPlan
6
+ class Step
7
+ class Upload < Step
8
+ def self.option_keys
9
+ Set['catch_errors', 'run_as']
10
+ end
11
+
12
+ def self.required_keys
13
+ Set['destination', 'targets', 'upload']
14
+ end
15
+
16
+ # Returns an array of arguments to pass to the step's function call
17
+ #
18
+ private def format_args(body)
19
+ opts = format_options(body)
20
+
21
+ args = [body['upload'], body['destination'], body['targets']]
22
+ args << body['description'] if body['description']
23
+ args << opts if opts.any?
24
+
25
+ args
26
+ end
27
+
28
+ # Returns the function corresponding to the step
29
+ #
30
+ private def function
31
+ 'upload_file'
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Bolt
4
+ class PAL
5
+ class YamlPlan
6
+ class Step
7
+ class Verbose < Step
8
+ def self.allowed_keys
9
+ super + Set['verbose']
10
+ end
11
+
12
+ def self.required_keys
13
+ Set['verbose']
14
+ end
15
+
16
+ # Returns an array of arguments to pass to the step's function call
17
+ #
18
+ private def format_args(body)
19
+ [body['verbose']]
20
+ end
21
+
22
+ # Returns the function corresponding to the step
23
+ #
24
+ private def function
25
+ 'out::verbose'
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end