class MCollective::DDL::Base - mcollective version 2.12.5

# class MCollective::DDL::Base

The base class for all kinds of `DDL` files. `DDL` files when run gets parsed and builds up a hash of the basic primitive types, ideally restricted so it can be converted to JSON though today there are some Ruby Symbols in them which might be fixed laster on.

The Hash being built should be stored in @entities, the format is generally not prescribed but there's a definite feel to how `DDL` files look so study the agent and discovery ones to see how the structure applies to very different use cases.

For every plugin type you should have a single word name - that corresponds to the directory in the libdir where these plugins live. If you need anything above and beyond 'metadata' in your plugin `DDL` then add a PlugintypeDDL class here and add your specific behaviors to those.

### Attributes

entities[R]
meta[R]
pluginname[R]
plugintype[R]
requirements[R]
usage[R]

### Public Class Methods

new(plugin, plugintype=:agent, loadddl=true) click to toggle source

       # File lib/mcollective/ddl/base.rb
    22 def initialize(plugin, plugintype=:agent, loadddl=true)
    23   @entities = {}
    24   @meta = {}
    25   @usage = ""
    26   @config = Config.instance
    27   @pluginname = plugin
    28   @plugintype = plugintype.to_sym
    29   @requirements = {}
    30
    31   loadddlfile if loadddl
    32 end

### Public Instance Methods

findddlfile(ddlname=nil, ddltype=nil) click to toggle source

       # File lib/mcollective/ddl/base.rb
    87 def findddlfile(ddlname=nil, ddltype=nil)
    88   ddlname = @pluginname unless ddlname
    89   ddltype = @plugintype unless ddltype
    90
    91   @config.libdir.each do |libdir|
    92     ddlfile = File.join([libdir, "mcollective", ddltype.to_s, "#{ddlname}.ddl"])
    93     if File.exist?(ddlfile)
    94       Log.debug("Found #{ddlname} ddl at #{ddlfile}")
    95       return ddlfile
    96     end
    97   end
    98   return false
    99 end

help(template=nil) click to toggle source

Generates help using the template based on the data created with metadata and input.

If no template name is provided one will be chosen based on the plugin type. If the provided template path is not absolute then the template will be loaded either from the config dir and if that does not exist, default to /etc/mcollective

       # File lib/mcollective/ddl/base.rb
    42 def help(template=nil)
    43   template = template_for_plugintype unless template
    44   template = Util.templatepath(template) unless Util.absolute_path?(template)
    45
    46   template = File.read(template)
    47   meta = @meta
    48   entities = @entities
    49
    50   unless template == "metadata-help.erb"
    51     metadata_template = Util.templatepath("metadata-help.erb")
    52     metadata_template = File.read(metadata_template)
    53     metastring = ERB.new(metadata_template, 0, '%')
    54     metastring = metastring.result(binding)
    55   end
    56
    57   erb = ERB.new(template, 0, '%')
    58   erb.result(binding)
    59 end

input(argument, properties) click to toggle source

Registers an input argument for a given action

See the documentation for action for how to use this

        # File lib/mcollective/ddl/base.rb
    146 def input(argument, properties)
    147   raise "Cannot figure out what entity input #{argument} belongs to" unless @current_entity
    148
    149   entity = @current_entity
    150
    151   [:prompt, :description, :type].each do |arg|
    152     raise "Input needs a :#{arg} property" unless properties.include?(arg)
    153   end
    154
    155   @entities[entity][:input][argument] = {:prompt => properties[:prompt],
    156                                          :description => properties[:description],
    157                                          :type => properties[:type],
    158                                          :default => properties[:default],
    159                                          :optional => properties[:optional]}
    160
    161   case properties[:type]
    162     when :string
    163       raise "Input type :string needs a :validation argument" unless properties.include?(:validation)
    164       raise "Input type :string needs a :maxlength argument" unless properties.include?(:maxlength)
    165
    166       @entities[entity][:input][argument][:validation] = properties[:validation]
    167       @entities[entity][:input][argument][:maxlength] = properties[:maxlength]
    168
    169     when :list
    170       raise "Input type :list needs a :list argument" unless properties.include?(:list)
    171
    172       @entities[entity][:input][argument][:list] = properties[:list]
    173   end
    174 end

