summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorLuke Kanies <luke@reductivelabs.com>2010-01-08 00:49:36 -0800
committertest branch <puppet-dev@googlegroups.com>2010-02-17 06:50:53 -0800
commit6d2a10b40c9f77ea5101abe6e568ed5a798c04f3 (patch)
treeb8ef1e9860be5c7b558e210fa066d327e5dbab92 /lib
parente515513b5cb065f3e43f5c2880d0452d8e2b25b8 (diff)
downloadpuppet-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.rb11
-rw-r--r--lib/puppet/dsl/resource_helper.rb62
-rw-r--r--lib/puppet/dsl/resource_type_api.rb40
-rw-r--r--lib/puppet/resource/type.rb18
-rw-r--r--lib/puppet/resource/type_collection.rb2
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