diff options
author | Luke Kanies <luke@puppetlabs.com> | 2011-01-30 17:33:28 -0800 |
---|---|---|
committer | Luke Kanies <luke@puppetlabs.com> | 2011-01-30 17:33:28 -0800 |
commit | 809aebec7a54be90990b9ee5fea1f85204598f17 (patch) | |
tree | 9adc1e05d66fbec9772c7b379bbb52976b9b5753 /lib/puppet/interface.rb | |
download | puppet-809aebec7a54be90990b9ee5fea1f85204598f17.tar.gz puppet-809aebec7a54be90990b9ee5fea1f85204598f17.tar.xz puppet-809aebec7a54be90990b9ee5fea1f85204598f17.zip |
Moving data executables to their own module
Signed-off-by: Luke Kanies <luke@puppetlabs.com>
Diffstat (limited to 'lib/puppet/interface.rb')
-rw-r--r-- | lib/puppet/interface.rb | 145 |
1 files changed, 145 insertions, 0 deletions
diff --git a/lib/puppet/interface.rb b/lib/puppet/interface.rb new file mode 100644 index 000000000..2be3df5d6 --- /dev/null +++ b/lib/puppet/interface.rb @@ -0,0 +1,145 @@ +require 'puppet' + +class Puppet::Interface + # This is just so we can search for actions. We only use its + # list of directories to search. + def self.autoloader + require 'puppet/util/autoload' + @autoloader ||= Puppet::Util::Autoload.new(:application, "puppet/interface") + end + + # Declare that this app can take a specific action, and provide + # the code to do so. + def self.action(name, &block) + @actions ||= [] + name = name.to_s.downcase.to_sym + raise "Action #{name} already defined for #{name}" if actions.include?(name) + + @actions << name + + define_method(name, &block) + end + + def self.actions + @actions ||= [] + (if superclass.respond_to?(:actions) + @actions + superclass.actions + else + @actions + end).sort { |a,b| a.to_s <=> b.to_s } + end + + # Return an indirection associated with an interface, if one exists + # One usually does. + def self.indirection + unless @indirection + raise "Could not find data type '#{name}' for interface '#{name}'" unless @indirection = Puppet::Indirector::Indirection.instance(name.to_sym) + end + @indirection + end + + # Return an interface by name, loading from disk if necessary. + def self.interface(name) + require "puppet/interface/#{name.to_s.downcase}" + self.const_get(name.to_s.capitalize) + rescue Exception => detail + $stderr.puts "Unable to find interface '#{name.to_s}': #{detail}." + Kernel::exit(1) + end + + # Return the interface name. + def self.name + @name || self.to_s.sub(/.+::/, '').downcase + end + + attr_accessor :from, :type, :verb, :name, :arguments, :indirection, :format + + def action?(name) + self.class.actions.include?(name.to_sym) + end + + # Print the configuration for the current terminus class + action :showconfig do |*args| + if t = indirection.terminus_class + puts "Run mode #{Puppet.run_mode}: #{t}" + else + $stderr.puts "No default terminus class for run mode #{Puppet.run_mode}" + end + end + + action :destroy do |name, *args| + call_indirection_method(:destroy, name, *args) + end + + action :find do |name, *args| + call_indirection_method(:find, name, *args) + end + + action :save do |name, *args| + call_indirection_method(:save, name, *args) + end + + action :search do |name, *args| + call_indirection_method(:search, name, *args) + end + + def indirection + self.class.indirection + end + + def initialize(options = {}) + options.each { |opt, val| send(opt.to_s + "=", val) } + + @format ||= :yaml + + Puppet::Util::Log.newdestination :console + + load_actions + end + + def set_terminus(from) + begin + indirection.terminus_class = from + rescue => detail + raise "Could not set '#{indirection.name}' terminus to '#{from}' (#{detail}); valid terminus types are #{terminus_classes(indirection.name).join(", ") }" + end + end + + def call_indirection_method(method, name, *args) + begin + result = indirection.send(method, name, *args) + rescue => detail + puts detail.backtrace if Puppet[:trace] + raise "Could not call #{method} on #{type}: #{detail}" + end + + unless result + raise "Could not #{verb} #{type} for #{name}" + end + + puts result.render(format.to_sym) + end + + # Try to find actions defined in other files. + def load_actions + path = "puppet/interface/#{self.class.name}" + + self.class.autoloader.search_directories.each do |dir| + fdir = File.join(dir, path) + next unless FileTest.directory?(fdir) + + Dir.glob("#{fdir}/*.rb").each do |file| + Puppet.info "Loading actions for '#{self.class.name}' from '#{file}'" + require file + end + end + end + + def indirections + Puppet::Indirector::Indirection.instances.collect { |t| t.to_s }.sort + end + + def terminus_classes(indirection) + Puppet::Indirector::Terminus.terminus_classes(indirection).collect { |t| t.to_s }.sort + end +end |