loadddlfile() click to toggle source

       # File lib/mcollective/ddl/base.rb
    79 def loadddlfile
    80   if ddlfile = findddlfile
    81     instance_eval(File.read(ddlfile), ddlfile, 1)
    82   else
    83     raise("Can't find DDL for #{@plugintype} plugin '#{@pluginname}'")
    84   end
    85 end

metadata(meta) click to toggle source

Registers meta data for the introspection hash

        # File lib/mcollective/ddl/base.rb
    208 def metadata(meta)
    209   [:name, :description, :author, :license, :version, :url, :timeout].each do |arg|
    210     raise "Metadata needs a :#{arg} property" unless meta.include?(arg)
    211   end
    212
    213   @meta = meta
    214 end

output(argument, properties) click to toggle source

Registers an output argument for a given action

See the documentation for action for how to use this

        # File lib/mcollective/ddl/base.rb
    179 def output(argument, properties)
    180   raise "Cannot figure out what action input #{argument} belongs to" unless @current_entity
    181   raise "Output #{argument} needs a description argument" unless properties.include?(:description)
    182   raise "Output #{argument} needs a display_as argument" unless properties.include?(:display_as)
    183
    184   action = @current_entity
    185
    186   @entities[action][:output][argument] = {:description => properties[:description],
    187                                           :display_as  => properties[:display_as],
    188                                           :default     => properties[:default]}
    189 end

requires(requirement) click to toggle source

        # File lib/mcollective/ddl/base.rb
    191 def requires(requirement)
    192   raise "Requirement should be a hash in the form :item => 'requirement'" unless requirement.is_a?(Hash)
    193
    194   valid_requirements = [:mcollective]
    195
    196   requirement.keys.each do |key|
    197     unless valid_requirements.include?(key)
    198       raise "Requirement %s is not a valid requirement, only %s is supported" % [key, valid_requirements.join(", ")]
    199     end
    200
    201     @requirements[key] = requirement[key]
    202   end
    203
    204   validate_requirements
    205 end

template_for_plugintype() click to toggle source

       # File lib/mcollective/ddl/base.rb
    65 def template_for_plugintype
    66   case @plugintype
    67   when :agent
    68     return "rpc-help.erb"
    69   else
    70     if File.exists?(Util.templatepath("#{@plugintype}-help.erb"))
    71       return "#{@plugintype}-help.erb"
    72     else
    73       # Default help template gets loaded if plugintype-help does not exist.
    74       return "metadata-help.erb"
    75     end
    76   end
    77 end

validate_input_argument(input, key, argument) click to toggle source

validate strings, lists and booleans, we'll add more types of validators when all the use cases are clear

only does validation for arguments actually given, since some might be optional. We validate the presense of the argument earlier so this is a safe assumption, just to skip them.

:string can have maxlength and regex. A maxlength of 0 will bypasss checks :list has a array of valid values

        # File lib/mcollective/ddl/base.rb
    120 def validate_input_argument(input, key, argument)
    121   Validator.load_validators
    122
    123   case input[key][:type]
    124   when :string
    125     Validator.validate(argument, :string)
    126
    127     Validator.length(argument, input[key][:maxlength].to_i)
    128
    129     Validator.validate(argument, input[key][:validation])
    130
    131   when :list
    132     Validator.validate(argument, input[key][:list])
    133
    134   else
    135     Validator.validate(argument, input[key][:type])
    136   end
    137
    138   return true
    139 rescue => e
    140   raise DDLValidationError, "Cannot validate input %s: %s" % [key, e.to_s]
    141 end

validate_requirements() click to toggle source

        # File lib/mcollective/ddl/base.rb
    101 def validate_requirements
    102   if requirement = @requirements[:mcollective]
    103     if Util.versioncmp(Util.mcollective_version, requirement) < 0
    104       raise DDLValidationError, "%s plugin '%s' requires MCollective version %s or newer" % [@plugintype.to_s.capitalize, @pluginname, requirement]
    105     end
    106   end
    107
    108   true
    109 end