module MCollective::DDL - mcollective version 2.12.5

# module MCollective::DDL

A set of classes that helps create data description language files for plugins. You can define meta data, actions, input and output describing the behavior of your agent or other plugins

`DDL` files are used for input validation, constructing outputs, producing online help, informing the various display routines and so forth.

A sample `DDL` for an agent be seen below, you'd put this in your agent dir as <agent name>.ddl

     metadata :name        => "SimpleRPC Service Agent",
              :description => "Agent to manage services using the Puppet service provider",
              :author      => "R.I.Pienaar",
              :license     => "GPLv2",
              :version     => "1.1",
              :url         => "http://mcollective-plugins.googlecode.com/",
              :timeout     => 60

     action "status", :description => "Gets the status of a service" do
        display :always

        input :service,
              :prompt      => "Service Name",
              :description => "The service to get the status for",
              :type        => :string,
              :validation  => '^[a-zA-Z\-_\d]+$',
              :optional    => true,
              :maxlength   => 30

        output :status,
               :description => "The status of service",
               :display_as  => "Service Status"
    end

There are now many types of `DDL` and ultimately all pugins should have `DDL` files. The code is organized so that any plugin type will magically just work - they will be an instane of `Base` which has metadata and a few common cases.

For plugin types that require more specific behaviors they can just add a class here that inherits from `Base` and add their specific behavior.

`Base` defines a specific behavior for input, output and metadata which we'd like to keep standard across plugin types so do not completely override the behavior of input. The methods are written that they will gladly store extra content though so you add, do not remove. See the `AgentDDL` class for an example where agents want a :required argument to be always set.

### Public Class Methods

load_and_cache(*args) click to toggle source

       # File lib/mcollective/ddl.rb
    69 def self.load_and_cache(*args)
    70   Cache.setup(:ddl, 300)
    71
    72   plugin = args.first
    73   args.size > 1 ? type = args[1].to_s : type = "agent"
    74   path = "%s/%s" % [type, plugin]
    75
    76   begin
    77     ddl = Cache.read(:ddl, path)
    78   rescue
    79     begin
    80       klass = DDL.const_get("%sDDL" % type.capitalize)
    81     rescue NameError
    82       klass = Base
    83     end
    84
    85     ddl = Cache.write(:ddl, path, klass.new(*args))
    86   end
    87
    88   return ddl
    89 end

new(*args, &blk) click to toggle source

There used to be only one big nasty `DDL` class with a bunch of mashed together behaviors. It's been around for ages and we would rather not ask all the users to change their `DDL.new` calls to some other factory method that would have this exact same behavior.

So we override the behavior of new which is a hugely sucky thing to do but ultimately it's what would be least disrupting to code out there today. We did though change `DDL` to a module to make it possibly a little less suprising, possibly.

       # File lib/mcollective/ddl.rb
    65 def self.new(*args, &blk)
    66   load_and_cache(*args)
    67 end

string_to_boolean(val) click to toggle source

As we're taking arguments on the command line we need a way to input booleans, true on the cli is a string so this method will take the ddl, find all arguments that are supposed to be boolean and if they are the strings “true”/“yes” or “false”/“no” turn them into the matching boolean

        # File lib/mcollective/ddl.rb
     96 def self.string_to_boolean(val)
     97   return true if ["true", "t", "yes", "y", "1"].include?(val.downcase)
     98   return false if ["false", "f", "no", "n", "0"].include?(val.downcase)
     99
    100   raise "#{val} does not look like a boolean argument"
    101 end

string_to_number(val) click to toggle source

a generic string to number function, if a number looks like a float it turns it into a float else an int. This is naive but should be sufficient for numbers typed on the cli in most cases

        # File lib/mcollective/ddl.rb
    106 def self.string_to_number(val)
    107   return val.to_f if val =~ /^\d+\.\d+$/
    108   return val.to_i if val =~ /^\d+$/
    109
    110   raise "#{val} does not look like a number"
    111 end