diff options
author | Luke Kanies <luke@reductivelabs.com> | 2010-01-08 00:49:36 -0800 |
---|---|---|
committer | test branch <puppet-dev@googlegroups.com> | 2010-02-17 06:50:53 -0800 |
commit | 6d2a10b40c9f77ea5101abe6e568ed5a798c04f3 (patch) | |
tree | b8ef1e9860be5c7b558e210fa066d327e5dbab92 /lib | |
parent | e515513b5cb065f3e43f5c2880d0452d8e2b25b8 (diff) | |
download | puppet-6d2a10b40c9f77ea5101abe6e568ed5a798c04f3.tar.gz puppet-6d2a10b40c9f77ea5101abe6e568ed5a798c04f3.tar.xz puppet-6d2a10b40c9f77ea5101abe6e568ed5a798c04f3.zip |
Adding simplistic pure ruby interface
This is a simplistic DSL - you can create
resource types (defined resources), classes,
and nodes, and they can call functions and
create resources. Nothing else, at this point.
Signed-off-by: Luke Kanies <luke@reductivelabs.com>
Diffstat (limited to 'lib')
-rw-r--r-- | lib/puppet/dsl.rb | 11 | ||||
-rw-r--r-- | lib/puppet/dsl/resource_helper.rb | 62 | ||||
-rw-r--r-- | lib/puppet/dsl/resource_type_api.rb | 40 | ||||
-rw-r--r-- | lib/puppet/resource/type.rb | 18 | ||||
-rw-r--r-- | lib/puppet/resource/type_collection.rb | 2 |
5 files changed, 128 insertions, 5 deletions
diff --git a/lib/puppet/dsl.rb b/lib/puppet/dsl.rb new file mode 100644 index 000000000..93cf0fbcf --- /dev/null +++ b/lib/puppet/dsl.rb @@ -0,0 +1,11 @@ +require 'puppet' + +module Puppet::DSL +end + +require 'puppet/dsl/resource_type_api' +require 'puppet/dsl/resource_helper' + +class Object + include Puppet::DSL::ResourceTypeAPI +end diff --git a/lib/puppet/dsl/resource_helper.rb b/lib/puppet/dsl/resource_helper.rb new file mode 100644 index 000000000..aaf8ab5f7 --- /dev/null +++ b/lib/puppet/dsl/resource_helper.rb @@ -0,0 +1,62 @@ +# This module adds functionality to a resource to make it +# capable of evaluating the DSL resource type block and also +# hooking into the scope system. +require 'puppet/resource/type_collection_helper' + +module Puppet::DSL::ResourceHelper + include Puppet::Resource::TypeCollectionHelper + + FUNCTION_MAP = {:acquire => :include} + + # Try to convert a missing method into a resource type or a function. + def method_missing(name, *args) + return create_resource(name, args[0], args[1]) if valid_type?(name) + + name = map_function(name) + + return call_function(name, args) if Puppet::Parser::Functions.function(name) + + super + end + + def set_instance_variables + eachparam do |param| + instance_variable_set("@#{param.name}", param.value) + end + end + + def create_resource(type, names, arguments = nil) + names = [names] unless names.is_a?(Array) + + arguments ||= {} + raise ArgumentError, "Resource arguments must be provided as a hash" unless arguments.is_a?(Hash) + + names.collect do |name| + resource = Puppet::Parser::Resource.new(:type => type, :title => name, :scope => scope) + arguments.each do |param, value| + resource[param] = value + end + + scope.compiler.add_resource(scope, resource) + resource + end + end + + def call_function(name, args) + return false unless method = Puppet::Parser::Functions.function(name) + scope.send(method, *args) + end + + def valid_type?(name) + return true if [:class, :node].include?(name) + return true if Puppet::Type.type(name) + return true if known_resource_types.definition(name) + return false + end + + private + + def map_function(name) + return FUNCTION_MAP[name] || name + end +end diff --git a/lib/puppet/dsl/resource_type_api.rb b/lib/puppet/dsl/resource_type_api.rb new file mode 100644 index 000000000..014d1a3dc --- /dev/null +++ b/lib/puppet/dsl/resource_type_api.rb @@ -0,0 +1,40 @@ +require 'puppet/resource/type' + +module Puppet::DSL::ResourceTypeAPI + def resource_type(name, *args, &block) + result = mk_resource_type(:definition, name, Hash.new, block) + result.set_arguments(munge_type_arguments(args)) + result + end + + def hostclass(name, options = {}, &block) + mk_resource_type(:hostclass, name, options, block) + end + + def node(name, options = {}, &block) + mk_resource_type(:node, name, options, block) + end + + private + + def mk_resource_type(type, name, options, code) + klass = Puppet::Resource::Type.new(type, name, options) + + klass.ruby_code = code if code + + Puppet::Node::Environment.new.known_resource_types.add klass + + klass + end + + def munge_type_arguments(args) + args.inject([]) do |result, item| + if item.is_a?(Hash) + item.each { |p, v| result << [p, v] } + else + result << item + end + result + end + end +end diff --git a/lib/puppet/resource/type.rb b/lib/puppet/resource/type.rb index 1b78bf58b..fa5fd5c88 100644 --- a/lib/puppet/resource/type.rb +++ b/lib/puppet/resource/type.rb @@ -3,6 +3,7 @@ require 'puppet/util/warnings' require 'puppet/util/errors' require 'puppet/util/inline_docs' require 'puppet/parser/ast/leaf' +require 'puppet/dsl' class Puppet::Resource::Type include Puppet::Util::InlineDocs @@ -11,7 +12,7 @@ class Puppet::Resource::Type RESOURCE_SUPERTYPES = [:hostclass, :node, :definition] - attr_accessor :file, :line, :doc, :code, :parent, :code_collection + attr_accessor :file, :line, :doc, :code, :ruby_code, :parent, :resource_type_collection attr_reader :type, :namespace, :arguments, :behaves_like # Are we a child of the passed class? Do a recursive search up our @@ -35,8 +36,9 @@ class Puppet::Resource::Type set_resource_parameters(resource, scope) - return nil unless c = self.code - return c.safeevaluate(scope) + code.safeevaluate(scope) if code + + evaluate_ruby_code(resource, scope) if ruby_code end def initialize(type, name, options = {}) @@ -137,7 +139,7 @@ class Puppet::Resource::Type def parent_type return nil unless parent - unless @parent_type ||= code_collection.send(type, parent) + unless @parent_type ||= resource_type_collection.send(type, parent) fail Puppet::ParseError, "Could not find parent resource type '#{parent}'" end @@ -217,6 +219,14 @@ class Puppet::Resource::Type return parent_scope(resource.scope, klass) end + def evaluate_ruby_code(resource, scope) + resource.extend(Puppet::DSL::ResourceHelper) + + resource.set_instance_variables + + resource.instance_eval(&ruby_code) + end + # Split an fq name into a namespace and name def namesplit(fullname) ary = fullname.split("::") diff --git a/lib/puppet/resource/type_collection.rb b/lib/puppet/resource/type_collection.rb index e2ca56290..513c1c672 100644 --- a/lib/puppet/resource/type_collection.rb +++ b/lib/puppet/resource/type_collection.rb @@ -31,7 +31,7 @@ class Puppet::Resource::TypeCollection end method = "add_#{instance.type}" send(method, instance) - instance.code_collection = self + instance.resource_type_collection = self instance end |