+100 :-)

On Wed, Aug 20, 2008 at 9:35 AM, James Turnbull <[EMAIL PROTECTED]> wrote:
>
>
> Signed-off-by: James Turnbull <[EMAIL PROTECTED]>
> ---
>  CHANGELOG                                |    4 +
>  lib/puppet/parser/functions.rb           |  224 
> +-----------------------------
>  lib/puppet/parser/functions/defined.rb   |   27 ++++
>  lib/puppet/parser/functions/fail.rb      |    4 +
>  lib/puppet/parser/functions/file.rb      |   21 +++
>  lib/puppet/parser/functions/fqdn_rand.rb |   15 ++
>  lib/puppet/parser/functions/generate.rb  |   35 +++++
>  lib/puppet/parser/functions/include.rb   |   26 ++++
>  lib/puppet/parser/functions/realize.rb   |   14 ++
>  lib/puppet/parser/functions/search.rb    |    7 +
>  lib/puppet/parser/functions/sha1.rb      |    6 +
>  lib/puppet/parser/functions/tag.rb       |    6 +
>  lib/puppet/parser/functions/tagged.rb    |   18 +++
>  lib/puppet/parser/functions/template.rb  |   22 +++
>  14 files changed, 212 insertions(+), 217 deletions(-)
>  create mode 100644 lib/puppet/parser/functions/defined.rb
>  create mode 100644 lib/puppet/parser/functions/fail.rb
>  create mode 100644 lib/puppet/parser/functions/file.rb
>  create mode 100644 lib/puppet/parser/functions/fqdn_rand.rb
>  create mode 100644 lib/puppet/parser/functions/generate.rb
>  create mode 100644 lib/puppet/parser/functions/include.rb
>  create mode 100644 lib/puppet/parser/functions/realize.rb
>  create mode 100644 lib/puppet/parser/functions/search.rb
>  create mode 100644 lib/puppet/parser/functions/sha1.rb
>  create mode 100644 lib/puppet/parser/functions/tag.rb
>  create mode 100644 lib/puppet/parser/functions/tagged.rb
>  create mode 100644 lib/puppet/parser/functions/template.rb
>
> diff --git a/CHANGELOG b/CHANGELOG
> index bf0fea2..eb7f88a 100644
> --- a/CHANGELOG
> +++ b/CHANGELOG
> @@ -1,4 +1,8 @@
>  0.24.x
> +    Fixed #1488 - Moved individual functions out of functions.rb into
> +    lib/puppet/parser/functions directory.  New functions should be created 
> in
> +    this directory.
> +
>     Fixed #1508 - Added HP-UX package provider
>
>     Fixed #1502 - Fixed poor stored configuration performance
> diff --git a/lib/puppet/parser/functions.rb b/lib/puppet/parser/functions.rb
> index 51903e9..5fb0439 100644
> --- a/lib/puppet/parser/functions.rb
> +++ b/lib/puppet/parser/functions.rb
> @@ -6,6 +6,8 @@ module Functions
>     # A module for managing parser functions.  Each specified function
>     # becomes an instance method on the Scope class.
>
> +    @functions = {}
> +
>     class << self
>         include Puppet::Util
>     end
> @@ -23,7 +25,6 @@ module Functions
>
>     # Create a new function type.
>     def self.newfunction(name, options = {}, &block)
> -        @functions ||= {}
>         name = symbolize(name)
>
>         if @functions.include? name
> @@ -105,226 +106,15 @@ module Functions
>             return false
>         end
>     end
> -
> -    # Include the specified classes
> -    newfunction(:include, :doc => "Evaluate one or more classes.") do |vals|
> -        vals = [vals] unless vals.is_a?(Array)
> -
> -        # The 'false' disables lazy evaluation.
> -        klasses = compiler.evaluate_classes(vals, self, false)
> -
> -        missing = vals.find_all do |klass|
> -            ! klasses.include?(klass)
> -        end
> -
> -        unless missing.empty?
> -            # Throw an error if we didn't evaluate all of the classes.
> -            str = "Could not find class"
> -            if missing.length > 1
> -                str += "es"
> -            end
> -
> -            str += " " + missing.join(", ")
> -
> -            if n = namespaces and ! n.empty? and n != [""]
> -                str += " in namespaces %s" % @namespaces.join(", ")
> -            end
> -            self.fail Puppet::ParseError, str
> -        end
> -    end
> -
> -    # Tag the current scope with each passed name
> -    newfunction(:tag, :doc => "Add the specified tags to the containing class
> -    or definition.  All contained objects will then acquire that tag, also.
> -    ") do |vals|
> -        self.resource.tag(*vals)
> -    end
> -
> -    # Test whether a given tag is set.  This functions as a big OR -- if any 
> of the
> -    # specified tags are unset, we return false.
> -    newfunction(:tagged, :type => :rvalue, :doc => "A boolean function that
> -    tells you whether the current container is tagged with the specified 
> tags.
> -    The tags are ANDed, so that all of the specified tags must be included 
> for
> -    the function to return true.") do |vals|
> -        configtags = compiler.catalog.tags
> -        resourcetags = resource.tags
> -
> -        retval = true
> -        vals.each do |val|
> -            unless configtags.include?(val) or resourcetags.include?(val)
> -                retval = false
> -                break
> -            end
> -        end
> -
> -        return retval
> -    end
> -
> -    # Test whether a given class or definition is defined
> -    newfunction(:defined, :type => :rvalue, :doc => "Determine whether a 
> given
> -    type is defined, either as a native type or a defined type, or whether a 
> class is defined.
> -    This is useful for checking whether a class is defined and only 
> including it if it is.
> -    This function can also test whether a resource has been defined, using 
> resource references
> -    (e.g., ``if defined(File['/tmp/myfile']) { ... }``).  This function is 
> unfortunately
> -    dependent on the parse order of the configuration when testing whether a 
> resource is defined.") do |vals|
> -        result = false
> -        vals.each do |val|
> -            case val
> -            when String:
> -                # For some reason, it doesn't want me to return from here.
> -                if Puppet::Type.type(val) or finddefine(val) or 
> findclass(val)
> -                    result = true
> -                    break
> -                end
> -            when Puppet::Parser::Resource::Reference:
> -                if findresource(val.to_s)
> -                    result = true
> -                    break
> -                end
> -            else
> -                raise ArgumentError, "Invalid argument of type %s to 
> 'defined'" % val.class
> -            end
> -        end
> -        result
> -    end
> -
> -    newfunction(:fqdn_rand, :type => :rvalue, :doc => "Generates random
> -    numbers based on the node's fqdn. The first argument sets the range.
> -    The second argument specifies a number to add to the seed and is
> -    optional.") do |args|
> -       require 'md5'
> -       max = args[0]
> -       if args[1] then
> -            seed = args[1]
> -       else
> -            seed = 1
> -       end
> -       fqdn_seed = MD5.new(lookupvar('fqdn')).to_s.hex
> -       srand(seed+fqdn_seed)
> -       rand(max).to_s
> -    end
> -
> -    newfunction(:fail, :doc => "Fail with a parse error.") do |vals|
> -        vals = vals.collect { |s| s.to_s }.join(" ") if vals.is_a? Array
> -        raise Puppet::ParseError, vals.to_s
> -    end
> -
> +
>     # Runs a newfunction to create a function for each of the log levels
> -    Puppet::Util::Log.levels.each do |level|
> -        newfunction(level, :doc => "Log a message on the server at level
> -        #{level.to_s}.") do |vals|
> -            send(level, vals.join(" "))
> -        end
> -    end
> -
> -    newfunction(:template, :type => :rvalue, :doc => "Evaluate a template and
> -    return its value.  See `the templating docs 
> </trac/puppet/wiki/PuppetTemplating>`_
> -    for more information.  Note that if multiple templates are specified, 
> their
> -    output is all concatenated and returned as the output of the function.
> -    ") do |vals|
> -        require 'erb'
> -
> -        vals.collect do |file|
> -            # Use a wrapper, so the template can't get access to the full
> -            # Scope object.
> -            debug "Retrieving template %s" % file
> -            wrapper = Puppet::Parser::TemplateWrapper.new(self, file)
> -
> -            begin
> -                wrapper.result()
> -            rescue => detail
> -                raise Puppet::ParseError,
> -                    "Failed to parse template %s: %s" %
> -                        [file, detail]
> -            end
> -        end.join("")
> -    end
> -
> -    # This is just syntactic sugar for a collection, although it will 
> generally
> -    # be a good bit faster.
> -    newfunction(:realize, :doc => "Make a virtual object real.  This is 
> useful
> -        when you want to know the name of the virtual object and don't want 
> to
> -        bother with a full collection.  It is slightly faster than a 
> collection,
> -        and, of course, is a bit shorter.  You must pass the object using a
> -        reference; e.g.: ``realize User[luke]``." ) do |vals|
> -        coll = Puppet::Parser::Collector.new(self, :nomatter, nil, nil, 
> :virtual)
> -        vals = [vals] unless vals.is_a?(Array)
> -        coll.resources = vals
>
> -        compiler.add_collection(coll)
> -    end
> -
> -    newfunction(:search, :doc => "Add another namespace for this class to 
> search.
> -        This allows you to create classes with sets of definitions and add
> -        those classes to another class's search path.") do |vals|
> -        vals.each do |val|
> -            add_namespace(val)
> +    Puppet::Util::Log.levels.each do |level|
> +        newfunction(level, :doc => "Log a message on the server at level
> +        #{level.to_s}.") do |vals|
> +            send(level, vals.join(" "))
>         end
>     end
>
> -    newfunction(:file, :type => :rvalue,
> -        :doc => "Return the contents of a file.  Multiple files
> -        can be passed, and the first file that exists will be read in.") do 
> |vals|
> -            ret = nil
> -            vals.each do |file|
> -                unless file =~ /^#{File::SEPARATOR}/
> -                    raise Puppet::ParseError, "Files must be fully qualified"
> -                end
> -                if FileTest.exists?(file)
> -                    ret = File.read(file)
> -                    break
> -                end
> -            end
> -            if ret
> -                ret
> -            else
> -                raise Puppet::ParseError, "Could not find any files from %s" 
> %
> -                    vals.join(", ")
> -            end
> -    end
> -
> -    newfunction(:generate, :type => :rvalue,
> -        :doc => "Calls an external command and returns the results of the
> -        command.  Any arguments are passed to the external command as
> -        arguments.  If the generator does not exit with return code of 0,
> -        the generator is considered to have failed and a parse error is
> -        thrown.  Generators can only have file separators, alphanumerics, 
> dashes,
> -        and periods in them.  This function will attempt to protect you from
> -        malicious generator calls (e.g., those with '..' in them), but it can
> -        never be entirely safe.  No subshell is used to execute
> -        generators, so all shell metacharacters are passed directly to
> -        the generator.") do |args|
> -
> -            unless args[0] =~ /^#{File::SEPARATOR}/
> -                raise Puppet::ParseError, "Generators must be fully 
> qualified"
> -            end
> -
> -            unless args[0] =~ /^[-#{File::SEPARATOR}\w.]+$/
> -                raise Puppet::ParseError,
> -                    "Generators can only contain alphanumerics, file 
> separators, and dashes"
> -            end
> -
> -            if args[0] =~ /\.\./
> -                raise Puppet::ParseError,
> -                    "Can not use generators with '..' in them."
> -            end
> -
> -            begin
> -                output = Puppet::Util.execute(args)
> -            rescue Puppet::ExecutionFailure => detail
> -                raise Puppet::ParseError, "Failed to execute generator %s: 
> %s" %
> -                    [args[0], detail]
> -            end
> -            output
> -    end
> -
> -    newfunction(:sha1, :type => :rvalue,
> -        :doc => "Returns a SHA1 hash value from a provided string.") do 
> |args|
> -            require 'sha1'
> -
> -            Digest::SHA1.hexdigest(args[0])
> -    end
> -
>  end
>  end
> -
> diff --git a/lib/puppet/parser/functions/defined.rb 
> b/lib/puppet/parser/functions/defined.rb
> new file mode 100644
> index 0000000..4e369ae
> --- /dev/null
> +++ b/lib/puppet/parser/functions/defined.rb
> @@ -0,0 +1,27 @@
> +# Test whether a given class or definition is defined
> +Puppet::Parser::Functions::newfunction(:defined, :type => :rvalue, :doc => 
> "Determine whether a given
> +    type is defined, either as a native type or a defined type, or whether a 
> class is defined.
> +    This is useful for checking whether a class is defined and only 
> including it if it is.
> +    This function can also test whether a resource has been defined, using 
> resource references
> +    (e.g., ``if defined(File['/tmp/myfile']) { ... }``).  This function is 
> unfortunately
> +    dependent on the parse order of the configuration when testing whether a 
> resource is defined.") do |vals|
> +        result = false
> +        vals.each do |val|
> +            case val
> +            when String:
> +                # For some reason, it doesn't want me to return from here.
> +                if Puppet::Type.type(val) or finddefine(val) or 
> findclass(val)
> +                    result = true
> +                    break
> +                end
> +            when Puppet::Parser::Resource::Reference:
> +                if findresource(val.to_s)
> +                    result = true
> +                    break
> +                end
> +            else
> +                raise ArgumentError, "Invalid argument of type %s to 
> 'defined'" % val.class
> +            end
> +        end
> +        result
> +end
> diff --git a/lib/puppet/parser/functions/fail.rb 
> b/lib/puppet/parser/functions/fail.rb
> new file mode 100644
> index 0000000..35b20ee
> --- /dev/null
> +++ b/lib/puppet/parser/functions/fail.rb
> @@ -0,0 +1,4 @@
> +Puppet::Parser::Functions::newfunction(:fail, :doc => "Fail with a parse 
> error.") do |vals|
> +        vals = vals.collect { |s| s.to_s }.join(" ") if vals.is_a? Array
> +        raise Puppet::ParseError, vals.to_s
> +end
> diff --git a/lib/puppet/parser/functions/file.rb 
> b/lib/puppet/parser/functions/file.rb
> new file mode 100644
> index 0000000..47b3f96
> --- /dev/null
> +++ b/lib/puppet/parser/functions/file.rb
> @@ -0,0 +1,21 @@
> +# Returns the contents of a file
> +Puppet::Parser::Functions::newfunction(:file, :type => :rvalue,
> +        :doc => "Return the contents of a file.  Multiple files
> +        can be passed, and the first file that exists will be read in.") do 
> |vals|
> +            ret = nil
> +            vals.each do |file|
> +                unless file =~ /^#{File::SEPARATOR}/
> +                    raise Puppet::ParseError, "Files must be fully qualified"
> +                end
> +                if FileTest.exists?(file)
> +                    ret = File.read(file)
> +                    break
> +                end
> +            end
> +            if ret
> +                ret
> +            else
> +                raise Puppet::ParseError, "Could not find any files from %s" 
> %
> +                    vals.join(", ")
> +            end
> +end
> diff --git a/lib/puppet/parser/functions/fqdn_rand.rb 
> b/lib/puppet/parser/functions/fqdn_rand.rb
> new file mode 100644
> index 0000000..2ae46de
> --- /dev/null
> +++ b/lib/puppet/parser/functions/fqdn_rand.rb
> @@ -0,0 +1,15 @@
> +Puppet::Parser::Functions::newfunction(:fqdn_rand, :type => :rvalue, :doc =>
> +    "Generates random numbers based on the node's fqdn. The first argument
> +    sets the range.  The second argument specifies a number to add to the
> +    seed and is optional.") do |args|
> +        require 'md5'
> +        max = args[0]
> +        if args[1] then
> +             seed = args[1]
> +        else
> +             seed = 1
> +        end
> +        fqdn_seed = MD5.new(lookupvar('fqdn')).to_s.hex
> +        srand(seed+fqdn_seed)
> +        rand(max).to_s
> +end
> diff --git a/lib/puppet/parser/functions/generate.rb 
> b/lib/puppet/parser/functions/generate.rb
> new file mode 100644
> index 0000000..1be9016
> --- /dev/null
> +++ b/lib/puppet/parser/functions/generate.rb
> @@ -0,0 +1,35 @@
> +# Runs an external command and returns the results
> +Puppet::Parser::Functions::newfunction(:generate, :type => :rvalue,
> +        :doc => "Calls an external command and returns the results of the
> +        command.  Any arguments are passed to the external command as
> +        arguments.  If the generator does not exit with return code of 0,
> +        the generator is considered to have failed and a parse error is
> +        thrown.  Generators can only have file separators, alphanumerics, 
> dashes,
> +        and periods in them.  This function will attempt to protect you from
> +        malicious generator calls (e.g., those with '..' in them), but it can
> +        never be entirely safe.  No subshell is used to execute
> +        generators, so all shell metacharacters are passed directly to
> +        the generator.") do |args|
> +
> +            unless args[0] =~ /^#{File::SEPARATOR}/
> +                raise Puppet::ParseError, "Generators must be fully 
> qualified"
> +            end
> +
> +            unless args[0] =~ /^[-#{File::SEPARATOR}\w.]+$/
> +                raise Puppet::ParseError,
> +                    "Generators can only contain alphanumerics, file 
> separators, and dashes"
> +            end
> +
> +            if args[0] =~ /\.\./
> +                raise Puppet::ParseError,
> +                    "Can not use generators with '..' in them."
> +            end
> +
> +            begin
> +                output = Puppet::Util.execute(args)
> +            rescue Puppet::ExecutionFailure => detail
> +                raise Puppet::ParseError, "Failed to execute generator %s: 
> %s" %
> +                    [args[0], detail]
> +            end
> +            output
> +end
> diff --git a/lib/puppet/parser/functions/include.rb 
> b/lib/puppet/parser/functions/include.rb
> new file mode 100644
> index 0000000..213a041
> --- /dev/null
> +++ b/lib/puppet/parser/functions/include.rb
> @@ -0,0 +1,26 @@
> +# Include the specified classes
> +Puppet::Parser::Functions::newfunction(:include, :doc => "Evaluate one or 
> more classes.") do |vals|
> +        vals = [vals] unless vals.is_a?(Array)
> +
> +        # The 'false' disables lazy evaluation.
> +        klasses = compiler.evaluate_classes(vals, self, false)
> +
> +        missing = vals.find_all do |klass|
> +            ! klasses.include?(klass)
> +        end
> +
> +        unless missing.empty?
> +            # Throw an error if we didn't evaluate all of the classes.
> +            str = "Could not find class"
> +            if missing.length > 1
> +                str += "es"
> +            end
> +
> +            str += " " + missing.join(", ")
> +
> +            if n = namespaces and ! n.empty? and n != [""]
> +                str += " in namespaces %s" % @namespaces.join(", ")
> +            end
> +            self.fail Puppet::ParseError, str
> +        end
> +end
> diff --git a/lib/puppet/parser/functions/realize.rb 
> b/lib/puppet/parser/functions/realize.rb
> new file mode 100644
> index 0000000..1bdde23
> --- /dev/null
> +++ b/lib/puppet/parser/functions/realize.rb
> @@ -0,0 +1,14 @@
> +# This is just syntactic sugar for a collection, although it will generally
> +# be a good bit faster.
> +
> +Puppet::Parser::Functions::newfunction(:realize, :doc => "Make a virtual 
> object real.  This is useful
> +        when you want to know the name of the virtual object and don't want 
> to
> +        bother with a full collection.  It is slightly faster than a 
> collection,
> +        and, of course, is a bit shorter.  You must pass the object using a
> +        reference; e.g.: ``realize User[luke]``." ) do |vals|
> +        coll = Puppet::Parser::Collector.new(self, :nomatter, nil, nil, 
> :virtual)
> +        vals = [vals] unless vals.is_a?(Array)
> +        coll.resources = vals
> +
> +        compiler.add_collection(coll)
> +end
> diff --git a/lib/puppet/parser/functions/search.rb 
> b/lib/puppet/parser/functions/search.rb
> new file mode 100644
> index 0000000..87dd02d
> --- /dev/null
> +++ b/lib/puppet/parser/functions/search.rb
> @@ -0,0 +1,7 @@
> +Puppet::Parser::Functions::newfunction(:search, :doc => "Add another 
> namespace for this class to search.
> +        This allows you to create classes with sets of definitions and add
> +        those classes to another class's search path.") do |vals|
> +        vals.each do |val|
> +            add_namespace(val)
> +        end
> +end
> diff --git a/lib/puppet/parser/functions/sha1.rb 
> b/lib/puppet/parser/functions/sha1.rb
> new file mode 100644
> index 0000000..09386a6
> --- /dev/null
> +++ b/lib/puppet/parser/functions/sha1.rb
> @@ -0,0 +1,6 @@
> +Puppet::Parser::Functions::newfunction(:sha1, :type => :rvalue,
> +        :doc => "Returns a SHA1 hash value from a provided string.") do 
> |args|
> +            require 'sha1'
> +
> +            Digest::SHA1.hexdigest(args[0])
> +end
> diff --git a/lib/puppet/parser/functions/tag.rb 
> b/lib/puppet/parser/functions/tag.rb
> new file mode 100644
> index 0000000..3e487fe
> --- /dev/null
> +++ b/lib/puppet/parser/functions/tag.rb
> @@ -0,0 +1,6 @@
> +# Tag the current scope with each passed name
> +Puppet::Parser::Functions::newfunction(:tag, :doc => "Add the specified tags 
> to the containing class
> +    or definition.  All contained objects will then acquire that tag, also.
> +    ") do |vals|
> +        self.resource.tag(*vals)
> +end
> diff --git a/lib/puppet/parser/functions/tagged.rb 
> b/lib/puppet/parser/functions/tagged.rb
> new file mode 100644
> index 0000000..fccb132
> --- /dev/null
> +++ b/lib/puppet/parser/functions/tagged.rb
> @@ -0,0 +1,18 @@
> +# Test whether a given tag is set.  This functions as a big OR -- if any of 
> the specified tags are unset, we return false.
> +Puppet::Parser::Functions::newfunction(:tagged, :type => :rvalue, :doc => "A 
> boolean function that
> +    tells you whether the current container is tagged with the specified 
> tags.
> +    The tags are ANDed, so that all of the specified tags must be included 
> for
> +    the function to return true.") do |vals|
> +        configtags = compiler.catalog.tags
> +        resourcetags = resource.tags
> +
> +        retval = true
> +        vals.each do |val|
> +            unless configtags.include?(val) or resourcetags.include?(val)
> +                retval = false
> +                break
> +            end
> +        end
> +
> +        return retval
> +end
> diff --git a/lib/puppet/parser/functions/template.rb 
> b/lib/puppet/parser/functions/template.rb
> new file mode 100644
> index 0000000..e62c3b3
> --- /dev/null
> +++ b/lib/puppet/parser/functions/template.rb
> @@ -0,0 +1,22 @@
> +Puppet::Parser::Functions::newfunction(:template, :type => :rvalue, :doc =>
> +    "Evaluate a template and return its value.  See `the templating docs
> +    </trac/puppet/wiki/PuppetTemplating>`_ for more information.  Note that
> +    if multiple templates are specified, their output is all concatenated
> +    and returned as the output of the function.") do |vals|
> +        require 'erb'
> +
> +        vals.collect do |file|
> +            # Use a wrapper, so the template can't get access to the full
> +            # Scope object.
> +            debug "Retrieving template %s" % file
> +            wrapper = Puppet::Parser::TemplateWrapper.new(self, file)
> +
> +            begin
> +                wrapper.result()
> +            rescue => detail
> +                raise Puppet::ParseError,
> +                    "Failed to parse template %s: %s" %
> +                        [file, detail]
> +            end
> +        end.join("")
> +end
> --
> 1.5.4.1
>
>
> >
>

--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"Puppet Developers" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/puppet-dev?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to