Embedded Methods

One of the exciting new features in CloudForms 4.6 within Automate is Embedded Methods. That is, one can store reusable, directly callable, ruby code within Automate and access from other Automate Methods.

(In an attempt to maintain some sanity, I’m capitalizing words like Method when in the Automate sense, and leaving them lowercase when referring to the wholly unrelated ruby use).

In my experimentation with Unit Testing, I’ve developed a reasonable and, I think, future proof process for doing this. The implementation is very flexible, allows for multiple Methods to be embedded in the caller. Otherwise, I think, ad-hoc conventions could cause a lot of trouble if not used with some rigor.

From the Calling Method, there is a new area in the UI to load in additional Methods. You may embed multiple Methods, but the embedding is not recursive; that is, if the target Method is configured to embed Methods, those will not be loaded.

The method-to-be-Embedded, which I’ll call the Library Method needs no special configuration, though my strategy does require both methods to be coded in the new style using classes.  The Library Method could have “bare code”, that is, code not even in a ruby method, but that would almost always be a bad idea, as it would run unconditionally and be nigh impossible to troubleshoot.

The ruby module/module/module namespaces match the Automate Domain/Namespace/Namespace/Class names. The Library Method’s name is not relevant. It is probably a good idea too, when configuring the calling Method, to always include the Domain Prefix in the method.

I give you a sample (and use case #1) Library method:

#
# Description: Core StdLib
#
module Cflab
  module StdLib
   module Core
   def initialize(handle = $evm)
     @handle = handle
   end
   def log(level, msg, update_message = false)
     @handle.log(level, "#{msg}")
     @handle.task.message = msg if @task && (update_message || level == 'error')
   end
   def dump_root()
     log(:info, "Begin @handle.root.attributes")
     @handle.root.attributes.sort.each {|k, v| log(:info, "\t Attribute: #{k} = #{v}")}
     log(:info, "End @handle.root.attributes")
     log(:info, "")
   end
   end
  end
end

Note significantly, that the ruby methods are not part of a class, but a module. This makes the module, in ruby speak, a mixin.  You don’t need the initialize() method unless you also plan on unit testing the code.

In the Calling Method’s class, you must include the ruby Module above, which brings in the ruby methods into the same namespace, e.g. include Cflab::StdLib::Core per below.

module Cflab
  module DynamicDialogs
    module Methods
    #
    # Method for listing AWS flavors for a drop down.
    #
    class List_flavors
    include Cflab::StdLib::Core
    def initialize(handle = $evm)
    @handle = handle
    end

    #
    # Actual entry point the bare script will call into. Outputs into @handle
    #
    def main
    @user = @handle.root['user']
    dialog_hash = {}
    dump_root()
    @handle.vmdb(:ManageIQ_Providers_Amazon_CloudManager_Flavor).all.each do |flavor|
         next unless flavor.ext_management_system || flavor.enabled
         next unless object_eligible?(flavor)
         @handle.log(:info, "Inspecting flavor: [#{flavor}]")
         dialog_hash[flavor.id] = "#{flavor.name} on #{flavor.ext_management_system.name}"
    end
    if dialog_hash.blank?
         dialog_hash[''] = "< no flavors found >"
         @handle.object['default_value'] = '< no flavors found >'
    else
         @handle.object['default_value'] = dialog_hash.first[0]
    end
    @handle.object["values"] = dialog_hash
    end
    end
    end
  end
end

if __FILE__ == $PROGRAM_NAME
  Cflab::DynamicDialogs::Methods::List_flavors.new.main
end

You are free to not include the Library module into your main class, but then would need to call the methods with their full path,

Cflab::StdLib::Core::log(:info, 'stuff happened')

The possibilities with Embedded Methods are endless, and I look forward to building up some truly reusable, generic, well tested, and well documented collection of useful utilities.

 

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

w

Connecting to %s