class MotherBrain::Plugin

Constants

NODE_GROUP_ID_REGX
PLUGIN_FILENAME

Attributes

commands[R]

@return [Set<MB::Command>]

components[R]

@return [Set<MB::Component>]

cookbook_versions[R]

@return [Hash<String, String>]

metadata[R]

@return [MB::CookbookMetadata]

Public Class Methods

from_path(path) click to toggle source

Load the contents of a directory into an instance of MB::Plugin

The cookbook dependencies of this plugin will be loaded from the Berksfile.lock if it is found.

@param [#to_s] path

a path to a directory containing a motherbrain plugin file and cookbook
metadata file

@raise [PluginLoadError]

@return [MotherBrain::Plugin]

# File lib/mb/plugin.rb, line 32
def from_path(path)
  unless Dir.has_mb_plugin?(path)
    raise PluginLoadError, "Expected a motherbrain and metadata file at: #{path}"
  end

  plugin_filename = File.join(path, PLUGIN_FILENAME)
  plugin_contents = File.read(plugin_filename)
  metadata        = CookbookMetadata.from_path(path)
  berksfile_lock  = Berkshelf::Lockfile.from_path(path)

  load(metadata, berksfile_lock.locked_versions) { eval(plugin_contents, binding, plugin_filename, 1) }
rescue PluginSyntaxError => ex
  raise PluginSyntaxError, ErrorHandler.new(ex, file_path: plugin_filename).message
end
key_for(name, version) click to toggle source
# File lib/mb/plugin.rb, line 47
def key_for(name, version)
  "#{name}-#{version}".to_sym
end
load(metadata, cookbook_versions = {}, &block) click to toggle source

Create a new plugin instance from the given content

@param [MB::CookbookMetadata] metadata @param [Hash<String, String>] cookbook_versions

The cookbook dependencies which this plugin depends on. Key is
the cookbook name and the value is the version of the cookbook.

@raise [PluginLoadError]

@yieldreturn [MotherBrain::Plugin]

# File lib/mb/plugin.rb, line 14
def load(metadata, cookbook_versions = {}, &block)
  new(metadata, cookbook_versions, &block).validate!
rescue PluginSyntaxError => ex
  ErrorHandler.wrap(ex)
end
new(metadata, cookbook_versions = {}, &block) click to toggle source

@param [MB::CookbookMetadata] metadata @param [Hash<String, String>] cookbook_versions

The cookbook dependencies which this plugin depends on. Key is
the cookbook name and the value is the version of the cookbook.
# File lib/mb/plugin.rb, line 83
def initialize(metadata, cookbook_versions = {}, &block)
  @metadata          = metadata
  @cookbook_versions = cookbook_versions
  @components        = Set.new
  @commands          = Set.new

  if block_given?
    dsl_eval(&block)
  end
end

Public Instance Methods

<=>(other) click to toggle source
# File lib/mb/plugin.rb, line 245
def <=>(other)
  unless other.is_a?(self.class)
    return 0
  end

  if self.name == other.name
    self.version <=> other.version
  else
    self.name <=> other.name
  end
end
add_command(command) click to toggle source

@param [MB::Command] command

# File lib/mb/plugin.rb, line 208
def add_command(command)
  self.commands.add(command)
end
add_component(component) click to toggle source

@param [MB::Component] component

# File lib/mb/plugin.rb, line 203
def add_component(component)
  self.components.add(component)
end
as_json(options = {})
Alias for: to_json
command(name) click to toggle source

Return a command from the plugins list of commands.

@param [#to_s] name

name of the command to find and return

@return [MB::Command, nil]

# File lib/mb/plugin.rb, line 134
def command(name)
  commands.find { |command| command.name == name.to_s }
end
command!(name) click to toggle source

Return a command from the plugin’s list of commands. If a command is not found an exception will be rasied.

@param [#to_s] name

name of the command to find and return

@raise [CommandNotFound] if a command matching the given name is not found on this plugin

@return [MB::Command]

# File lib/mb/plugin.rb, line 146
def command!(name)
  found = command(name)

  if found.nil?
    raise CommandNotFound.new(name, self)
  end

  found
end
component(name) click to toggle source

@param [#to_s] name

@return [MB::Component, nil]

# File lib/mb/plugin.rb, line 102
def component(name)
  components.find { |component| component.name == name.to_s }
end
component!(name) click to toggle source

@param [#to_s] name

@raise [ComponentNotFound] if a component of the given name is not a part of this plugin

@return [MB::Component]

# File lib/mb/plugin.rb, line 111
def component!(name)
  component = component(name)

  if component.nil?
    raise ComponentNotFound.new(name, self)
  end

  component
end
eql?(other) click to toggle source
# File lib/mb/plugin.rb, line 257
def eql?(other)
  other.is_a?(self.class) && self == other
end
has_component?(name) click to toggle source

@param [#to_s] name

@return [Boolean]

# File lib/mb/plugin.rb, line 124
def has_component?(name)
  component(name).present?
end
id() click to toggle source

@return [Symbol]

# File lib/mb/plugin.rb, line 95
def id
  self.class.key_for(self.name, self.version)
end
messages_from_errors(errors) click to toggle source

Creates an error message from an error hash, where the keys are attributes and the values are an array of error messages.

@param [Hash] errors

@return [String]

# File lib/mb/plugin.rb, line 235
def messages_from_errors(errors)
  buffer = []

  errors.each do |attribute, messages|
    buffer |= messages
  end

  buffer.join "\n"
end
nodes(environment) click to toggle source

Finds the nodes for the given environment for each {Component} of the plugin groups them by Component#name and Group#name into a Hash where the keys are Component#name and values are a hash where the keys are Group#name and the values are a Hash representing a node from Chef.

@param [#to_s] environment

@raise [MB::EnvironmentNotFound] if the target environment does not exist @raise [MB::ChefConnectionError] if there was an error communicating to the Chef Server

@example

{
  "activemq" => {
    database_masters" => [
      {
        "name" => "db-master1",
        ...
      }
    ],
    "database_slaves" => [
      {
        "name" => "db-slave1",
        ...
      },
      {
        "name" => "db-slave2",
        ...
      }
    ]
  }
}

@return [Hash]

# File lib/mb/plugin.rb, line 190
def nodes(environment)
  unless Application.ridley.environment.find(environment)
    raise EnvironmentNotFound.new(environment)
  end

  {}.tap do |nodes|
    self.components.each do |component|
      nodes[component.name] = component.nodes(environment)
    end
  end
end
to_hash() click to toggle source
# File lib/mb/plugin.rb, line 265
def to_hash
  {
    name: name,
    version: version,
    maintainer: maintainer,
    maintainer_email: maintainer_email,
    description: description,
    long_description: long_description
  }
end
to_json(options = {}) click to toggle source

@param [Hash] options

a set of options to pass to MultiJson.encode

@return [String]

# File lib/mb/plugin.rb, line 280
def to_json(options = {})
  MultiJson.encode(self.to_hash, options)
end
Also aliased as: as_json
to_s() click to toggle source
# File lib/mb/plugin.rb, line 261
def to_s
  "#{self.name} (#{self.version})"
end
validate!() click to toggle source

Completely validate a loaded plugin and raise an exception of errors

@return [self]

# File lib/mb/plugin.rb, line 215
def validate!
  errors = validate

  if errors.any?
    ErrorHandler.wrap PluginSyntaxError,
      backtrace: [],
      plugin_name: try(:name),
      plugin_version: try(:version),
      text: messages_from_errors(errors)
  end

  self
end

Private Instance Methods

dsl_eval(&block) click to toggle source
# File lib/mb/plugin.rb, line 287
def dsl_eval(&block)
  CleanRoom.new(self).instance_eval(&block)
end