Class: Bolt::Plugin
- Inherits:
-
Object
- Object
- Bolt::Plugin
- Defined in:
- lib/bolt/plugin.rb,
lib/bolt/plugin/task.rb,
lib/bolt/plugin/module.rb,
lib/bolt/plugin/prompt.rb,
lib/bolt/plugin/env_var.rb,
lib/bolt/plugin/puppetdb.rb
Defined Under Namespace
Classes: EnvVar, Module, PluginContext, PluginError, Prompt, Puppetdb, Task
Constant Summary collapse
- KNOWN_HOOKS =
%i[ puppet_library resolve_reference secret_encrypt secret_decrypt secret_createkeys validate_resolve_reference ].freeze
- RUBY_PLUGINS =
%w[task prompt env_var puppetdb].freeze
- BUILTIN_PLUGINS =
%w[task terraform pkcs7 prompt vault aws_inventory puppetdb azure_inventory yaml env_var gcloud_inventory].freeze
- DEFAULT_PLUGIN_HOOKS =
{ 'puppet_library' => { 'plugin' => 'puppet_agent', 'stop_service' => true } }.freeze
Instance Attribute Summary collapse
-
#pal ⇒ Object
readonly
Returns the value of attribute pal.
-
#plugin_context ⇒ Object
readonly
Returns the value of attribute plugin_context.
-
#plugin_hooks ⇒ Object
Returns the value of attribute plugin_hooks.
Class Method Summary collapse
Instance Method Summary collapse
- #add_module_plugin(plugin_name) ⇒ Object
- #add_plugin(plugin) ⇒ Object
- #add_ruby_plugin(plugin_name) ⇒ Object
-
#by_name(plugin_name) ⇒ Object
Calling by_name or get_hook will load any module based plugin automatically.
- #config_for_plugin(plugin_name) ⇒ Object
- #get_hook(plugin_name, hook) ⇒ Object
-
#initialize(config, pal, analytics) ⇒ Plugin
constructor
A new instance of Plugin.
- #modules ⇒ Object
- #puppetdb_client ⇒ Object
-
#reference?(input) ⇒ Boolean
Checks whether a given value is a _plugin reference.
-
#resolve_references(data) ⇒ Object
Evaluate all _plugin references in a data structure.
-
#resolve_top_level_references(data) ⇒ Object
Iteratively resolves “top-level” references until the result no longer has top-level references.
Constructor Details
#initialize(config, pal, analytics) ⇒ Plugin
Returns a new instance of Plugin.
151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 |
# File 'lib/bolt/plugin.rb', line 151 def initialize(config, pal, analytics) @config = config @analytics = analytics @plugin_context = PluginContext.new(config, pal, self) @plugins = {} @pal = pal @unknown = Set.new @resolution_stack = [] @unresolved_plugin_configs = config.plugins.dup # The puppetdb plugin config comes from the puppetdb section, not from # the plugins section if @unresolved_plugin_configs.key?('puppetdb') msg = "Configuration for the PuppetDB plugin must be in the 'puppetdb' config section, not 'plugins'" raise Bolt::Error.new(msg, 'bolt/plugin-error') end @unresolved_plugin_configs['puppetdb'] = config.puppetdb if config.puppetdb @plugin_hooks = DEFAULT_PLUGIN_HOOKS.dup end |
Instance Attribute Details
#pal ⇒ Object (readonly)
Returns the value of attribute pal.
146 147 148 |
# File 'lib/bolt/plugin.rb', line 146 def pal @pal end |
#plugin_context ⇒ Object (readonly)
Returns the value of attribute plugin_context.
146 147 148 |
# File 'lib/bolt/plugin.rb', line 146 def plugin_context @plugin_context end |
#plugin_hooks ⇒ Object
Returns the value of attribute plugin_hooks.
147 148 149 |
# File 'lib/bolt/plugin.rb', line 147 def plugin_hooks @plugin_hooks end |
Class Method Details
.setup(config, pal, analytics = Bolt::Analytics::NoopClient.new) ⇒ Object
122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 |
# File 'lib/bolt/plugin.rb', line 122 def self.setup(config, pal, analytics = Bolt::Analytics::NoopClient.new) plugins = new(config, pal, analytics) # Initialize any plugins referenced in plugin config. This will also indirectly # initialize any plugins they depend on. if plugins.reference?(config.plugins) msg = "The 'plugins' setting cannot be set by a plugin reference" raise PluginError.new(msg, 'bolt/plugin-error') end config.plugins.each_key do |plugin| plugins.by_name(plugin) end plugins.plugin_hooks.merge!(plugins.resolve_references(config.plugin_hooks)) plugins end |
Instance Method Details
#add_module_plugin(plugin_name) ⇒ Object
192 193 194 195 196 197 198 199 200 |
# File 'lib/bolt/plugin.rb', line 192 def add_module_plugin(plugin_name) opts = { context: @plugin_context, config: config_for_plugin(plugin_name) } plugin = Bolt::Plugin::Module.load(plugin_name, modules, opts) add_plugin(plugin) end |
#add_plugin(plugin) ⇒ Object
174 175 176 |
# File 'lib/bolt/plugin.rb', line 174 def add_plugin(plugin) @plugins[plugin.name] = plugin end |
#add_ruby_plugin(plugin_name) ⇒ Object
178 179 180 181 182 183 184 185 186 187 188 189 190 |
# File 'lib/bolt/plugin.rb', line 178 def add_ruby_plugin(plugin_name) cls_name = Bolt::Util.snake_name_to_class_name(plugin_name) filename = "bolt/plugin/#{plugin_name}" require filename cls = Kernel.const_get("Bolt::Plugin::#{cls_name}") opts = { context: @plugin_context, config: config_for_plugin(plugin_name) } plugin = cls.new(**opts) add_plugin(plugin) end |
#by_name(plugin_name) ⇒ Object
Calling by_name or get_hook will load any module based plugin automatically
226 227 228 229 230 231 232 233 234 235 236 237 238 |
# File 'lib/bolt/plugin.rb', line 226 def by_name(plugin_name) return @plugins[plugin_name] if @plugins.include?(plugin_name) begin if RUBY_PLUGINS.include?(plugin_name) add_ruby_plugin(plugin_name) elsif !@unknown.include?(plugin_name) add_module_plugin(plugin_name) end rescue PluginError::Unknown @unknown << plugin_name nil end end |
#config_for_plugin(plugin_name) ⇒ Object
202 203 204 205 206 207 208 209 210 211 212 213 214 |
# File 'lib/bolt/plugin.rb', line 202 def config_for_plugin(plugin_name) return {} unless @unresolved_plugin_configs.include?(plugin_name) if @resolution_stack.include?(plugin_name) msg = "Configuration for plugin '#{plugin_name}' depends on the plugin itself" raise PluginError.new(msg, 'bolt/plugin-error') else @resolution_stack.push(plugin_name) config = resolve_references(@unresolved_plugin_configs[plugin_name]) @unresolved_plugin_configs.delete(plugin_name) @resolution_stack.pop config end end |
#get_hook(plugin_name, hook) ⇒ Object
216 217 218 219 220 221 222 223 |
# File 'lib/bolt/plugin.rb', line 216 def get_hook(plugin_name, hook) plugin = by_name(plugin_name) raise PluginError::Unknown, plugin_name unless plugin raise PluginError::UnsupportedHook.new(plugin_name, hook) unless plugin.hooks.include?(hook) @analytics.report_bundled_content("Plugin #{hook}", plugin_name) plugin.method(hook) end |
#modules ⇒ Object
170 171 172 |
# File 'lib/bolt/plugin.rb', line 170 def modules @modules ||= Bolt::Module.discover(@pal.modulepath) end |
#puppetdb_client ⇒ Object
240 241 242 |
# File 'lib/bolt/plugin.rb', line 240 def puppetdb_client by_name('puppetdb').puppetdb_client end |
#reference?(input) ⇒ Boolean
Checks whether a given value is a _plugin reference
309 310 311 |
# File 'lib/bolt/plugin.rb', line 309 def reference?(input) input.is_a?(Hash) && input.key?('_plugin') end |
#resolve_references(data) ⇒ Object
Evaluate all _plugin references in a data structure. Leaves are evaluated and then their parents are evaluated with references replaced by their values. If the result of a reference contains more references, they are resolved again before continuing to ascend the tree. The final result will not contain any references.
249 250 251 252 253 254 255 256 |
# File 'lib/bolt/plugin.rb', line 249 def resolve_references(data) Bolt::Util.postwalk_vals(data) do |value| reference?(value) ? resolve_references(resolve_single_reference(value)) : value end rescue SystemStackError raise Bolt::Error.new("Stack depth exceeded while recursively resolving references.", "bolt/recursive-reference-loop") end |
#resolve_top_level_references(data) ⇒ Object
Iteratively resolves “top-level” references until the result no longer has top-level references. A top-level reference is one which is not contained within another hash. It may be either the actual top-level result or arbitrarily nested within arrays. If parameters of the reference are themselves references, they will be looked. Any remaining references nested inside the result will not be evaluated once the top-level result is not a reference. This is used to resolve the ‘targets` and `groups` keys which are allowed to be references or arrays of references, but which may return data with nested references that should be resolved lazily. The end result will either be a single hash or a flat array of hashes.
269 270 271 272 273 274 275 276 277 278 279 280 281 282 |
# File 'lib/bolt/plugin.rb', line 269 def resolve_top_level_references(data) if data.is_a?(Array) data.flat_map { |elem| resolve_top_level_references(elem) } elsif reference?(data) partially_resolved = data.transform_values do |v| resolve_references(v) end fully_resolved = resolve_single_reference(partially_resolved) # The top-level reference may have returned more references, so repeat the process resolve_top_level_references(fully_resolved) else data end end |