class MCollective::Application::Plugin

Public Instance Methods

doc_command() click to toggle source

Show application list and plugin help

# File lib/mcollective/application/plugin.rb, line 226
def doc_command
  known_plugin_types = [["Agents", :agent], ["Aggregate", :aggregate],
                        ["Connectors", :connector], ["Data Queries", :data],
                        ["Discovery Methods", :discovery], ["Validator Plugins", :validator]]

  if configuration.include?(:target) && configuration[:target] != "."
    if configuration[:target] =~ /^(.+?)\/(.+)$/
      ddl = load_plugin_ddl($2.to_sym, $1)
    else
      found_plugin_type = nil

      known_plugin_types.each do |plugin_type|
        PluginManager.find(plugin_type[1], "ddl").each do |ddl|
          pluginname = ddl.gsub(/_#{plugin_type[1]}$/, "")
          if pluginname == configuration[:target]
            abort "Duplicate plugin name found, please specify a full path like agent/rpcutil" if found_plugin_type
            found_plugin_type = plugin_type[1]
          end
        end
      end

      abort "Could not find a plugin named '%s' in any supported plugin type" % configuration[:target] unless found_plugin_type
      ddl = load_plugin_ddl(configuration[:target], found_plugin_type)
    end

    if ddl
      puts ddl.help(configuration[:rpctemplate])
    else
      abort "Could not find a '%s' plugin named '%s'" % configuration[:target].split('/')
    end

  else
    puts "Please specify a plugin. Available plugins are:"
    puts

    load_errors = []

    known_plugin_types.each do |plugin_type|
      puts "%s:" % plugin_type[0]

      PluginManager.find(plugin_type[1], "ddl").each do |ddl|
        begin
          help = DDL.new(ddl, plugin_type[1])
          pluginname = ddl.gsub(/_#{plugin_type[1]}$/, "")
          puts "  %-25s %s" % [pluginname, help.meta[:description]]
        rescue => e
          load_errors << [plugin_type[1], ddl, e]
        end
      end

      puts
    end

    unless load_errors.empty?
      puts "Plugin Load Errors:"

      load_errors.each do |e|
        puts "  %-25s %s" % ["#{e[0]}/#{e[1]}", Util.colorize(:yellow, e[2])]
      end
    end
  end
end
generate_command() click to toggle source

Generate a plugin skeleton

# File lib/mcollective/application/plugin.rb, line 170
def generate_command
  raise "undefined plugin type. cannot generate plugin. valid types are 'agent' and 'data'" if configuration["target"] == '.'

  unless configuration[:pluginname]
    puts "No plugin name specified. Using 'new_plugin'"
    configuration[:pluginname] = "new_plugin"
  end

  load_plugin_config_values

  case configuration[:target].downcase
  when 'agent'
    Generators::AgentGenerator.new(configuration[:pluginname], configuration[:actions], configuration[:pluginname],
                                   configuration[:description], configuration[:author], configuration[:license],
                                   configuration[:version], configuration[:url], configuration[:timeout])
  when 'data'
    raise "data plugin must have at least one output" unless configuration[:outputs]
    Generators::DataGenerator.new(configuration[:pluginname], configuration[:outputs], configuration[:pluginname],
                                   configuration[:description], configuration[:author], configuration[:license],
                                   configuration[:version], configuration[:url], configuration[:timeout])
  else
    raise "invalid plugin type. cannot generate plugin '#{configuration[:target]}'"
  end
end
identify_plugin() click to toggle source

If plugintype is StandardDefinition, identify which of the special plugin types we are dealing with based on directory structure. To keep it simple we limit it to one type per target directory. Return the name of the type of plugin as a string

# File lib/mcollective/application/plugin.rb, line 334
def identify_plugin
  plugintype = Dir.glob(File.join(configuration[:target], "*")).select do |file|
    File.directory?(file) && file.match(/(connector|facts|registration|security|audit|pluginpackager|data|discovery|validator)/)
  end

  raise RuntimeError, "more than one plugin type detected in directory" if plugintype.size > 1
  raise RuntimeError, "no plugins detected in directory" if plugintype.size < 1

  File.basename(plugintype[0])
end
info_command() click to toggle source

Display info about plugin

# File lib/mcollective/application/plugin.rb, line 163
def info_command
  plugin = prepare_plugin
  packager = PluginPackager["#{configuration[:format].capitalize}Packager"]
  packager.new(plugin).package_information
end
load_plugin_config_values() click to toggle source

Load preset metadata values from config if they are present This makes it possible to override metadata values in a local client config file.

Example : plugin.metadata.license = Apache 2

# File lib/mcollective/application/plugin.rb, line 350
def load_plugin_config_values
  config = Config.instance
  [:pluginname, :description, :author, :license, :version, :url, :timeout].each do |confoption|
    configuration[confoption] = config.pluginconf["metadata.#{confoption}"] unless configuration[confoption]
  end
end
load_plugin_ddl(plugin, type) click to toggle source

Agents are just called 'agent' but newer plugin types are called plugin_plugintype for example facter_facts etc so this will first try the old way then the new way.

# File lib/mcollective/application/plugin.rb, line 213
def load_plugin_ddl(plugin, type)
  [plugin, "#{plugin}_#{type}"].each do |p|
    ddl = DDL.new(p, type, false)
    if ddl.findddlfile(p, type)
      ddl.loadddlfile
      return ddl
    end
  end

  return nil
end
main() click to toggle source
# File lib/mcollective/application/plugin.rb, line 357
def main
    abort "No action specified, please run 'mco help plugin' for help" unless configuration.include?(:action)

    cmd = "#{configuration[:action]}_command"

    if respond_to? cmd
      send cmd
    else
      abort "Invalid action #{configuration[:action]}, please run 'mco help plugin' for help."
    end
end
package_command() click to toggle source

Package plugin

# File lib/mcollective/application/plugin.rb, line 196
def package_command
  if configuration[:sign] && Config.instance.pluginconf.include?("debian_packager.keyname")
    configuration[:sign] = Config.instance.pluginconf["debian_packager.keyname"]
    configuration[:sign] = "\"#{configuration[:sign]}\"" unless configuration[:sign].match(/\".*\"/)
  end

  plugin = prepare_plugin
  (configuration[:pluginpath] = configuration[:pluginpath] + "/") if (configuration[:pluginpath] && !configuration[:pluginpath].match(/^.*\/$/))
  packager = PluginPackager["#{configuration[:format].capitalize}Packager"]
  packager.new(plugin, configuration[:pluginpath], configuration[:sign],
               options[:verbose], configuration[:keep_artifacts],
               configuration[:module_template]).create_packages
end
plugin_directory_exists?(plugin_type) click to toggle source
# File lib/mcollective/application/plugin.rb, line 313
def plugin_directory_exists?(plugin_type)
  File.directory?(File.join(PluginPackager.get_plugin_path(configuration[:target]), plugin_type))
end
post_option_parser(configuration) click to toggle source

Handle alternative format that optparser can't parse.

# File lib/mcollective/application/plugin.rb, line 136
def post_option_parser(configuration)
  if ARGV.length >= 1
    configuration[:action] = ARGV.delete_at(0)

    configuration[:target] = ARGV.delete_at(0) || "."

    if configuration[:action] == "generate"
      unless ARGV[0] && ARGV[0].match(/(actions|outputs)=(.+)/)
        unless configuration[:pluginname]
          configuration[:pluginname] = ARGV.delete_at(0)
        else
          ARGV.delete_at(0)
        end
      end

      ARGV.each do |argument|
        if argument.match(/(actions|outputs)=(.+)/)
          configuration[$1.downcase.to_sym]= $2.split(",")
        else
          raise "Could not parse --arg '#{argument}'"
        end
      end
    end
  end
end
prepare_plugin() click to toggle source

Creates the correct package plugin object.

# File lib/mcollective/application/plugin.rb, line 290
def prepare_plugin
  plugintype = set_plugin_type unless configuration[:plugintype]
  configuration[:format] = "ospackage" unless configuration[:format]
  PluginPackager.load_packagers
  plugin_class = PluginPackager[configuration[:plugintype]]

  if configuration[:dependency] && configuration[:dependency].size == 1
    configuration[:dependency] = configuration[:dependency][0].split(" ")
  elsif configuration[:dependency]
    configuration[:dependency].map!{|dep| {:name => dep, :version => nil}}
  end

  mcdependency = {:mcname => configuration[:mcname], :mcversion => configuration[:mcversion]}

  # Deprecation warning for --iteration
  if configuration[:iteration]
    puts 'Warning. The --iteration flag has been deprecated. Please use --revision instead.'
    configuration[:revision] = configuration[:iteration] unless configuration[:revision]
  end

  plugin_class.new(configuration, mcdependency, plugintype)
end
set_plugin_type() click to toggle source

Identify plugin type if not provided.

# File lib/mcollective/application/plugin.rb, line 318
def set_plugin_type
  if plugin_directory_exists?("agent") || plugin_directory_exists?("application")
    configuration[:plugintype] = "AgentDefinition"
    return "Agent"
  elsif plugin_directory_exists?(plugintype = identify_plugin)
    configuration[:plugintype] = "StandardDefinition"
    return plugintype
  else
    raise RuntimeError, "target directory is not a valid mcollective plugin"
  end
end