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.
- checksums.yaml +7 -0
- data/Puppetfile +52 -0
- data/bolt-modules/boltlib/lib/puppet/datatypes/applyresult.rb +60 -0
- data/bolt-modules/boltlib/lib/puppet/datatypes/containerresult.rb +51 -0
- data/bolt-modules/boltlib/lib/puppet/datatypes/future.rb +25 -0
- data/bolt-modules/boltlib/lib/puppet/datatypes/resourceinstance.rb +71 -0
- data/bolt-modules/boltlib/lib/puppet/datatypes/result.rb +55 -0
- data/bolt-modules/boltlib/lib/puppet/datatypes/resultset.rb +65 -0
- data/bolt-modules/boltlib/lib/puppet/datatypes/target.rb +93 -0
- data/bolt-modules/boltlib/lib/puppet/functions/add_facts.rb +33 -0
- data/bolt-modules/boltlib/lib/puppet/functions/add_to_group.rb +38 -0
- data/bolt-modules/boltlib/lib/puppet/functions/apply_prep.rb +208 -0
- data/bolt-modules/boltlib/lib/puppet/functions/background.rb +62 -0
- data/bolt-modules/boltlib/lib/puppet/functions/catch_errors.rb +57 -0
- data/bolt-modules/boltlib/lib/puppet/functions/download_file.rb +130 -0
- data/bolt-modules/boltlib/lib/puppet/functions/facts.rb +31 -0
- data/bolt-modules/boltlib/lib/puppet/functions/fail_plan.rb +52 -0
- data/bolt-modules/boltlib/lib/puppet/functions/get_resources.rb +87 -0
- data/bolt-modules/boltlib/lib/puppet/functions/get_target.rb +34 -0
- data/bolt-modules/boltlib/lib/puppet/functions/get_targets.rb +35 -0
- data/bolt-modules/boltlib/lib/puppet/functions/parallelize.rb +74 -0
- data/bolt-modules/boltlib/lib/puppet/functions/puppetdb_command.rb +97 -0
- data/bolt-modules/boltlib/lib/puppet/functions/puppetdb_fact.rb +47 -0
- data/bolt-modules/boltlib/lib/puppet/functions/puppetdb_query.rb +52 -0
- data/bolt-modules/boltlib/lib/puppet/functions/remove_from_group.rb +40 -0
- data/bolt-modules/boltlib/lib/puppet/functions/resolve_references.rb +42 -0
- data/bolt-modules/boltlib/lib/puppet/functions/resource.rb +53 -0
- data/bolt-modules/boltlib/lib/puppet/functions/run_command.rb +106 -0
- data/bolt-modules/boltlib/lib/puppet/functions/run_container.rb +162 -0
- data/bolt-modules/boltlib/lib/puppet/functions/run_plan.rb +291 -0
- data/bolt-modules/boltlib/lib/puppet/functions/run_script.rb +145 -0
- data/bolt-modules/boltlib/lib/puppet/functions/run_task.rb +164 -0
- data/bolt-modules/boltlib/lib/puppet/functions/run_task_with.rb +211 -0
- data/bolt-modules/boltlib/lib/puppet/functions/set_config.rb +48 -0
- data/bolt-modules/boltlib/lib/puppet/functions/set_feature.rb +43 -0
- data/bolt-modules/boltlib/lib/puppet/functions/set_resources.rb +145 -0
- data/bolt-modules/boltlib/lib/puppet/functions/set_var.rb +38 -0
- data/bolt-modules/boltlib/lib/puppet/functions/upload_file.rb +101 -0
- data/bolt-modules/boltlib/lib/puppet/functions/vars.rb +29 -0
- data/bolt-modules/boltlib/lib/puppet/functions/wait.rb +131 -0
- data/bolt-modules/boltlib/lib/puppet/functions/wait_until_available.rb +59 -0
- data/bolt-modules/boltlib/lib/puppet/functions/without_default_logging.rb +39 -0
- data/bolt-modules/boltlib/lib/puppet/functions/write_file.rb +50 -0
- data/bolt-modules/boltlib/types/planresult.pp +18 -0
- data/bolt-modules/boltlib/types/targetspec.pp +7 -0
- data/bolt-modules/ctrl/lib/puppet/functions/ctrl/do_until.rb +42 -0
- data/bolt-modules/ctrl/lib/puppet/functions/ctrl/sleep.rb +20 -0
- data/bolt-modules/dir/lib/puppet/functions/dir/children.rb +35 -0
- data/bolt-modules/file/lib/puppet/functions/file/delete.rb +21 -0
- data/bolt-modules/file/lib/puppet/functions/file/exists.rb +28 -0
- data/bolt-modules/file/lib/puppet/functions/file/join.rb +20 -0
- data/bolt-modules/file/lib/puppet/functions/file/read.rb +33 -0
- data/bolt-modules/file/lib/puppet/functions/file/readable.rb +28 -0
- data/bolt-modules/file/lib/puppet/functions/file/write.rb +24 -0
- data/bolt-modules/log/lib/puppet/functions/log/debug.rb +39 -0
- data/bolt-modules/log/lib/puppet/functions/log/error.rb +40 -0
- data/bolt-modules/log/lib/puppet/functions/log/fatal.rb +40 -0
- data/bolt-modules/log/lib/puppet/functions/log/info.rb +39 -0
- data/bolt-modules/log/lib/puppet/functions/log/trace.rb +39 -0
- data/bolt-modules/log/lib/puppet/functions/log/warn.rb +41 -0
- data/bolt-modules/out/lib/puppet/functions/out/message.rb +36 -0
- data/bolt-modules/out/lib/puppet/functions/out/verbose.rb +35 -0
- data/bolt-modules/prompt/lib/puppet/functions/prompt/menu.rb +103 -0
- data/bolt-modules/prompt/lib/puppet/functions/prompt.rb +65 -0
- data/bolt-modules/system/lib/puppet/functions/system/env.rb +20 -0
- data/exe/bolt +17 -0
- data/guides/debugging.yaml +27 -0
- data/guides/inventory.yaml +23 -0
- data/guides/links.yaml +12 -0
- data/guides/logging.yaml +17 -0
- data/guides/module.yaml +18 -0
- data/guides/modulepath.yaml +24 -0
- data/guides/project.yaml +21 -0
- data/guides/targets.yaml +28 -0
- data/guides/transports.yaml +22 -0
- data/lib/bolt/analytics.rb +233 -0
- data/lib/bolt/application.rb +806 -0
- data/lib/bolt/applicator.rb +368 -0
- data/lib/bolt/apply_inventory.rb +93 -0
- data/lib/bolt/apply_result.rb +154 -0
- data/lib/bolt/apply_target.rb +90 -0
- data/lib/bolt/bolt_option_parser.rb +1226 -0
- data/lib/bolt/catalog/logging.rb +15 -0
- data/lib/bolt/catalog.rb +144 -0
- data/lib/bolt/cli.rb +949 -0
- data/lib/bolt/config/modulepath.rb +30 -0
- data/lib/bolt/config/options.rb +673 -0
- data/lib/bolt/config/transport/base.rb +133 -0
- data/lib/bolt/config/transport/docker.rb +34 -0
- data/lib/bolt/config/transport/jail.rb +33 -0
- data/lib/bolt/config/transport/local.rb +39 -0
- data/lib/bolt/config/transport/lxd.rb +34 -0
- data/lib/bolt/config/transport/options.rb +431 -0
- data/lib/bolt/config/transport/orch.rb +41 -0
- data/lib/bolt/config/transport/podman.rb +33 -0
- data/lib/bolt/config/transport/remote.rb +24 -0
- data/lib/bolt/config/transport/ssh.rb +138 -0
- data/lib/bolt/config/transport/winrm.rb +63 -0
- data/lib/bolt/config.rb +515 -0
- data/lib/bolt/container_result.rb +105 -0
- data/lib/bolt/error.rb +194 -0
- data/lib/bolt/executor.rb +539 -0
- data/lib/bolt/fiber_executor.rb +190 -0
- data/lib/bolt/inventory/group.rb +446 -0
- data/lib/bolt/inventory/inventory.rb +391 -0
- data/lib/bolt/inventory/options.rb +139 -0
- data/lib/bolt/inventory/target.rb +293 -0
- data/lib/bolt/inventory.rb +120 -0
- data/lib/bolt/logger.rb +252 -0
- data/lib/bolt/module.rb +54 -0
- data/lib/bolt/module_installer/installer.rb +44 -0
- data/lib/bolt/module_installer/puppetfile/forge_module.rb +54 -0
- data/lib/bolt/module_installer/puppetfile/git_module.rb +37 -0
- data/lib/bolt/module_installer/puppetfile/module.rb +26 -0
- data/lib/bolt/module_installer/puppetfile.rb +131 -0
- data/lib/bolt/module_installer/resolver.rb +129 -0
- data/lib/bolt/module_installer/specs/forge_spec.rb +91 -0
- data/lib/bolt/module_installer/specs/git_spec.rb +150 -0
- data/lib/bolt/module_installer/specs/id/base.rb +116 -0
- data/lib/bolt/module_installer/specs/id/gitclone.rb +120 -0
- data/lib/bolt/module_installer/specs/id/github.rb +90 -0
- data/lib/bolt/module_installer/specs/id/gitlab.rb +92 -0
- data/lib/bolt/module_installer/specs.rb +95 -0
- data/lib/bolt/module_installer.rb +208 -0
- data/lib/bolt/node/errors.rb +55 -0
- data/lib/bolt/node/output.rb +29 -0
- data/lib/bolt/outputter/human.rb +958 -0
- data/lib/bolt/outputter/json.rb +205 -0
- data/lib/bolt/outputter/logger.rb +76 -0
- data/lib/bolt/outputter/rainbow.rb +118 -0
- data/lib/bolt/outputter.rb +57 -0
- data/lib/bolt/pal/issues.rb +19 -0
- data/lib/bolt/pal/logging.rb +17 -0
- data/lib/bolt/pal/yaml_plan/evaluator.rb +83 -0
- data/lib/bolt/pal/yaml_plan/loader.rb +94 -0
- data/lib/bolt/pal/yaml_plan/parameter.rb +63 -0
- data/lib/bolt/pal/yaml_plan/step/command.rb +45 -0
- data/lib/bolt/pal/yaml_plan/step/download.rb +37 -0
- data/lib/bolt/pal/yaml_plan/step/eval.rb +42 -0
- data/lib/bolt/pal/yaml_plan/step/message.rb +31 -0
- data/lib/bolt/pal/yaml_plan/step/plan.rb +42 -0
- data/lib/bolt/pal/yaml_plan/step/resources.rb +170 -0
- data/lib/bolt/pal/yaml_plan/step/script.rb +62 -0
- data/lib/bolt/pal/yaml_plan/step/task.rb +42 -0
- data/lib/bolt/pal/yaml_plan/step/upload.rb +37 -0
- data/lib/bolt/pal/yaml_plan/step/verbose.rb +31 -0
- data/lib/bolt/pal/yaml_plan/step.rb +223 -0
- data/lib/bolt/pal/yaml_plan/transpiler.rb +90 -0
- data/lib/bolt/pal/yaml_plan.rb +172 -0
- data/lib/bolt/pal.rb +847 -0
- data/lib/bolt/plan_creator.rb +219 -0
- data/lib/bolt/plan_future.rb +86 -0
- data/lib/bolt/plan_result.rb +44 -0
- data/lib/bolt/plugin/cache.rb +76 -0
- data/lib/bolt/plugin/env_var.rb +54 -0
- data/lib/bolt/plugin/module.rb +276 -0
- data/lib/bolt/plugin/prompt.rb +36 -0
- data/lib/bolt/plugin/puppet_connect_data.rb +84 -0
- data/lib/bolt/plugin/puppetdb.rb +124 -0
- data/lib/bolt/plugin/task.rb +72 -0
- data/lib/bolt/plugin.rb +380 -0
- data/lib/bolt/project.rb +219 -0
- data/lib/bolt/project_manager/config_migrator.rb +113 -0
- data/lib/bolt/project_manager/inventory_migrator.rb +67 -0
- data/lib/bolt/project_manager/migrator.rb +39 -0
- data/lib/bolt/project_manager/module_migrator.rb +203 -0
- data/lib/bolt/project_manager.rb +221 -0
- data/lib/bolt/puppetdb/client.rb +153 -0
- data/lib/bolt/puppetdb/config.rb +176 -0
- data/lib/bolt/puppetdb/instance.rb +146 -0
- data/lib/bolt/puppetdb.rb +15 -0
- data/lib/bolt/r10k_log_proxy.rb +30 -0
- data/lib/bolt/rerun.rb +55 -0
- data/lib/bolt/resource_instance.rb +133 -0
- data/lib/bolt/result.rb +247 -0
- data/lib/bolt/result_set.rb +128 -0
- data/lib/bolt/shell/bash/tmpdir.rb +62 -0
- data/lib/bolt/shell/bash.rb +516 -0
- data/lib/bolt/shell/powershell/snippets.rb +181 -0
- data/lib/bolt/shell/powershell.rb +365 -0
- data/lib/bolt/shell.rb +105 -0
- data/lib/bolt/target.rb +174 -0
- data/lib/bolt/task/puppet_server.rb +27 -0
- data/lib/bolt/task/run.rb +55 -0
- data/lib/bolt/task.rb +163 -0
- data/lib/bolt/transport/base.rb +252 -0
- data/lib/bolt/transport/docker/connection.rb +150 -0
- data/lib/bolt/transport/docker.rb +23 -0
- data/lib/bolt/transport/jail/connection.rb +81 -0
- data/lib/bolt/transport/jail.rb +21 -0
- data/lib/bolt/transport/local/connection.rb +106 -0
- data/lib/bolt/transport/local.rb +20 -0
- data/lib/bolt/transport/lxd/connection.rb +115 -0
- data/lib/bolt/transport/lxd.rb +26 -0
- data/lib/bolt/transport/orch/connection.rb +111 -0
- data/lib/bolt/transport/orch.rb +271 -0
- data/lib/bolt/transport/podman/connection.rb +102 -0
- data/lib/bolt/transport/podman.rb +19 -0
- data/lib/bolt/transport/remote.rb +41 -0
- data/lib/bolt/transport/simple.rb +54 -0
- data/lib/bolt/transport/ssh/connection.rb +321 -0
- data/lib/bolt/transport/ssh/exec_connection.rb +140 -0
- data/lib/bolt/transport/ssh.rb +48 -0
- data/lib/bolt/transport/winrm/connection.rb +378 -0
- data/lib/bolt/transport/winrm.rb +33 -0
- data/lib/bolt/util/format.rb +68 -0
- data/lib/bolt/util/puppet_log_level.rb +21 -0
- data/lib/bolt/util.rb +465 -0
- data/lib/bolt/validator.rb +227 -0
- data/lib/bolt/version.rb +5 -0
- data/lib/bolt.rb +8 -0
- data/lib/bolt_server/acl.rb +39 -0
- data/lib/bolt_server/base_config.rb +112 -0
- data/lib/bolt_server/config.rb +64 -0
- data/lib/bolt_server/file_cache.rb +200 -0
- data/lib/bolt_server/request_error.rb +11 -0
- data/lib/bolt_server/schemas/action-check_node_connections.json +14 -0
- data/lib/bolt_server/schemas/action-run_command.json +12 -0
- data/lib/bolt_server/schemas/action-run_script.json +47 -0
- data/lib/bolt_server/schemas/action-run_task.json +20 -0
- data/lib/bolt_server/schemas/action-upload_file.json +47 -0
- data/lib/bolt_server/schemas/partials/target-any.json +10 -0
- data/lib/bolt_server/schemas/partials/target-ssh.json +88 -0
- data/lib/bolt_server/schemas/partials/target-winrm.json +67 -0
- data/lib/bolt_server/schemas/partials/task.json +94 -0
- data/lib/bolt_server/schemas/transport-ssh.json +25 -0
- data/lib/bolt_server/schemas/transport-winrm.json +19 -0
- data/lib/bolt_server/transport_app.rb +554 -0
- data/lib/bolt_spec/bolt_context.rb +226 -0
- data/lib/bolt_spec/plans/action_stubs/command_stub.rb +51 -0
- data/lib/bolt_spec/plans/action_stubs/download_stub.rb +66 -0
- data/lib/bolt_spec/plans/action_stubs/plan_stub.rb +55 -0
- data/lib/bolt_spec/plans/action_stubs/script_stub.rb +59 -0
- data/lib/bolt_spec/plans/action_stubs/task_stub.rb +57 -0
- data/lib/bolt_spec/plans/action_stubs/upload_stub.rb +65 -0
- data/lib/bolt_spec/plans/action_stubs.rb +196 -0
- data/lib/bolt_spec/plans/mock_executor.rb +361 -0
- data/lib/bolt_spec/plans/publish_stub.rb +49 -0
- data/lib/bolt_spec/plans.rb +190 -0
- data/lib/bolt_spec/run.rb +246 -0
- data/lib/logging_extensions/logging.rb +13 -0
- data/libexec/apply_catalog.rb +130 -0
- data/libexec/bolt_catalog +68 -0
- data/libexec/custom_facts.rb +63 -0
- data/libexec/query_resources.rb +75 -0
- data/modules/aggregate/lib/puppet/functions/aggregate/count.rb +21 -0
- data/modules/aggregate/lib/puppet/functions/aggregate/nodes.rb +22 -0
- data/modules/aggregate/lib/puppet/functions/aggregate/targets.rb +21 -0
- data/modules/aggregate/plans/count.pp +56 -0
- data/modules/aggregate/plans/targets.pp +56 -0
- data/modules/canary/lib/puppet/functions/canary/merge.rb +13 -0
- data/modules/canary/lib/puppet/functions/canary/random_split.rb +22 -0
- data/modules/canary/lib/puppet/functions/canary/skip.rb +25 -0
- data/modules/canary/plans/init.pp +100 -0
- data/modules/puppet_connect/plans/test_input_data.pp +94 -0
- data/modules/puppetdb_fact/plans/init.pp +20 -0
- data/resources/bolt_bash_completion.sh +214 -0
- metadata +735 -0
data/lib/bolt/plugin.rb
ADDED
@@ -0,0 +1,380 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative '../bolt/inventory'
|
4
|
+
require_relative '../bolt/executor'
|
5
|
+
require_relative '../bolt/module'
|
6
|
+
require_relative '../bolt/pal'
|
7
|
+
require_relative 'plugin/cache'
|
8
|
+
require_relative 'plugin/puppetdb'
|
9
|
+
|
10
|
+
module Bolt
|
11
|
+
class Plugin
|
12
|
+
KNOWN_HOOKS = %i[
|
13
|
+
puppet_library
|
14
|
+
resolve_reference
|
15
|
+
secret_encrypt
|
16
|
+
secret_decrypt
|
17
|
+
secret_createkeys
|
18
|
+
validate_resolve_reference
|
19
|
+
].freeze
|
20
|
+
|
21
|
+
class PluginError < Bolt::Error
|
22
|
+
class ExecutionError < PluginError
|
23
|
+
def initialize(msg, plugin_name, location)
|
24
|
+
mess = "Error executing plugin #{plugin_name} from #{location}: #{msg}"
|
25
|
+
super(mess, 'bolt/plugin-error')
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
class Unknown < PluginError
|
30
|
+
def initialize(plugin_name)
|
31
|
+
super("Unknown plugin: '#{plugin_name}'", 'bolt/unknown-plugin')
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
class UnsupportedHook < PluginError
|
36
|
+
def initialize(plugin_name, hook)
|
37
|
+
super("Plugin #{plugin_name} does not support #{hook}", 'bolt/unsupported-hook')
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
class LoadingDisabled < PluginError
|
42
|
+
def initialize(plugin_name)
|
43
|
+
msg = "Cannot load plugin #{plugin_name}: plugin loading is disabled"
|
44
|
+
super(msg, 'bolt/plugin-loading-disabled', { 'plugin_name' => plugin_name })
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
class PluginContext
|
50
|
+
def initialize(config, pal, plugins)
|
51
|
+
@pal = pal
|
52
|
+
@config = config
|
53
|
+
@plugins = plugins
|
54
|
+
end
|
55
|
+
|
56
|
+
def serial_executor
|
57
|
+
@serial_executor ||= Bolt::Executor.new(1)
|
58
|
+
end
|
59
|
+
private :serial_executor
|
60
|
+
|
61
|
+
def empty_inventory
|
62
|
+
@empty_inventory ||= Bolt::Inventory.empty
|
63
|
+
end
|
64
|
+
private :empty_inventory
|
65
|
+
|
66
|
+
def with_a_compiler
|
67
|
+
# If we're already inside a pal compiler block use that compiler
|
68
|
+
# This may blow up if you try to load a task in catalog pal. Should we
|
69
|
+
# guard against that?
|
70
|
+
compiler = nil
|
71
|
+
if defined?(Puppet)
|
72
|
+
begin
|
73
|
+
compiler = Puppet.lookup(:pal_compiler)
|
74
|
+
rescue Puppet::Context::UndefinedBindingError; end # rubocop:disable Lint/SuppressedException
|
75
|
+
end
|
76
|
+
|
77
|
+
if compiler
|
78
|
+
yield compiler
|
79
|
+
else
|
80
|
+
@pal.in_bolt_compiler do |temp_compiler|
|
81
|
+
yield temp_compiler
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
private :with_a_compiler
|
86
|
+
|
87
|
+
def get_validated_task(task_name, params = nil)
|
88
|
+
with_a_compiler do |compiler|
|
89
|
+
tasksig = compiler.task_signature(task_name)
|
90
|
+
|
91
|
+
raise Bolt::Error.unknown_task(task_name) unless tasksig
|
92
|
+
|
93
|
+
Bolt::Task::Run.validate_params(tasksig, params) if params
|
94
|
+
Bolt::Task.from_task_signature(tasksig)
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
def validate_params(task_name, params)
|
99
|
+
with_a_compiler do |compiler|
|
100
|
+
tasksig = compiler.task_signature(task_name)
|
101
|
+
|
102
|
+
raise Bolt::Error.new("#{task_name} could not be found", 'bolt/plugin-error') unless tasksig
|
103
|
+
|
104
|
+
Bolt::Task::Run.validate_params(tasksig, params)
|
105
|
+
end
|
106
|
+
nil
|
107
|
+
end
|
108
|
+
|
109
|
+
# By passing `_` keys in params the caller can send metaparams directly to the task
|
110
|
+
# _catch_errors must be passed as an executor option not a param
|
111
|
+
def run_local_task(task, params, options)
|
112
|
+
# Make sure we're in a compiler to use the sensitive type
|
113
|
+
with_a_compiler do |_comp|
|
114
|
+
params = Bolt::Task::Run.wrap_sensitive(task, params)
|
115
|
+
Bolt::Task::Run.run_task(
|
116
|
+
task,
|
117
|
+
empty_inventory.get_targets('localhost'),
|
118
|
+
params,
|
119
|
+
options,
|
120
|
+
serial_executor
|
121
|
+
)
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
def boltdir
|
126
|
+
@config.project.path
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
RUBY_PLUGINS = %w[task prompt env_var puppetdb puppet_connect_data].freeze
|
131
|
+
BUILTIN_PLUGINS = %w[task terraform pkcs7 prompt vault aws_inventory puppetdb azure_inventory
|
132
|
+
yaml env_var gcloud_inventory].freeze
|
133
|
+
DEFAULT_PLUGIN_HOOKS = { 'puppet_library' => { 'plugin' => 'puppet_agent', 'stop_service' => true } }.freeze
|
134
|
+
|
135
|
+
attr_reader :pal, :plugin_context
|
136
|
+
attr_writer :plugin_hooks
|
137
|
+
|
138
|
+
def initialize(config, pal, analytics = Bolt::Analytics::NoopClient.new, load_plugins: true)
|
139
|
+
@config = config
|
140
|
+
@analytics = analytics
|
141
|
+
@plugin_context = PluginContext.new(config, pal, self)
|
142
|
+
@plugins = {}
|
143
|
+
@pal = pal
|
144
|
+
@load_plugins = load_plugins
|
145
|
+
@unknown = Set.new
|
146
|
+
@resolution_stack = []
|
147
|
+
@unresolved_plugin_configs = config.plugins.dup
|
148
|
+
# The puppetdb plugin config comes from the puppetdb section, not from
|
149
|
+
# the plugins section
|
150
|
+
if @unresolved_plugin_configs.key?('puppetdb')
|
151
|
+
msg = "Configuration for the PuppetDB plugin must be in the 'puppetdb' config section, not 'plugins'"
|
152
|
+
raise Bolt::Error.new(msg, 'bolt/plugin-error')
|
153
|
+
end
|
154
|
+
@unresolved_plugin_configs['puppetdb'] = config.puppetdb.merge('default' => config.default_puppetdb,
|
155
|
+
'instances' => config.puppetdb_instances)
|
156
|
+
end
|
157
|
+
|
158
|
+
# Returns a map of configured plugin hooks. Any unresolved plugin references
|
159
|
+
# are resolved.
|
160
|
+
#
|
161
|
+
# @return [Hash[String, Hash]]
|
162
|
+
#
|
163
|
+
def plugin_hooks
|
164
|
+
@plugin_hooks ||= DEFAULT_PLUGIN_HOOKS.merge(resolve_references(@config.plugin_hooks))
|
165
|
+
end
|
166
|
+
|
167
|
+
def modules
|
168
|
+
@modules ||= Bolt::Module.discover(@pal.full_modulepath, @config.project)
|
169
|
+
end
|
170
|
+
|
171
|
+
def add_plugin(plugin)
|
172
|
+
@plugins[plugin.name] = plugin
|
173
|
+
end
|
174
|
+
|
175
|
+
def add_ruby_plugin(plugin_name)
|
176
|
+
cls_name = Bolt::Util.snake_name_to_class_name(plugin_name)
|
177
|
+
filename = "bolt/plugin/#{plugin_name}"
|
178
|
+
require filename
|
179
|
+
cls = Kernel.const_get("Bolt::Plugin::#{cls_name}")
|
180
|
+
opts = {
|
181
|
+
context: @plugin_context,
|
182
|
+
config: config_for_plugin(plugin_name)
|
183
|
+
}
|
184
|
+
|
185
|
+
plugin = cls.new(**opts)
|
186
|
+
add_plugin(plugin)
|
187
|
+
end
|
188
|
+
|
189
|
+
def add_module_plugin(plugin_name)
|
190
|
+
opts = {
|
191
|
+
context: @plugin_context,
|
192
|
+
# Make sure that the plugin's config is validated _before_ the unknown-plugin
|
193
|
+
# and loading-disabled checks. This way, we can fail early on invalid plugin
|
194
|
+
# config instead of _after_ loading the modulepath (which can be expensive).
|
195
|
+
config: config_for_plugin(plugin_name)
|
196
|
+
}
|
197
|
+
|
198
|
+
mod = modules[plugin_name]
|
199
|
+
|
200
|
+
plugin = Bolt::Plugin::Module.load(mod, opts)
|
201
|
+
add_plugin(plugin)
|
202
|
+
end
|
203
|
+
|
204
|
+
def config_for_plugin(plugin_name)
|
205
|
+
return {} unless @unresolved_plugin_configs.include?(plugin_name)
|
206
|
+
if @resolution_stack.include?(plugin_name)
|
207
|
+
msg = "Configuration for plugin '#{plugin_name}' depends on the plugin itself"
|
208
|
+
raise PluginError.new(msg, 'bolt/plugin-error')
|
209
|
+
else
|
210
|
+
@resolution_stack.push(plugin_name)
|
211
|
+
config = resolve_references(@unresolved_plugin_configs[plugin_name])
|
212
|
+
@unresolved_plugin_configs.delete(plugin_name)
|
213
|
+
@resolution_stack.pop
|
214
|
+
config
|
215
|
+
end
|
216
|
+
end
|
217
|
+
|
218
|
+
def known_plugin?(plugin_name)
|
219
|
+
@plugins.include?(plugin_name) ||
|
220
|
+
RUBY_PLUGINS.include?(plugin_name) ||
|
221
|
+
(modules.include?(plugin_name) && modules[plugin_name].plugin?)
|
222
|
+
end
|
223
|
+
|
224
|
+
def get_hook(plugin_name, hook)
|
225
|
+
plugin = by_name(plugin_name)
|
226
|
+
raise PluginError::Unknown, plugin_name unless plugin
|
227
|
+
raise PluginError::UnsupportedHook.new(plugin_name, hook) unless plugin.hooks.include?(hook)
|
228
|
+
@analytics.report_bundled_content("Plugin #{hook}", plugin_name)
|
229
|
+
|
230
|
+
plugin.method(hook)
|
231
|
+
end
|
232
|
+
|
233
|
+
# Calling by_name or get_hook will load any module based plugin automatically
|
234
|
+
def by_name(plugin_name)
|
235
|
+
if known_plugin?(plugin_name)
|
236
|
+
if @plugins.include?(plugin_name)
|
237
|
+
@plugins[plugin_name]
|
238
|
+
elsif !@load_plugins
|
239
|
+
raise PluginError::LoadingDisabled, plugin_name
|
240
|
+
elsif RUBY_PLUGINS.include?(plugin_name)
|
241
|
+
add_ruby_plugin(plugin_name)
|
242
|
+
else
|
243
|
+
add_module_plugin(plugin_name)
|
244
|
+
end
|
245
|
+
end
|
246
|
+
end
|
247
|
+
|
248
|
+
# Loads all plugins and returns a map of plugin names to hooks.
|
249
|
+
#
|
250
|
+
def list_plugins
|
251
|
+
load_all_plugins
|
252
|
+
|
253
|
+
hooks = KNOWN_HOOKS.map { |hook| [hook, {}] }.to_h
|
254
|
+
|
255
|
+
@plugins.sort.each do |name, plugin|
|
256
|
+
# Don't show the Puppet Connect plugin for now.
|
257
|
+
next if name == 'puppet_connect_data'
|
258
|
+
|
259
|
+
case plugin
|
260
|
+
when Bolt::Plugin::Module
|
261
|
+
plugin.hook_map.each do |hook, spec|
|
262
|
+
next unless hooks.include?(hook)
|
263
|
+
hooks[hook][name] = spec['task'].description
|
264
|
+
end
|
265
|
+
else
|
266
|
+
plugin.hook_descriptions.each do |hook, description|
|
267
|
+
hooks[hook][name] = description
|
268
|
+
end
|
269
|
+
end
|
270
|
+
end
|
271
|
+
|
272
|
+
hooks
|
273
|
+
end
|
274
|
+
|
275
|
+
# Loads all plugins available to the project.
|
276
|
+
#
|
277
|
+
private def load_all_plugins
|
278
|
+
modules.each do |name, mod|
|
279
|
+
next unless mod.plugin?
|
280
|
+
by_name(name)
|
281
|
+
end
|
282
|
+
|
283
|
+
RUBY_PLUGINS.each { |name| by_name(name) }
|
284
|
+
end
|
285
|
+
|
286
|
+
def puppetdb_client
|
287
|
+
by_name('puppetdb').puppetdb_client
|
288
|
+
end
|
289
|
+
|
290
|
+
# Evaluate all _plugin references in a data structure. Leaves are
|
291
|
+
# evaluated and then their parents are evaluated with references replaced
|
292
|
+
# by their values. If the result of a reference contains more references,
|
293
|
+
# they are resolved again before continuing to ascend the tree. The final
|
294
|
+
# result will not contain any references.
|
295
|
+
def resolve_references(data)
|
296
|
+
Bolt::Util.postwalk_vals(data) do |value|
|
297
|
+
reference?(value) ? resolve_references(resolve_single_reference(value)) : value
|
298
|
+
end
|
299
|
+
rescue SystemStackError
|
300
|
+
raise Bolt::Error.new("Stack depth exceeded while recursively resolving references.",
|
301
|
+
"bolt/recursive-reference-loop")
|
302
|
+
end
|
303
|
+
|
304
|
+
# Iteratively resolves "top-level" references until the result no longer
|
305
|
+
# has top-level references. A top-level reference is one which is not
|
306
|
+
# contained within another hash. It may be either the actual top-level
|
307
|
+
# result or arbitrarily nested within arrays. If parameters of the
|
308
|
+
# reference are themselves references, they will be looked. Any remaining
|
309
|
+
# references nested inside the result will *not* be evaluated once the
|
310
|
+
# top-level result is not a reference. This is used to resolve the
|
311
|
+
# `targets` and `groups` keys which are allowed to be references or
|
312
|
+
# arrays of references, but which may return data with nested references
|
313
|
+
# that should be resolved lazily. The end result will either be a single
|
314
|
+
# hash or a flat array of hashes.
|
315
|
+
def resolve_top_level_references(data)
|
316
|
+
if data.is_a?(Array)
|
317
|
+
data.flat_map { |elem| resolve_top_level_references(elem) }
|
318
|
+
elsif reference?(data)
|
319
|
+
partially_resolved = data.transform_values do |v|
|
320
|
+
resolve_references(v)
|
321
|
+
end
|
322
|
+
fully_resolved = resolve_single_reference(partially_resolved)
|
323
|
+
# The top-level reference may have returned more references, so repeat the process
|
324
|
+
resolve_top_level_references(fully_resolved)
|
325
|
+
else
|
326
|
+
data
|
327
|
+
end
|
328
|
+
end
|
329
|
+
|
330
|
+
# Evaluates a single reference. The value returned may be another
|
331
|
+
# reference.
|
332
|
+
def resolve_single_reference(reference)
|
333
|
+
plugin_cache = if cache?(reference)
|
334
|
+
cache = Bolt::Plugin::Cache.new(reference,
|
335
|
+
@config.project.plugin_cache_file,
|
336
|
+
@config.plugin_cache)
|
337
|
+
entry = cache.read_and_clean_cache
|
338
|
+
return entry unless entry.nil?
|
339
|
+
|
340
|
+
cache
|
341
|
+
end
|
342
|
+
|
343
|
+
plugin_name = reference['_plugin']
|
344
|
+
hook = get_hook(plugin_name, :resolve_reference)
|
345
|
+
|
346
|
+
begin
|
347
|
+
validate_proc = get_hook(plugin_name, :validate_resolve_reference)
|
348
|
+
rescue PluginError
|
349
|
+
validate_proc = proc { |*args| } # Nothing to do
|
350
|
+
end
|
351
|
+
|
352
|
+
validate_proc.call(reference)
|
353
|
+
|
354
|
+
result = begin
|
355
|
+
# Evaluate the plugin and then recursively evaluate any plugin returned by it.
|
356
|
+
hook.call(reference)
|
357
|
+
rescue StandardError => e
|
358
|
+
loc = "resolve_reference in #{plugin_name}"
|
359
|
+
raise PluginError::ExecutionError.new(e.message, plugin_name, loc)
|
360
|
+
end
|
361
|
+
|
362
|
+
plugin_cache.write_cache(result) if cache?(reference)
|
363
|
+
|
364
|
+
result
|
365
|
+
end
|
366
|
+
private :resolve_single_reference
|
367
|
+
|
368
|
+
private def cache?(reference)
|
369
|
+
reference.key?('_cache') || @config.plugin_cache.key?('ttl')
|
370
|
+
end
|
371
|
+
|
372
|
+
# Checks whether a given value is a _plugin reference
|
373
|
+
def reference?(input)
|
374
|
+
input.is_a?(Hash) && input.key?('_plugin')
|
375
|
+
end
|
376
|
+
end
|
377
|
+
end
|
378
|
+
|
379
|
+
# references PluginError
|
380
|
+
require_relative 'plugin/module'
|
data/lib/bolt/project.rb
ADDED
@@ -0,0 +1,219 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'pathname'
|
4
|
+
require_relative '../bolt/config'
|
5
|
+
require_relative '../bolt/validator'
|
6
|
+
require_relative '../bolt/pal'
|
7
|
+
require_relative '../bolt/module'
|
8
|
+
|
9
|
+
module Bolt
|
10
|
+
class Project
|
11
|
+
BOLTDIR_NAME = 'Boltdir'
|
12
|
+
CONFIG_NAME = 'bolt-project.yaml'
|
13
|
+
|
14
|
+
attr_reader :path, :data, :inventory_file, :hiera_config,
|
15
|
+
:puppetfile, :rerunfile, :type, :resource_types, :project_file,
|
16
|
+
:downloads, :plans_path, :modulepath, :managed_moduledir,
|
17
|
+
:backup_dir, :plugin_cache_file, :plan_cache_file, :task_cache_file,
|
18
|
+
:manifests
|
19
|
+
|
20
|
+
def self.default_project
|
21
|
+
create_project(File.expand_path(File.join('~', '.puppetlabs', 'bolt')), 'user')
|
22
|
+
# If homedir isn't defined use the system config path
|
23
|
+
rescue ArgumentError
|
24
|
+
create_project(Bolt::Config.system_path, 'system')
|
25
|
+
end
|
26
|
+
|
27
|
+
# Search recursively up the directory hierarchy for the Project. Look for a
|
28
|
+
# directory called Boltdir or a file called bolt-project.yaml (for a control
|
29
|
+
# repo type Project). Otherwise, repeat the check on each directory up the
|
30
|
+
# hierarchy, falling back to the default if we reach the root.
|
31
|
+
def self.find_boltdir(dir)
|
32
|
+
dir = Pathname.new(dir)
|
33
|
+
|
34
|
+
if (dir + BOLTDIR_NAME).directory?
|
35
|
+
create_project(dir + BOLTDIR_NAME, 'embedded')
|
36
|
+
elsif (dir + CONFIG_NAME).file?
|
37
|
+
create_project(dir, 'local')
|
38
|
+
elsif dir.root?
|
39
|
+
default_project
|
40
|
+
else
|
41
|
+
Bolt::Logger.debug(
|
42
|
+
"Did not detect Boltdir or bolt-project.yaml at '#{dir}'. This directory won't be loaded as a project."
|
43
|
+
)
|
44
|
+
find_boltdir(dir.parent)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def self.create_project(path, type = 'option')
|
49
|
+
fullpath = Pathname.new(path).expand_path
|
50
|
+
|
51
|
+
if type == 'user'
|
52
|
+
begin
|
53
|
+
# This is already expanded if the type is user
|
54
|
+
FileUtils.mkdir_p(path)
|
55
|
+
rescue StandardError
|
56
|
+
Bolt::Logger.warn(
|
57
|
+
"non_writeable_project",
|
58
|
+
"Could not create default project at #{path}. Continuing without a writeable project. "\
|
59
|
+
"Log and rerun files will not be written."
|
60
|
+
)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
if type == 'option' && !File.directory?(path)
|
65
|
+
raise Bolt::Error.new("Could not find project at #{path}", "bolt/project-error")
|
66
|
+
end
|
67
|
+
|
68
|
+
if !Bolt::Util.windows? && type != 'environment' && fullpath.world_writable?
|
69
|
+
raise Bolt::Error.new(
|
70
|
+
"Project directory '#{fullpath}' is world-writable which poses a security risk. Set "\
|
71
|
+
"BOLT_PROJECT='#{fullpath}' to force the use of this project directory.",
|
72
|
+
"bolt/world-writable-error"
|
73
|
+
)
|
74
|
+
end
|
75
|
+
|
76
|
+
project_file = File.join(fullpath, CONFIG_NAME)
|
77
|
+
data = Bolt::Util.read_optional_yaml_hash(File.expand_path(project_file), 'project')
|
78
|
+
default = type =~ /user|system/ ? 'default ' : ''
|
79
|
+
|
80
|
+
if File.exist?(File.expand_path(project_file))
|
81
|
+
Bolt::Logger.info("Loaded #{default}project from '#{fullpath}'")
|
82
|
+
end
|
83
|
+
|
84
|
+
Bolt::Validator.new.tap do |validator|
|
85
|
+
validator.validate(data, schema, project_file)
|
86
|
+
validator.warnings.each { |warning| Bolt::Logger.warn(warning[:id], warning[:msg]) }
|
87
|
+
validator.deprecations.each { |dep| Bolt::Logger.deprecate(dep[:id], dep[:msg]) }
|
88
|
+
end
|
89
|
+
|
90
|
+
new(data, path, type)
|
91
|
+
end
|
92
|
+
|
93
|
+
# Builds the schema for bolt-project.yaml used by the validator.
|
94
|
+
#
|
95
|
+
def self.schema
|
96
|
+
{
|
97
|
+
type: Hash,
|
98
|
+
properties: Bolt::Config::PROJECT_OPTIONS.map { |opt| [opt, _ref: opt] }.to_h,
|
99
|
+
definitions: Bolt::Config::OPTIONS
|
100
|
+
}
|
101
|
+
end
|
102
|
+
|
103
|
+
def initialize(data, path, type = 'option')
|
104
|
+
@type = type
|
105
|
+
@path = Pathname.new(path).expand_path
|
106
|
+
@project_file = @path + CONFIG_NAME
|
107
|
+
@inventory_file = @path + 'inventory.yaml'
|
108
|
+
@hiera_config = @path + 'hiera.yaml'
|
109
|
+
@puppetfile = @path + 'Puppetfile'
|
110
|
+
@rerunfile = @path + '.rerun.json'
|
111
|
+
@resource_types = @path + '.resource_types'
|
112
|
+
@downloads = @path + 'downloads'
|
113
|
+
@plans_path = @path + 'plans'
|
114
|
+
@managed_moduledir = @path + '.modules'
|
115
|
+
@backup_dir = @path + '.bolt-bak'
|
116
|
+
@plugin_cache_file = @path + '.plugin_cache.json'
|
117
|
+
@plan_cache_file = @path + '.plan_cache.json'
|
118
|
+
@task_cache_file = @path + '.task_cache.json'
|
119
|
+
@modulepath = [(@path + 'modules').to_s]
|
120
|
+
@manifests = @path + 'manifests'
|
121
|
+
|
122
|
+
if (tc = Bolt::Config::INVENTORY_OPTIONS.keys & data.keys).any?
|
123
|
+
Bolt::Logger.warn(
|
124
|
+
"project_transport_config",
|
125
|
+
"Transport configuration isn't supported in bolt-project.yaml. Ignoring keys #{tc}."
|
126
|
+
)
|
127
|
+
end
|
128
|
+
|
129
|
+
@data = data.slice(*Bolt::Config::PROJECT_OPTIONS)
|
130
|
+
|
131
|
+
if @data['rerunfile']
|
132
|
+
@rerunfile = File.expand_path(@data['rerunfile'], @path)
|
133
|
+
end
|
134
|
+
|
135
|
+
validate if project_file?
|
136
|
+
end
|
137
|
+
|
138
|
+
def to_s
|
139
|
+
@path.to_s
|
140
|
+
end
|
141
|
+
|
142
|
+
# This API is used to prepend the project as a module to Puppet's internal
|
143
|
+
# module_references list. CHANGE AT YOUR OWN RISK
|
144
|
+
def to_h
|
145
|
+
{ path: @path.to_s,
|
146
|
+
name: name,
|
147
|
+
load_as_module?: load_as_module? }
|
148
|
+
end
|
149
|
+
|
150
|
+
def eql?(other)
|
151
|
+
path == other.path
|
152
|
+
end
|
153
|
+
alias == eql?
|
154
|
+
|
155
|
+
def project_file?
|
156
|
+
@project_file.file?
|
157
|
+
end
|
158
|
+
|
159
|
+
def load_as_module?
|
160
|
+
!name.nil?
|
161
|
+
end
|
162
|
+
|
163
|
+
def name
|
164
|
+
@data['name']
|
165
|
+
end
|
166
|
+
|
167
|
+
def tasks
|
168
|
+
@data['tasks']
|
169
|
+
end
|
170
|
+
|
171
|
+
def plans
|
172
|
+
@data['plans']
|
173
|
+
end
|
174
|
+
|
175
|
+
def plugin_cache
|
176
|
+
@data['plugin-cache']
|
177
|
+
end
|
178
|
+
|
179
|
+
def module_install
|
180
|
+
@data['module-install']
|
181
|
+
end
|
182
|
+
|
183
|
+
def disable_warnings
|
184
|
+
@data['disable-warnings'] || []
|
185
|
+
end
|
186
|
+
|
187
|
+
def modules
|
188
|
+
mod_data = @data['modules'] || []
|
189
|
+
@modules ||= mod_data.map do |mod|
|
190
|
+
if mod.is_a?(String)
|
191
|
+
{ 'name' => mod }
|
192
|
+
else
|
193
|
+
mod
|
194
|
+
end
|
195
|
+
end
|
196
|
+
end
|
197
|
+
|
198
|
+
def validate
|
199
|
+
if name
|
200
|
+
if name !~ Bolt::Module::MODULE_NAME_REGEX
|
201
|
+
raise Bolt::ValidationError, <<~ERROR_STRING
|
202
|
+
Invalid project name '#{name}' in bolt-project.yaml; project name must begin with a lowercase letter
|
203
|
+
and can include lowercase letters, numbers, and underscores.
|
204
|
+
ERROR_STRING
|
205
|
+
elsif Dir.children(Bolt::Config::Modulepath::BOLTLIB_PATH).include?(name)
|
206
|
+
raise Bolt::ValidationError, "The project '#{name}' will not be loaded. The project name conflicts "\
|
207
|
+
"with a built-in Bolt module of the same name."
|
208
|
+
end
|
209
|
+
elsif name.nil? &&
|
210
|
+
(File.directory?(plans_path) ||
|
211
|
+
File.directory?(@path + 'tasks') ||
|
212
|
+
File.directory?(@path + 'files'))
|
213
|
+
message = "No project name is specified in bolt-project.yaml. Project-level content will not be available."
|
214
|
+
|
215
|
+
Bolt::Logger.warn("missing_project_name", message)
|
216
|
+
end
|
217
|
+
end
|
218
|
+
end
|
219
|
+
end
|
@@ -0,0 +1,113 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative '../../bolt/project_manager/migrator'
|
4
|
+
|
5
|
+
module Bolt
|
6
|
+
class ProjectManager
|
7
|
+
class ConfigMigrator < Migrator
|
8
|
+
def migrate(config_file, project_file, inventory_file, backup_dir)
|
9
|
+
bolt_yaml_to_bolt_project(config_file, project_file, inventory_file, backup_dir) &&
|
10
|
+
update_options(project_file)
|
11
|
+
end
|
12
|
+
|
13
|
+
private def bolt_yaml_to_bolt_project(config_file, project_file, inventory_file, backup_dir)
|
14
|
+
if File.exist?(project_file)
|
15
|
+
return true
|
16
|
+
end
|
17
|
+
|
18
|
+
unless File.exist?(config_file)
|
19
|
+
return true
|
20
|
+
end
|
21
|
+
|
22
|
+
@outputter.print_message "Migrating project configuration\n\n"
|
23
|
+
|
24
|
+
config_data = Bolt::Util.read_optional_yaml_hash(config_file, 'config')
|
25
|
+
transport_data, project_data = config_data.partition do |k, _|
|
26
|
+
Bolt::Config::INVENTORY_OPTIONS.keys.include?(k)
|
27
|
+
end.map(&:to_h)
|
28
|
+
|
29
|
+
if transport_data.any?
|
30
|
+
if File.exist?(inventory_file)
|
31
|
+
inventory_data = Bolt::Util.read_yaml_hash(inventory_file, 'inventory')
|
32
|
+
merged = Bolt::Util.deep_merge(transport_data, inventory_data['config'] || {})
|
33
|
+
inventory_data['config'] = merged
|
34
|
+
backup_file(inventory_file, backup_dir)
|
35
|
+
else
|
36
|
+
FileUtils.touch(inventory_file)
|
37
|
+
inventory_data = { 'config' => transport_data }
|
38
|
+
end
|
39
|
+
|
40
|
+
backup_file(config_file, backup_dir)
|
41
|
+
|
42
|
+
begin
|
43
|
+
@outputter.print_action_step(
|
44
|
+
"Moving transportation configuration options '#{transport_data.keys.join(', ')}' "\
|
45
|
+
"from bolt.yaml to inventory.yaml"
|
46
|
+
)
|
47
|
+
|
48
|
+
File.write(inventory_file, inventory_data.to_yaml)
|
49
|
+
File.write(config_file, project_data.to_yaml)
|
50
|
+
rescue StandardError => e
|
51
|
+
raise Bolt::FileError.new("#{e.message}; unable to write inventory.", inventory_file)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
@outputter.print_action_step("Renaming bolt.yaml to bolt-project.yaml")
|
56
|
+
FileUtils.mv(config_file, project_file)
|
57
|
+
|
58
|
+
command = Bolt::Util.powershell? ? 'Get-Help about_bolt_project' : 'bolt guide project'
|
59
|
+
@outputter.print_action_step(
|
60
|
+
"Successfully migrated config. Please add a 'name' key to bolt-project.yaml "\
|
61
|
+
"to use project-level tasks and plans. Learn more about projects by running "\
|
62
|
+
"'#{command}'."
|
63
|
+
)
|
64
|
+
|
65
|
+
true
|
66
|
+
end
|
67
|
+
|
68
|
+
private def update_options(project_file)
|
69
|
+
return true unless File.exist?(project_file)
|
70
|
+
|
71
|
+
@outputter.print_message("Updating project configuration options\n\n")
|
72
|
+
data = Bolt::Util.read_yaml_hash(project_file, 'config')
|
73
|
+
modified = false
|
74
|
+
|
75
|
+
# Keys to update. The first element is the old key, while the second is
|
76
|
+
# the key update it to.
|
77
|
+
to_update = [
|
78
|
+
%w[apply_settings apply-settings],
|
79
|
+
%w[puppetfile module-install],
|
80
|
+
%w[plugin_hooks plugin-hooks]
|
81
|
+
]
|
82
|
+
|
83
|
+
to_update.each do |old, new|
|
84
|
+
next unless data.key?(old)
|
85
|
+
|
86
|
+
if data.key?(new)
|
87
|
+
@outputter.print_action_step("Removing deprecated option '#{old}'")
|
88
|
+
data.delete(old)
|
89
|
+
else
|
90
|
+
@outputter.print_action_step("Updating deprecated option '#{old}' to '#{new}'")
|
91
|
+
data[new] = data.delete(old)
|
92
|
+
end
|
93
|
+
|
94
|
+
modified = true
|
95
|
+
end
|
96
|
+
|
97
|
+
if modified
|
98
|
+
begin
|
99
|
+
File.write(project_file, data.to_yaml)
|
100
|
+
rescue StandardError => e
|
101
|
+
raise Bolt::FileError.new("#{e.message}; unable to write config.", project_file)
|
102
|
+
end
|
103
|
+
|
104
|
+
@outputter.print_action_step("Successfully updated project configuration #{project_file}")
|
105
|
+
else
|
106
|
+
@outputter.print_action_step("Project configuration is up to date, nothing to do.")
|
107
|
+
end
|
108
|
+
|
109
|
+
true
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|