Initial commit
This commit is contained in:
commit
a7a56f1f71
|
@ -0,0 +1,5 @@
|
|||
source :rubygems
|
||||
|
||||
puppetversion = ENV.key?('PUPPET_VERSION') ? "= #{ENV['PUPPET_VERSION']}" : ['>= 2.7']
|
||||
gem 'puppet', puppetversion
|
||||
gem 'puppetlabs_spec_helper', '>= 0.1.0'
|
|
@ -0,0 +1,4 @@
|
|||
pkg/
|
||||
.DS_Store
|
||||
metadata.json
|
||||
coverage/
|
|
@ -0,0 +1,16 @@
|
|||
language: ruby
|
||||
rvm:
|
||||
- 1.8.7
|
||||
before_script:
|
||||
after_script:
|
||||
script: "rake spec_full"
|
||||
branches:
|
||||
only:
|
||||
- master
|
||||
env:
|
||||
- PUPPET_VERSION=2.7.13
|
||||
- PUPPET_VERSION=2.7.6
|
||||
- PUPPET_VERSION=2.6.9
|
||||
notifications:
|
||||
email: false
|
||||
gemfile: .gemfile
|
|
@ -0,0 +1,86 @@
|
|||
2012-05-22 - Peter Meier <peter.meier@immerda.ch> - 2.3.3
|
||||
* fix regression in #11017 properly (f0a62c7)
|
||||
|
||||
2012-05-10 - Jeff McCune <jeff@puppetlabs.com> - 2.3.3
|
||||
* Fix spec tests using the new spec_helper (7d34333)
|
||||
|
||||
2012-05-10 - Puppet Labs <support@puppetlabs.com> - 2.3.2
|
||||
* Make file_line default to ensure => present (1373e70)
|
||||
* Memoize file_line spec instance variables (20aacc5)
|
||||
* Fix spec tests using the new spec_helper (1ebfa5d)
|
||||
* (#13595) initialize_everything_for_tests couples modules Puppet ver (3222f35)
|
||||
* (#13439) Fix MRI 1.9 issue with spec_helper (15c5fd1)
|
||||
* (#13439) Fix test failures with Puppet 2.6.x (665610b)
|
||||
* (#13439) refactor spec helper for compatibility with both puppet 2.7 and master (82194ca)
|
||||
* (#13494) Specify the behavior of zero padded strings (61891bb)
|
||||
|
||||
2012-03-29 Puppet Labs <support@puppetlabs.com> - 2.1.3
|
||||
* (#11607) Add Rakefile to enable spec testing
|
||||
* (#12377) Avoid infinite loop when retrying require json
|
||||
|
||||
2012-03-13 Puppet Labs <support@puppetlabs.com> - 2.3.1
|
||||
* (#13091) Fix LoadError bug with puppet apply and puppet_vardir fact
|
||||
|
||||
2012-03-12 Puppet Labs <support@puppetlabs.com> - 2.3.0
|
||||
* Add a large number of new Puppet functions
|
||||
* Backwards compatibility preserved with 2.2.x
|
||||
|
||||
2011-12-30 Puppet Labs <support@puppetlabs.com> - 2.2.1
|
||||
* Documentation only release for the Forge
|
||||
|
||||
2011-12-30 Puppet Labs <support@puppetlabs.com> - 2.1.2
|
||||
* Documentation only release for PE 2.0.x
|
||||
|
||||
2011-11-08 Puppet Labs <support@puppetlabs.com> - 2.2.0
|
||||
* #10285 - Refactor json to use pson instead.
|
||||
* Maint - Add watchr autotest script
|
||||
* Maint - Make rspec tests work with Puppet 2.6.4
|
||||
* #9859 - Add root_home fact and tests
|
||||
|
||||
2011-08-18 Puppet Labs <support@puppetlabs.com> - 2.1.1
|
||||
* Change facts.d paths to match Facter 2.0 paths.
|
||||
* /etc/facter/facts.d
|
||||
* /etc/puppetlabs/facter/facts.d
|
||||
|
||||
2011-08-17 Puppet Labs <support@puppetlabs.com> - 2.1.0
|
||||
* Add R.I. Pienaar's facts.d custom facter fact
|
||||
* facts defined in /etc/facts.d and /etc/puppetlabs/facts.d are
|
||||
automatically loaded now.
|
||||
|
||||
2011-08-04 Puppet Labs <support@puppetlabs.com> - 2.0.0
|
||||
* Rename whole_line to file_line
|
||||
* This is an API change and as such motivating a 2.0.0 release according to semver.org.
|
||||
|
||||
2011-08-04 Puppet Labs <support@puppetlabs.com> - 1.1.0
|
||||
* Rename append_line to whole_line
|
||||
* This is an API change and as such motivating a 1.1.0 release.
|
||||
|
||||
2011-08-04 Puppet Labs <support@puppetlabs.com> - 1.0.0
|
||||
* Initial stable release
|
||||
* Add validate_array and validate_string functions
|
||||
* Make merge() function work with Ruby 1.8.5
|
||||
* Add hash merging function
|
||||
* Add has_key function
|
||||
* Add loadyaml() function
|
||||
* Add append_line native
|
||||
|
||||
2011-06-21 Jeff McCune <jeff@puppetlabs.com> - 0.1.7
|
||||
* Add validate_hash() and getvar() functions
|
||||
|
||||
2011-06-15 Jeff McCune <jeff@puppetlabs.com> - 0.1.6
|
||||
* Add anchor resource type to provide containment for composite classes
|
||||
|
||||
2011-06-03 Jeff McCune <jeff@puppetlabs.com> - 0.1.5
|
||||
* Add validate_bool() function to stdlib
|
||||
|
||||
0.1.4 2011-05-26 Jeff McCune <jeff@puppetlabs.com>
|
||||
* Move most stages after main
|
||||
|
||||
0.1.3 2011-05-25 Jeff McCune <jeff@puppetlabs.com>
|
||||
* Add validate_re() function
|
||||
|
||||
0.1.2 2011-05-24 Jeff McCune <jeff@puppetlabs.com>
|
||||
* Update to add annotated tag
|
||||
|
||||
0.1.1 2011-05-24 Jeff McCune <jeff@puppetlabs.com>
|
||||
* Add stdlib::stages class with a standard set of stages
|
|
@ -0,0 +1,19 @@
|
|||
Copyright (C) 2011 Puppet Labs Inc
|
||||
|
||||
and some parts:
|
||||
|
||||
Copyright (C) 2011 Krzysztof Wilczynski
|
||||
|
||||
Puppet Labs can be contacted at: info@puppetlabs.com
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
|
@ -0,0 +1,11 @@
|
|||
name 'puppetlabs-stdlib'
|
||||
version '2.3.3'
|
||||
source 'git://github.com/puppetlabs/puppetlabs-stdlib'
|
||||
author 'puppetlabs'
|
||||
license 'Apache 2.0'
|
||||
summary 'Puppet Module Standard Library'
|
||||
description 'Standard Library for Puppet Modules'
|
||||
project_page 'https://github.com/puppetlabs/puppetlabs-stdlib'
|
||||
|
||||
## Add dependencies, if any:
|
||||
# dependency 'username/name', '>= 1.2.0'
|
|
@ -0,0 +1,89 @@
|
|||
# Puppet Labs Standard Library #
|
||||
|
||||
This module provides a "standard library" of resources for developing Puppet
|
||||
Modules. This modules will include the following additions to Puppet
|
||||
|
||||
* Stages
|
||||
* Facts
|
||||
* Functions
|
||||
* Defined resource types
|
||||
* Types
|
||||
* Providers
|
||||
|
||||
This module is officially curated and provided by Puppet Labs. The modules
|
||||
Puppet Labs writes and distributes will make heavy use of this standard
|
||||
library.
|
||||
|
||||
# Versions #
|
||||
|
||||
This module follows semver.org (v1.0.0) versioning guidelines. The standard
|
||||
library module is released as part of [Puppet
|
||||
Enterprise](http://puppetlabs.com/puppet/puppet-enterprise/) and as a result
|
||||
older versions of Puppet Enterprise that Puppet Labs still supports will have
|
||||
bugfix maintenance branches periodically "merged up" into master. The current
|
||||
list of integration branches are:
|
||||
|
||||
* v2.1.x (v2.1.1 released in PE 1.2, 1.2.1, 1.2.3, 1.2.4)
|
||||
* v2.2.x (Never released as part of PE, only to the Forge)
|
||||
* v2.3.x (Scheduled for next PE feature release)
|
||||
* master (mainline development branch)
|
||||
|
||||
The first Puppet Enterprise version including the stdlib module is Puppet
|
||||
Enterprise 1.2.
|
||||
|
||||
# Compatibility #
|
||||
|
||||
## stdlib v2.1.x, v2.2.x ##
|
||||
|
||||
v2.1.x and v2.2.x of this module are designed to work with Puppet versions
|
||||
2.6.x and 2.7.x. There are currently no plans for a Puppet 0.25 standard
|
||||
library module.
|
||||
|
||||
## stdlib v2.3.x ##
|
||||
|
||||
While not yet released, the standard library may only work with Puppet 2.7.x.
|
||||
|
||||
# Functions #
|
||||
|
||||
Please see `puppet doc -r function` for documentation on each function. The
|
||||
current list of functions is:
|
||||
|
||||
* getvar
|
||||
* has\_key
|
||||
* loadyaml
|
||||
* merge.rb
|
||||
* validate\_array
|
||||
* validate\_bool
|
||||
* validate\_hash
|
||||
* validate\_re
|
||||
* validate\_string
|
||||
|
||||
## validate\_hash ##
|
||||
|
||||
$somehash = { 'one' => 'two' }
|
||||
validate\_hash($somehash)
|
||||
|
||||
## getvar() ##
|
||||
|
||||
This function aims to look up variables in user-defined namespaces within
|
||||
puppet. Note, if the namespace is a class, it should already be evaluated
|
||||
before the function is used.
|
||||
|
||||
$namespace = 'site::data'
|
||||
include "${namespace}"
|
||||
$myvar = getvar("${namespace}::myvar")
|
||||
|
||||
## Facts ##
|
||||
|
||||
Facts in `/etc/facter/facts.d` and `/etc/puppetlabs/facter/facts.d` are now loaded
|
||||
automatically. This is a direct copy of R.I. Pienaar's custom facter fact
|
||||
located at:
|
||||
[https://github.com/ripienaar/facter-facts/tree/master/facts-dot-d](https://github.com/ripienaar/facter-facts/tree/master/facts-dot-d)
|
||||
|
||||
stdlib releases beyond 2.x will not include external fact support using
|
||||
facts-dot-d. Instead, these versions of stdlib require Facter 2.0 which
|
||||
includes external fact support in the main Facter codebase.
|
||||
|
||||
Please see [2157](http://projects.puppetlabs.com/issues/2157) for more
|
||||
information.
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
Puppet Specific Facts
|
||||
=====================
|
||||
|
||||
Facter is meant to stand alone and apart from Puppet. However, Facter often
|
||||
runs inside Puppet and all custom facts included in the stdlib module will
|
||||
almost always be evaluated in the context of Puppet and Facter working
|
||||
together.
|
||||
|
||||
Still, we don't want to write custom facts that blow up in the users face if
|
||||
Puppet is not loaded in memory. This is often the case if the user run
|
||||
`facter` without also supplying the `--puppet` flag.
|
||||
|
||||
Ah! But Jeff, the custom fact won't be in the `$LOAD_PATH` unless the user
|
||||
supplies `--facter`! You might say...
|
||||
|
||||
Not (always) true I say! If the user happens to have a CWD of
|
||||
`<modulepath>/stdlib/lib` then the facts will automatically be evaluated and
|
||||
blow up.
|
||||
|
||||
In any event, it's pretty easy to write a fact that has no value if Puppet is
|
||||
not loaded. Simply do it like this:
|
||||
|
||||
Facter.add(:node_vardir) do
|
||||
setcode do
|
||||
# This will be nil if Puppet is not available.
|
||||
Facter::Util::PuppetSettings.with_puppet do
|
||||
Puppet[:vardir]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
The `Facter::Util::PuppetSettings.with_puppet` method accepts a block and
|
||||
yields to it only if the Puppet library is loaded. If the Puppet library is
|
||||
not loaded, then the method silently returns `nil` which Facter interprets as
|
||||
an undefined fact value. The net effect is that the fact won't be set.
|
|
@ -0,0 +1,25 @@
|
|||
# Contributing to this module #
|
||||
|
||||
* Work in a topic branch
|
||||
* Submit a github pull request
|
||||
* Address any comments / feeback
|
||||
* Merge into master using --no-ff
|
||||
|
||||
# Releasing this module #
|
||||
|
||||
* This module adheres to http://semver.org/
|
||||
* Look for API breaking changes using git diff vX.Y.Z..master
|
||||
* If no API breaking changes, the minor version may be bumped.
|
||||
* If there are API breaking changes, the major version must be bumped.
|
||||
* If there are only small minor changes, the patch version may be bumped.
|
||||
* Update the CHANGELOG
|
||||
* Update the Modulefile
|
||||
* Commit these changes with a message along the lines of "Update CHANGELOG and
|
||||
Modulefile for release"
|
||||
* Create an annotated tag with git tag -a vX.Y.Z -m 'version X.Y.Z' (NOTE the
|
||||
leading v as per semver.org)
|
||||
* Push the tag with git push origin --tags
|
||||
* Build a new package with puppet-module or the rake build task if it exists
|
||||
* Publish the new package to the forge
|
||||
* Bonus points for an announcement to puppet-users.
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
require 'rubygems'
|
||||
require 'puppetlabs_spec_helper/rake_tasks'
|
|
@ -0,0 +1,26 @@
|
|||
# This facter fact returns the value of the Puppet vardir setting for the node
|
||||
# running puppet or puppet agent. The intent is to enable Puppet modules to
|
||||
# automatically have insight into a place where they can place variable data,
|
||||
# regardless of the node's platform.
|
||||
#
|
||||
# The value should be directly usable in a File resource path attribute.
|
||||
|
||||
|
||||
begin
|
||||
require 'facter/util/puppet_settings'
|
||||
rescue LoadError => e
|
||||
# puppet apply does not add module lib directories to the $LOAD_PATH (See
|
||||
# #4248). It should (in the future) but for the time being we need to be
|
||||
# defensive which is what this rescue block is doing.
|
||||
rb_file = File.join(File.dirname(__FILE__), 'util', 'puppet_settings.rb')
|
||||
load rb_file if File.exists?(rb_file) or raise e
|
||||
end
|
||||
|
||||
Facter.add(:puppet_vardir) do
|
||||
setcode do
|
||||
# This will be nil if Puppet is not available.
|
||||
Facter::Util::PuppetSettings.with_puppet do
|
||||
Puppet[:vardir]
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,19 @@
|
|||
# A facter fact to determine the root home directory.
|
||||
# This varies on PE supported platforms and may be
|
||||
# reconfigured by the end user.
|
||||
|
||||
module Facter::Util::RootHome
|
||||
class << self
|
||||
def get_root_home
|
||||
root_ent = Facter::Util::Resolution.exec("getent passwd root")
|
||||
# The home directory is the sixth element in the passwd entry
|
||||
# If the platform doesn't have getent, root_ent will be nil and we should
|
||||
# return it straight away.
|
||||
root_ent && root_ent.split(":")[5]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Facter.add(:root_home) do
|
||||
setcode { Facter::Util::RootHome.get_root_home }
|
||||
end
|
|
@ -0,0 +1,21 @@
|
|||
module Facter
|
||||
module Util
|
||||
module PuppetSettings
|
||||
# This method is intended to provide a convenient way to evaluate a
|
||||
# Facter code block only if Puppet is loaded. This is to account for the
|
||||
# situation where the fact happens to be in the load path, but Puppet is
|
||||
# not loaded for whatever reason. Perhaps the user is simply running
|
||||
# facter without the --puppet flag and they happen to be working in a lib
|
||||
# directory of a module.
|
||||
def self.with_puppet
|
||||
begin
|
||||
Module.const_get("Puppet")
|
||||
rescue NameError
|
||||
nil
|
||||
else
|
||||
yield
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,36 @@
|
|||
#
|
||||
# abs.rb
|
||||
#
|
||||
|
||||
module Puppet::Parser::Functions
|
||||
newfunction(:abs, :type => :rvalue, :doc => <<-EOS
|
||||
Returns the absolute value of a number, for example -34.56 becomes
|
||||
34.56. Takes a single integer and float value as an argument.
|
||||
EOS
|
||||
) do |arguments|
|
||||
|
||||
raise(Puppet::ParseError, "abs(): Wrong number of arguments " +
|
||||
"given (#{arguments.size} for 1)") if arguments.size < 1
|
||||
|
||||
value = arguments[0]
|
||||
|
||||
# Numbers in Puppet are often string-encoded which is troublesome ...
|
||||
if value.is_a?(String)
|
||||
if value.match(/^-?(?:\d+)(?:\.\d+){1}$/)
|
||||
value = value.to_f
|
||||
elsif value.match(/^-?\d+$/)
|
||||
value = value.to_i
|
||||
else
|
||||
raise(Puppet::ParseError, 'abs(): Requires float or ' +
|
||||
'integer to work with')
|
||||
end
|
||||
end
|
||||
|
||||
# We have numeric value to handle ...
|
||||
result = value.abs
|
||||
|
||||
return result
|
||||
end
|
||||
end
|
||||
|
||||
# vim: set ts=2 sw=2 et :
|
|
@ -0,0 +1,49 @@
|
|||
#
|
||||
# bool2num.rb
|
||||
#
|
||||
|
||||
module Puppet::Parser::Functions
|
||||
newfunction(:bool2num, :type => :rvalue, :doc => <<-EOS
|
||||
Converts a boolean to a number. Converts the values:
|
||||
false, f, 0, n, and no to 0
|
||||
true, t, 1, y, and yes to 1
|
||||
Requires a single boolean or string as an input.
|
||||
EOS
|
||||
) do |arguments|
|
||||
|
||||
raise(Puppet::ParseError, "bool2num(): Wrong number of arguments " +
|
||||
"given (#{arguments.size} for 1)") if arguments.size < 1
|
||||
|
||||
value = arguments[0]
|
||||
klass = value.class
|
||||
|
||||
# We can have either true or false, or string which resembles boolean ...
|
||||
unless [FalseClass, TrueClass, String].include?(klass)
|
||||
raise(Puppet::ParseError, 'bool2num(): Requires either ' +
|
||||
'boolean or string to work with')
|
||||
end
|
||||
|
||||
if value.is_a?(String)
|
||||
# We consider all the yes, no, y, n and so on too ...
|
||||
value = case value
|
||||
#
|
||||
# This is how undef looks like in Puppet ...
|
||||
# We yield 0 (or false if you wish) in this case.
|
||||
#
|
||||
when /^$/, '' then false # Empty string will be false ...
|
||||
when /^(1|t|y|true|yes)$/ then true
|
||||
when /^(0|f|n|false|no)$/ then false
|
||||
when /^(undef|undefined)$/ then false # This is not likely to happen ...
|
||||
else
|
||||
raise(Puppet::ParseError, 'bool2num(): Unknown type of boolean given')
|
||||
end
|
||||
end
|
||||
|
||||
# We have real boolean values as well ...
|
||||
result = value ? 1 : 0
|
||||
|
||||
return result
|
||||
end
|
||||
end
|
||||
|
||||
# vim: set ts=2 sw=2 et :
|
|
@ -0,0 +1,34 @@
|
|||
#
|
||||
# capitalize.rb
|
||||
#
|
||||
|
||||
module Puppet::Parser::Functions
|
||||
newfunction(:capitalize, :type => :rvalue, :doc => <<-EOS
|
||||
Capitalizes the first letter of a string or array of strings.
|
||||
Requires either a single string or an array as an input.
|
||||
EOS
|
||||
) do |arguments|
|
||||
|
||||
raise(Puppet::ParseError, "capitalize(): Wrong number of arguments " +
|
||||
"given (#{arguments.size} for 1)") if arguments.size < 1
|
||||
|
||||
value = arguments[0]
|
||||
klass = value.class
|
||||
|
||||
unless [Array, String].include?(klass)
|
||||
raise(Puppet::ParseError, 'capitalize(): Requires either ' +
|
||||
'array or string to work with')
|
||||
end
|
||||
|
||||
if value.is_a?(Array)
|
||||
# Numbers in Puppet are often string-encoded which is troublesome ...
|
||||
result = value.collect { |i| i.is_a?(String) ? i.capitalize : i }
|
||||
else
|
||||
result = value.capitalize
|
||||
end
|
||||
|
||||
return result
|
||||
end
|
||||
end
|
||||
|
||||
# vim: set ts=2 sw=2 et :
|
|
@ -0,0 +1,35 @@
|
|||
#
|
||||
# chomp.rb
|
||||
#
|
||||
|
||||
module Puppet::Parser::Functions
|
||||
newfunction(:chomp, :type => :rvalue, :doc => <<-'EOS'
|
||||
Removes the record separator from the end of a string or an array of
|
||||
strings, for example `hello\n` becomes `hello`.
|
||||
Requires a single string or array as an input.
|
||||
EOS
|
||||
) do |arguments|
|
||||
|
||||
raise(Puppet::ParseError, "chomp(): Wrong number of arguments " +
|
||||
"given (#{arguments.size} for 1)") if arguments.size < 1
|
||||
|
||||
value = arguments[0]
|
||||
klass = value.class
|
||||
|
||||
unless [Array, String].include?(klass)
|
||||
raise(Puppet::ParseError, 'chomp(): Requires either ' +
|
||||
'array or string to work with')
|
||||
end
|
||||
|
||||
if value.is_a?(Array)
|
||||
# Numbers in Puppet are often string-encoded which is troublesome ...
|
||||
result = value.collect { |i| i.is_a?(String) ? i.chomp : i }
|
||||
else
|
||||
result = value.chomp
|
||||
end
|
||||
|
||||
return result
|
||||
end
|
||||
end
|
||||
|
||||
# vim: set ts=2 sw=2 et :
|
|
@ -0,0 +1,37 @@
|
|||
#
|
||||
# chop.rb
|
||||
#
|
||||
|
||||
module Puppet::Parser::Functions
|
||||
newfunction(:chop, :type => :rvalue, :doc => <<-'EOS'
|
||||
Returns a new string with the last character removed. If the string ends
|
||||
with `\r\n`, both characters are removed. Applying chop to an empty
|
||||
string returns an empty string. If you wish to merely remove record
|
||||
separators then you should use the `chomp` function.
|
||||
Requires a string or array of strings as input.
|
||||
EOS
|
||||
) do |arguments|
|
||||
|
||||
raise(Puppet::ParseError, "chop(): Wrong number of arguments " +
|
||||
"given (#{arguments.size} for 1)") if arguments.size < 1
|
||||
|
||||
value = arguments[0]
|
||||
klass = value.class
|
||||
|
||||
unless [Array, String].include?(klass)
|
||||
raise(Puppet::ParseError, 'chop(): Requires either an ' +
|
||||
'array or string to work with')
|
||||
end
|
||||
|
||||
if value.is_a?(Array)
|
||||
# Numbers in Puppet are often string-encoded which is troublesome ...
|
||||
result = value.collect { |i| i.is_a?(String) ? i.chop : i }
|
||||
else
|
||||
result = value.chop
|
||||
end
|
||||
|
||||
return result
|
||||
end
|
||||
end
|
||||
|
||||
# vim: set ts=2 sw=2 et :
|
|
@ -0,0 +1,34 @@
|
|||
#
|
||||
# delete.rb
|
||||
#
|
||||
|
||||
# TODO(Krzysztof Wilczynski): We need to add support for regular expression ...
|
||||
# TODO(Krzysztof Wilczynski): Support for strings and hashes too ...
|
||||
|
||||
module Puppet::Parser::Functions
|
||||
newfunction(:delete, :type => :rvalue, :doc => <<-EOS
|
||||
Deletes a selected element from an array.
|
||||
|
||||
*Examples:*
|
||||
|
||||
delete(['a','b','c'], 'b')
|
||||
|
||||
Would return: ['a','c']
|
||||
EOS
|
||||
) do |arguments|
|
||||
|
||||
if (arguments.size != 2) then
|
||||
raise(Puppet::ParseError, "delete(): Wrong number of arguments "+
|
||||
"given #{arguments.size} for 2")
|
||||
end
|
||||
|
||||
a = arguments[0]
|
||||
item = arguments[1]
|
||||
|
||||
a.delete(item)
|
||||
a
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
# vim: set ts=2 sw=2 et :
|
|
@ -0,0 +1,49 @@
|
|||
#
|
||||
# delete_at.rb
|
||||
#
|
||||
|
||||
module Puppet::Parser::Functions
|
||||
newfunction(:delete_at, :type => :rvalue, :doc => <<-EOS
|
||||
Deletes a determined indexed value from an array.
|
||||
|
||||
*Examples:*
|
||||
|
||||
delete_at(['a','b','c'], 1)
|
||||
|
||||
Would return: ['a','c']
|
||||
EOS
|
||||
) do |arguments|
|
||||
|
||||
raise(Puppet::ParseError, "delete_at(): Wrong number of arguments " +
|
||||
"given (#{arguments.size} for 2)") if arguments.size < 2
|
||||
|
||||
array = arguments[0]
|
||||
|
||||
unless array.is_a?(Array)
|
||||
raise(Puppet::ParseError, 'delete_at(): Requires array to work with')
|
||||
end
|
||||
|
||||
index = arguments[1]
|
||||
|
||||
if index.is_a?(String) and not index.match(/^\d+$/)
|
||||
raise(Puppet::ParseError, 'delete_at(): You must provide ' +
|
||||
'non-negative numeric index')
|
||||
end
|
||||
|
||||
result = array.clone
|
||||
|
||||
# Numbers in Puppet are often string-encoded which is troublesome ...
|
||||
index = index.to_i
|
||||
|
||||
if index > result.size - 1 # First element is at index 0 is it not?
|
||||
raise(Puppet::ParseError, 'delete_at(): Given index ' +
|
||||
'exceeds size of array given')
|
||||
end
|
||||
|
||||
result.delete_at(index) # We ignore the element that got deleted ...
|
||||
|
||||
return result
|
||||
end
|
||||
end
|
||||
|
||||
# vim: set ts=2 sw=2 et :
|
|
@ -0,0 +1,33 @@
|
|||
#
|
||||
# downcase.rb
|
||||
#
|
||||
|
||||
module Puppet::Parser::Functions
|
||||
newfunction(:downcase, :type => :rvalue, :doc => <<-EOS
|
||||
Converts the case of a string or all strings in an array to lower case.
|
||||
EOS
|
||||
) do |arguments|
|
||||
|
||||
raise(Puppet::ParseError, "downcase(): Wrong number of arguments " +
|
||||
"given (#{arguments.size} for 1)") if arguments.size < 1
|
||||
|
||||
value = arguments[0]
|
||||
klass = value.class
|
||||
|
||||
unless [Array, String].include?(klass)
|
||||
raise(Puppet::ParseError, 'downcase(): Requires either ' +
|
||||
'array or string to work with')
|
||||
end
|
||||
|
||||
if value.is_a?(Array)
|
||||
# Numbers in Puppet are often string-encoded which is troublesome ...
|
||||
result = value.collect { |i| i.is_a?(String) ? i.downcase : i }
|
||||
else
|
||||
result = value.downcase
|
||||
end
|
||||
|
||||
return result
|
||||
end
|
||||
end
|
||||
|
||||
# vim: set ts=2 sw=2 et :
|
|
@ -0,0 +1,28 @@
|
|||
#
|
||||
# empty.rb
|
||||
#
|
||||
|
||||
module Puppet::Parser::Functions
|
||||
newfunction(:empty, :type => :rvalue, :doc => <<-EOS
|
||||
Returns true if the variable is empty.
|
||||
EOS
|
||||
) do |arguments|
|
||||
|
||||
raise(Puppet::ParseError, "empty(): Wrong number of arguments " +
|
||||
"given (#{arguments.size} for 1)") if arguments.size < 1
|
||||
|
||||
value = arguments[0]
|
||||
klass = value.class
|
||||
|
||||
unless [Array, Hash, String].include?(klass)
|
||||
raise(Puppet::ParseError, 'empty(): Requires either ' +
|
||||
'array, hash or string to work with')
|
||||
end
|
||||
|
||||
result = value.empty?
|
||||
|
||||
return result
|
||||
end
|
||||
end
|
||||
|
||||
# vim: set ts=2 sw=2 et :
|
|
@ -0,0 +1,33 @@
|
|||
#
|
||||
# flatten.rb
|
||||
#
|
||||
|
||||
module Puppet::Parser::Functions
|
||||
newfunction(:flatten, :type => :rvalue, :doc => <<-EOS
|
||||
This function flattens any deeply nested arrays and returns a single flat array
|
||||
as a result.
|
||||
|
||||
*Examples:*
|
||||
|
||||
flatten(['a', ['b', ['c']]])
|
||||
|
||||
Would return: ['a','b','c']
|
||||
EOS
|
||||
) do |arguments|
|
||||
|
||||
raise(Puppet::ParseError, "flatten(): Wrong number of arguments " +
|
||||
"given (#{arguments.size} for 1)") if arguments.size < 1
|
||||
|
||||
array = arguments[0]
|
||||
|
||||
unless array.is_a?(Array)
|
||||
raise(Puppet::ParseError, 'flatten(): Requires array to work with')
|
||||
end
|
||||
|
||||
result = array.flatten
|
||||
|
||||
return result
|
||||
end
|
||||
end
|
||||
|
||||
# vim: set ts=2 sw=2 et :
|
|
@ -0,0 +1,46 @@
|
|||
#
|
||||
# fqdn_rotate.rb
|
||||
#
|
||||
|
||||
module Puppet::Parser::Functions
|
||||
newfunction(:fqdn_rotate, :type => :rvalue, :doc => <<-EOS
|
||||
Rotates an array a random number of times based on a nodes fqdn.
|
||||
EOS
|
||||
) do |arguments|
|
||||
|
||||
raise(Puppet::ParseError, "fqdn_rotate(): Wrong number of arguments " +
|
||||
"given (#{arguments.size} for 1)") if arguments.size < 1
|
||||
|
||||
value = arguments[0]
|
||||
klass = value.class
|
||||
require 'digest/md5'
|
||||
|
||||
unless [Array, String].include?(klass)
|
||||
raise(Puppet::ParseError, 'fqdn_rotate(): Requires either ' +
|
||||
'array or string to work with')
|
||||
end
|
||||
|
||||
result = value.clone
|
||||
|
||||
string = value.is_a?(String) ? true : false
|
||||
|
||||
# Check whether it makes sense to rotate ...
|
||||
return result if result.size <= 1
|
||||
|
||||
# We turn any string value into an array to be able to rotate ...
|
||||
result = string ? result.split('') : result
|
||||
|
||||
elements = result.size
|
||||
|
||||
srand(Digest::MD5.hexdigest([lookupvar('::fqdn'),arguments].join(':')).hex)
|
||||
rand(elements).times {
|
||||
result.push result.shift
|
||||
}
|
||||
|
||||
result = string ? result.join : result
|
||||
|
||||
return result
|
||||
end
|
||||
end
|
||||
|
||||
# vim: set ts=2 sw=2 et :
|
|
@ -0,0 +1,17 @@
|
|||
module Puppet::Parser::Functions
|
||||
newfunction(:get_module_path, :type =>:rvalue, :doc => <<-EOT
|
||||
Returns the absolute path of the specified module for the current
|
||||
environment.
|
||||
|
||||
Example:
|
||||
$module_path = get_module_path('stdlib')
|
||||
EOT
|
||||
) do |args|
|
||||
raise(Puppet::ParseError, "get_module_name(): Wrong number of arguments, expects one") unless args.size == 1
|
||||
if module_path = Puppet::Module.find(args[0], compiler.environment.to_s)
|
||||
module_path.path
|
||||
else
|
||||
raise(Puppet::ParseError, "Could not find module #{args[0]} in environment #{compiler.environment}")
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,26 @@
|
|||
module Puppet::Parser::Functions
|
||||
|
||||
newfunction(:getvar, :type => :rvalue, :doc => <<-'ENDHEREDOC') do |args|
|
||||
Lookup a variable in a remote namespace.
|
||||
|
||||
For example:
|
||||
|
||||
$foo = getvar('site::data::foo')
|
||||
# Equivalent to $foo = $site::data::foo
|
||||
|
||||
This is useful if the namespace itself is stored in a string:
|
||||
|
||||
$datalocation = 'site::data'
|
||||
$bar = getvar("${datalocation}::bar")
|
||||
# Equivalent to $bar = $site::data::bar
|
||||
ENDHEREDOC
|
||||
|
||||
unless args.length == 1
|
||||
raise Puppet::ParseError, ("getvar(): wrong number of arguments (#{args.length}; must be 1)")
|
||||
end
|
||||
|
||||
self.lookupvar("#{args[0]}")
|
||||
|
||||
end
|
||||
|
||||
end
|
|
@ -0,0 +1,33 @@
|
|||
#
|
||||
# grep.rb
|
||||
#
|
||||
|
||||
module Puppet::Parser::Functions
|
||||
newfunction(:grep, :type => :rvalue, :doc => <<-EOS
|
||||
This function searches through an array and returns any elements that match
|
||||
the provided regular expression.
|
||||
|
||||
*Examples:*
|
||||
|
||||
grep(['aaa','bbb','ccc','aaaddd'], 'aaa')
|
||||
|
||||
Would return:
|
||||
|
||||
['aaa','aaaddd']
|
||||
EOS
|
||||
) do |arguments|
|
||||
|
||||
if (arguments.size != 2) then
|
||||
raise(Puppet::ParseError, "grep(): Wrong number of arguments "+
|
||||
"given #{arguments.size} for 2")
|
||||
end
|
||||
|
||||
a = arguments[0]
|
||||
pattern = Regexp.new(arguments[1])
|
||||
|
||||
a.grep(pattern)
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
# vim: set ts=2 sw=2 et :
|
|
@ -0,0 +1,28 @@
|
|||
module Puppet::Parser::Functions
|
||||
|
||||
newfunction(:has_key, :type => :rvalue, :doc => <<-'ENDHEREDOC') do |args|
|
||||
Determine if a hash has a certain key value.
|
||||
|
||||
Example:
|
||||
|
||||
$my_hash = {'key_one' => 'value_one'}
|
||||
if has_key($my_hash, 'key_two') {
|
||||
notice('we will not reach here')
|
||||
}
|
||||
if has_key($my_hash, 'key_one') {
|
||||
notice('this will be printed')
|
||||
}
|
||||
|
||||
ENDHEREDOC
|
||||
|
||||
unless args.length == 2
|
||||
raise Puppet::ParseError, ("has_key(): wrong number of arguments (#{args.length}; must be 2)")
|
||||
end
|
||||
unless args[0].is_a?(Hash)
|
||||
raise Puppet::ParseError, "has_key(): expects the first argument to be a hash, got #{args[0].inspect} which is of type #{args[0].class}"
|
||||
end
|
||||
args[0].has_key?(args[1])
|
||||
|
||||
end
|
||||
|
||||
end
|
|
@ -0,0 +1,41 @@
|
|||
#
|
||||
# hash.rb
|
||||
#
|
||||
|
||||
module Puppet::Parser::Functions
|
||||
newfunction(:hash, :type => :rvalue, :doc => <<-EOS
|
||||
This function converts and array into a hash.
|
||||
|
||||
*Examples:*
|
||||
|
||||
hash(['a',1,'b',2,'c',3])
|
||||
|
||||
Would return: {'a'=>1,'b'=>2,'c'=>3}
|
||||
EOS
|
||||
) do |arguments|
|
||||
|
||||
raise(Puppet::ParseError, "hash(): Wrong number of arguments " +
|
||||
"given (#{arguments.size} for 1)") if arguments.size < 1
|
||||
|
||||
array = arguments[0]
|
||||
|
||||
unless array.is_a?(Array)
|
||||
raise(Puppet::ParseError, 'hash(): Requires array to work with')
|
||||
end
|
||||
|
||||
result = {}
|
||||
|
||||
begin
|
||||
# This is to make it compatible with older version of Ruby ...
|
||||
array = array.flatten
|
||||
result = Hash[*array]
|
||||
rescue Exception
|
||||
raise(Puppet::ParseError, 'hash(): Unable to compute ' +
|
||||
'hash from array given')
|
||||
end
|
||||
|
||||
return result
|
||||
end
|
||||
end
|
||||
|
||||
# vim: set ts=2 sw=2 et :
|
|
@ -0,0 +1,22 @@
|
|||
#
|
||||
# is_array.rb
|
||||
#
|
||||
|
||||
module Puppet::Parser::Functions
|
||||
newfunction(:is_array, :type => :rvalue, :doc => <<-EOS
|
||||
Returns true if the variable passed to this function is an array.
|
||||
EOS
|
||||
) do |arguments|
|
||||
|
||||
raise(Puppet::ParseError, "is_array(): Wrong number of arguments " +
|
||||
"given (#{arguments.size} for 1)") if arguments.size < 1
|
||||
|
||||
type = arguments[0]
|
||||
|
||||
result = type.is_a?(Array)
|
||||
|
||||
return result
|
||||
end
|
||||
end
|
||||
|
||||
# vim: set ts=2 sw=2 et :
|
|
@ -0,0 +1,47 @@
|
|||
#
|
||||
# is_domain_name.rb
|
||||
#
|
||||
|
||||
module Puppet::Parser::Functions
|
||||
newfunction(:is_domain_name, :type => :rvalue, :doc => <<-EOS
|
||||
Returns true if the string passed to this function is a syntactically correct domain name.
|
||||
EOS
|
||||
) do |arguments|
|
||||
|
||||
if (arguments.size != 1) then
|
||||
raise(Puppet::ParseError, "is_domain_name(): Wrong number of arguments "+
|
||||
"given #{arguments.size} for 1")
|
||||
end
|
||||
|
||||
domain = arguments[0]
|
||||
|
||||
# Limits (rfc1035, 3.1)
|
||||
domain_max_length=255
|
||||
label_min_length=1
|
||||
label_max_length=63
|
||||
|
||||
# Allow ".", it is the top level domain
|
||||
return true if domain == '.'
|
||||
|
||||
# Remove the final dot, if present.
|
||||
domain.chomp!('.')
|
||||
|
||||
# Check the whole domain
|
||||
return false if domain.empty?
|
||||
return false if domain.length > domain_max_length
|
||||
|
||||
# Check each label in the domain
|
||||
labels = domain.split('.')
|
||||
vlabels = labels.each do |label|
|
||||
break if label.length < label_min_length
|
||||
break if label.length > label_max_length
|
||||
break if label[-1..-1] == '-'
|
||||
break if label[0..0] == '-'
|
||||
break unless /^[a-z\d-]+$/i.match(label)
|
||||
end
|
||||
return vlabels == labels
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
# vim: set ts=2 sw=2 et :
|
|
@ -0,0 +1,27 @@
|
|||
#
|
||||
# is_float.rb
|
||||
#
|
||||
|
||||
module Puppet::Parser::Functions
|
||||
newfunction(:is_float, :type => :rvalue, :doc => <<-EOS
|
||||
Returns true if the variable passed to this function is a float.
|
||||
EOS
|
||||
) do |arguments|
|
||||
|
||||
if (arguments.size != 1) then
|
||||
raise(Puppet::ParseError, "is_float(): Wrong number of arguments "+
|
||||
"given #{arguments.size} for 1")
|
||||
end
|
||||
|
||||
value = arguments[0]
|
||||
|
||||
if value != value.to_f.to_s then
|
||||
return false
|
||||
else
|
||||
return true
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
# vim: set ts=2 sw=2 et :
|
|
@ -0,0 +1,22 @@
|
|||
#
|
||||
# is_hash.rb
|
||||
#
|
||||
|
||||
module Puppet::Parser::Functions
|
||||
newfunction(:is_hash, :type => :rvalue, :doc => <<-EOS
|
||||
Returns true if the variable passed to this function is a hash.
|
||||
EOS
|
||||
) do |arguments|
|
||||
|
||||
raise(Puppet::ParseError, "is_hash(): Wrong number of arguments " +
|
||||
"given (#{arguments.size} for 1)") if arguments.size != 1
|
||||
|
||||
type = arguments[0]
|
||||
|
||||
result = type.is_a?(Hash)
|
||||
|
||||
return result
|
||||
end
|
||||
end
|
||||
|
||||
# vim: set ts=2 sw=2 et :
|
|
@ -0,0 +1,27 @@
|
|||
#
|
||||
# is_integer.rb
|
||||
#
|
||||
|
||||
module Puppet::Parser::Functions
|
||||
newfunction(:is_integer, :type => :rvalue, :doc => <<-EOS
|
||||
Returns true if the variable returned to this string is an integer.
|
||||
EOS
|
||||
) do |arguments|
|
||||
|
||||
if (arguments.size != 1) then
|
||||
raise(Puppet::ParseError, "is_integer(): Wrong number of arguments "+
|
||||
"given #{arguments.size} for 1")
|
||||
end
|
||||
|
||||
value = arguments[0]
|
||||
|
||||
if value != value.to_i.to_s then
|
||||
return false
|
||||
else
|
||||
return true
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
# vim: set ts=2 sw=2 et :
|
|
@ -0,0 +1,32 @@
|
|||
#
|
||||
# is_ip_address.rb
|
||||
#
|
||||
|
||||
module Puppet::Parser::Functions
|
||||
newfunction(:is_ip_address, :type => :rvalue, :doc => <<-EOS
|
||||
Returns true if the string passed to this function is a valid IP address.
|
||||
EOS
|
||||
) do |arguments|
|
||||
|
||||
require 'ipaddr'
|
||||
|
||||
if (arguments.size != 1) then
|
||||
raise(Puppet::ParseError, "is_ip_address(): Wrong number of arguments "+
|
||||
"given #{arguments.size} for 1")
|
||||
end
|
||||
|
||||
begin
|
||||
ip = IPAddr.new(arguments[0])
|
||||
rescue ArgumentError
|
||||
return false
|
||||
end
|
||||
|
||||
if ip.ipv4? or ip.ipv6? then
|
||||
return true
|
||||
else
|
||||
return false
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# vim: set ts=2 sw=2 et :
|
|
@ -0,0 +1,27 @@
|
|||
#
|
||||
# is_mac_address.rb
|
||||
#
|
||||
|
||||
module Puppet::Parser::Functions
|
||||
newfunction(:is_mac_address, :type => :rvalue, :doc => <<-EOS
|
||||
Returns true if the string passed to this function is a valid mac address.
|
||||
EOS
|
||||
) do |arguments|
|
||||
|
||||
if (arguments.size != 1) then
|
||||
raise(Puppet::ParseError, "is_mac_address(): Wrong number of arguments "+
|
||||
"given #{arguments.size} for 1")
|
||||
end
|
||||
|
||||
mac = arguments[0]
|
||||
|
||||
if /^[a-fA-F0-9]{1,2}:[a-fA-F0-9]{1,2}:[a-fA-F0-9]{1,2}:[a-fA-F0-9]{1,2}:[a-fA-F0-9]{1,2}:[a-fA-F0-9]{1,2}$/.match(mac) then
|
||||
return true
|
||||
else
|
||||
return false
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
# vim: set ts=2 sw=2 et :
|
|
@ -0,0 +1,27 @@
|
|||
#
|
||||
# is_numeric.rb
|
||||
#
|
||||
|
||||
module Puppet::Parser::Functions
|
||||
newfunction(:is_numeric, :type => :rvalue, :doc => <<-EOS
|
||||
Returns true if the variable passed to this function is a number.
|
||||
EOS
|
||||
) do |arguments|
|
||||
|
||||
if (arguments.size != 1) then
|
||||
raise(Puppet::ParseError, "is_numeric(): Wrong number of arguments "+
|
||||
"given #{arguments.size} for 1")
|
||||
end
|
||||
|
||||
value = arguments[0]
|
||||
|
||||
if value == value.to_f.to_s or value == value.to_i.to_s then
|
||||
return true
|
||||
else
|
||||
return false
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
# vim: set ts=2 sw=2 et :
|
|
@ -0,0 +1,26 @@
|
|||
#
|
||||
# is_string.rb
|
||||
#
|
||||
|
||||
module Puppet::Parser::Functions
|
||||
newfunction(:is_string, :type => :rvalue, :doc => <<-EOS
|
||||
Returns true if the variable passed to this function is a string.
|
||||
EOS
|
||||
) do |arguments|
|
||||
|
||||
raise(Puppet::ParseError, "is_string(): Wrong number of arguments " +
|
||||
"given (#{arguments.size} for 1)") if arguments.size < 1
|
||||
|
||||
type = arguments[0]
|
||||
|
||||
result = type.is_a?(String)
|
||||
|
||||
if result and (type == type.to_f.to_s or type == type.to_i.to_s) then
|
||||
return false
|
||||
end
|
||||
|
||||
return result
|
||||
end
|
||||
end
|
||||
|
||||
# vim: set ts=2 sw=2 et :
|
|
@ -0,0 +1,41 @@
|
|||
#
|
||||
# join.rb
|
||||
#
|
||||
|
||||
module Puppet::Parser::Functions
|
||||
newfunction(:join, :type => :rvalue, :doc => <<-EOS
|
||||
This function joins an array into a string using a seperator.
|
||||
|
||||
*Examples:*
|
||||
|
||||
join(['a','b','c'], ",")
|
||||
|
||||
Would result in: "a,b,c"
|
||||
EOS
|
||||
) do |arguments|
|
||||
|
||||
# Technically we support two arguments but only first is mandatory ...
|
||||
raise(Puppet::ParseError, "join(): Wrong number of arguments " +
|
||||
"given (#{arguments.size} for 1)") if arguments.size < 1
|
||||
|
||||
array = arguments[0]
|
||||
|
||||
unless array.is_a?(Array)
|
||||
raise(Puppet::ParseError, 'join(): Requires array to work with')
|
||||
end
|
||||
|
||||
suffix = arguments[1] if arguments[1]
|
||||
|
||||
if suffix
|
||||
unless suffix.is_a?(String)
|
||||
raise(Puppet::ParseError, 'join(): Requires string to work with')
|
||||
end
|
||||
end
|
||||
|
||||
result = suffix ? array.join(suffix) : array.join
|
||||
|
||||
return result
|
||||
end
|
||||
end
|
||||
|
||||
# vim: set ts=2 sw=2 et :
|
|
@ -0,0 +1,26 @@
|
|||
#
|
||||
# keys.rb
|
||||
#
|
||||
|
||||
module Puppet::Parser::Functions
|
||||
newfunction(:keys, :type => :rvalue, :doc => <<-EOS
|
||||
Returns the keys of a hash as an array.
|
||||
EOS
|
||||
) do |arguments|
|
||||
|
||||
raise(Puppet::ParseError, "keys(): Wrong number of arguments " +
|
||||
"given (#{arguments.size} for 1)") if arguments.size < 1
|
||||
|
||||
hash = arguments[0]
|
||||
|
||||
unless hash.is_a?(Hash)
|
||||
raise(Puppet::ParseError, 'keys(): Requires hash to work with')
|
||||
end
|
||||
|
||||
result = hash.keys
|
||||
|
||||
return result
|
||||
end
|
||||
end
|
||||
|
||||
# vim: set ts=2 sw=2 et :
|
|
@ -0,0 +1,20 @@
|
|||
module Puppet::Parser::Functions
|
||||
|
||||
newfunction(:loadyaml, :type => :rvalue, :doc => <<-'ENDHEREDOC') do |args|
|
||||
Load a YAML file containing an array, string, or hash, and return the data
|
||||
in the corresponding native data type.
|
||||
|
||||
For example:
|
||||
|
||||
$myhash = loadyaml('/etc/puppet/data/myhash.yaml')
|
||||
ENDHEREDOC
|
||||
|
||||
unless args.length == 1
|
||||
raise Puppet::ParseError, ("loadyaml(): wrong number of arguments (#{args.length}; must be 1)")
|
||||
end
|
||||
|
||||
YAML.load_file(args[0])
|
||||
|
||||
end
|
||||
|
||||
end
|
|
@ -0,0 +1,33 @@
|
|||
#
|
||||
# lstrip.rb
|
||||
#
|
||||
|
||||
module Puppet::Parser::Functions
|
||||
newfunction(:lstrip, :type => :rvalue, :doc => <<-EOS
|
||||
Strips leading spaces to the left of a string.
|
||||
EOS
|
||||
) do |arguments|
|
||||
|
||||
raise(Puppet::ParseError, "lstrip(): Wrong number of arguments " +
|
||||
"given (#{arguments.size} for 1)") if arguments.size < 1
|
||||
|
||||
value = arguments[0]
|
||||
klass = value.class
|
||||
|
||||
unless [Array, String].include?(klass)
|
||||
raise(Puppet::ParseError, 'lstrip(): Requires either ' +
|
||||
'array or string to work with')
|
||||
end
|
||||
|
||||
if value.is_a?(Array)
|
||||
# Numbers in Puppet are often string-encoded which is troublesome ...
|
||||
result = value.collect { |i| i.is_a?(String) ? i.lstrip : i }
|
||||
else
|
||||
result = value.lstrip
|
||||
end
|
||||
|
||||
return result
|
||||
end
|
||||
end
|
||||
|
||||
# vim: set ts=2 sw=2 et :
|
|
@ -0,0 +1,44 @@
|
|||
#
|
||||
# member.rb
|
||||
#
|
||||
|
||||
# TODO(Krzysztof Wilczynski): We need to add support for regular expression ...
|
||||
# TODO(Krzysztof Wilczynski): Support for strings and hashes too ...
|
||||
|
||||
module Puppet::Parser::Functions
|
||||
newfunction(:member, :type => :rvalue, :doc => <<-EOS
|
||||
This function determines if a variable is a member of an array.
|
||||
|
||||
*Examples:*
|
||||
|
||||
member(['a','b'], 'b')
|
||||
|
||||
Would return: true
|
||||
|
||||
member(['a','b'], 'c')
|
||||
|
||||
Would return: false
|
||||
EOS
|
||||
) do |arguments|
|
||||
|
||||
raise(Puppet::ParseError, "member(): Wrong number of arguments " +
|
||||
"given (#{arguments.size} for 2)") if arguments.size < 2
|
||||
|
||||
array = arguments[0]
|
||||
|
||||
unless array.is_a?(Array)
|
||||
raise(Puppet::ParseError, 'member(): Requires array to work with')
|
||||
end
|
||||
|
||||
item = arguments[1]
|
||||
|
||||
raise(Puppet::ParseError, 'member(): You must provide item ' +
|
||||
'to search for within array given') if item.empty?
|
||||
|
||||
result = array.include?(item)
|
||||
|
||||
return result
|
||||
end
|
||||
end
|
||||
|
||||
# vim: set ts=2 sw=2 et :
|
|
@ -0,0 +1,33 @@
|
|||
module Puppet::Parser::Functions
|
||||
newfunction(:merge, :type => :rvalue, :doc => <<-'ENDHEREDOC') do |args|
|
||||
Merges two or more hashes together and returns the resulting hash.
|
||||
|
||||
For example:
|
||||
|
||||
$hash1 = {'one' => 1, 'two', => 2}
|
||||
$hash2 = {'two' => 'dos', 'three', => 'tres'}
|
||||
$merged_hash = merge($hash1, $hash2)
|
||||
# The resulting hash is equivalent to:
|
||||
# $merged_hash = {'one' => 1, 'two' => 'dos', 'three' => 'tres'}
|
||||
|
||||
When there is a duplicate key, the key in the rightmost hash will "win."
|
||||
|
||||
ENDHEREDOC
|
||||
|
||||
if args.length < 2
|
||||
raise Puppet::ParseError, ("merge(): wrong number of arguments (#{args.length}; must be at least 2)")
|
||||
end
|
||||
|
||||
# The hash we accumulate into
|
||||
accumulator = Hash.new
|
||||
# Merge into the accumulator hash
|
||||
args.each do |arg|
|
||||
unless arg.is_a?(Hash)
|
||||
raise Puppet::ParseError, "merge: unexpected argument type #{arg.class}, only expects hash arguments"
|
||||
end
|
||||
accumulator.merge!(arg)
|
||||
end
|
||||
# Return the fully merged hash
|
||||
accumulator
|
||||
end
|
||||
end
|
|
@ -0,0 +1,40 @@
|
|||
#
|
||||
# num2bool.rb
|
||||
#
|
||||
|
||||
# TODO(Krzysztof Wilczynski): We probably need to approach numeric values differently ...
|
||||
|
||||
module Puppet::Parser::Functions
|
||||
newfunction(:num2bool, :type => :rvalue, :doc => <<-EOS
|
||||
This function converts a number into a true boolean. Zero becomes false. Numbers
|
||||
higher then 0 become true.
|
||||
EOS
|
||||
) do |arguments|
|
||||
|
||||
raise(Puppet::ParseError, "num2bool(): Wrong number of arguments " +
|
||||
"given (#{arguments.size} for 1)") if arguments.size < 1
|
||||
|
||||
number = arguments[0]
|
||||
|
||||
# Only numbers allowed ...
|
||||
unless number.match(/^\-?\d+$/)
|
||||
raise(Puppet::ParseError, 'num2bool(): Requires integer to work with')
|
||||
end
|
||||
|
||||
result = case number
|
||||
when /^0$/
|
||||
false
|
||||
when /^\-?\d+$/
|
||||
# Numbers in Puppet are often string-encoded which is troublesome ...
|
||||
number = number.to_i
|
||||
# We yield true for any positive number and false otherwise ...
|
||||
number > 0 ? true : false
|
||||
else
|
||||
raise(Puppet::ParseError, 'num2bool(): Unknown numeric format given')
|
||||
end
|
||||
|
||||
return result
|
||||
end
|
||||
end
|
||||
|
||||
# vim: set ts=2 sw=2 et :
|
|
@ -0,0 +1,24 @@
|
|||
#
|
||||
# parsejson.rb
|
||||
#
|
||||
|
||||
module Puppet::Parser::Functions
|
||||
newfunction(:parsejson, :type => :rvalue, :doc => <<-EOS
|
||||
This function accepts JSON as a string and converts into the correct Puppet
|
||||
structure.
|
||||
EOS
|
||||
) do |arguments|
|
||||
|
||||
if (arguments.size != 1) then
|
||||
raise(Puppet::ParseError, "parsejson(): Wrong number of arguments "+
|
||||
"given #{arguments.size} for 1")
|
||||
end
|
||||
|
||||
json = arguments[0]
|
||||
|
||||
# PSON is natively available in puppet
|
||||
PSON.load(json)
|
||||
end
|
||||
end
|
||||
|
||||
# vim: set ts=2 sw=2 et :
|
|
@ -0,0 +1,24 @@
|
|||
#
|
||||
# parseyaml.rb
|
||||
#
|
||||
|
||||
module Puppet::Parser::Functions
|
||||
newfunction(:parseyaml, :type => :rvalue, :doc => <<-EOS
|
||||
This function accepts YAML as a string and converts it into the correct
|
||||
Puppet structure.
|
||||
EOS
|
||||
) do |arguments|
|
||||
|
||||
if (arguments.size != 1) then
|
||||
raise(Puppet::ParseError, "parseyaml(): Wrong number of arguments "+
|
||||
"given #{arguments.size} for 1")
|
||||
end
|
||||
|
||||
require 'yaml'
|
||||
|
||||
YAML::load(arguments[0])
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
# vim: set ts=2 sw=2 et :
|
|
@ -0,0 +1,45 @@
|
|||
#
|
||||
# prefix.rb
|
||||
#
|
||||
|
||||
module Puppet::Parser::Functions
|
||||
newfunction(:prefix, :type => :rvalue, :doc => <<-EOS
|
||||
This function applies a prefix to all elements in an array.
|
||||
|
||||
*Examles:*
|
||||
|
||||
prefix(['a','b','c'], 'p')
|
||||
|
||||
Will return: ['pa','pb','pc']
|
||||
EOS
|
||||
) do |arguments|
|
||||
|
||||
# Technically we support two arguments but only first is mandatory ...
|
||||
raise(Puppet::ParseError, "prefix(): Wrong number of arguments " +
|
||||
"given (#{arguments.size} for 1)") if arguments.size < 1
|
||||
|
||||
array = arguments[0]
|
||||
|
||||
unless array.is_a?(Array)
|
||||
raise(Puppet::ParseError, 'prefix(): Requires array to work with')
|
||||
end
|
||||
|
||||
prefix = arguments[1] if arguments[1]
|
||||
|
||||
if prefix
|
||||
unless prefix.is_a?(String)
|
||||
raise(Puppet::ParseError, 'prefix(): Requires string to work with')
|
||||
end
|
||||
end
|
||||
|
||||
# Turn everything into string same as join would do ...
|
||||
result = array.collect do |i|
|
||||
i = i.to_s
|
||||
prefix ? prefix + i : i
|
||||
end
|
||||
|
||||
return result
|
||||
end
|
||||
end
|
||||
|
||||
# vim: set ts=2 sw=2 et :
|
|
@ -0,0 +1,80 @@
|
|||
#
|
||||
# range.rb
|
||||
#
|
||||
|
||||
# TODO(Krzysztof Wilczynski): We probably need to approach numeric values differently ...
|
||||
|
||||
module Puppet::Parser::Functions
|
||||
newfunction(:range, :type => :rvalue, :doc => <<-EOS
|
||||
When given range in the form of (start, stop) it will extrapolate a range as
|
||||
an array.
|
||||
|
||||
*Examples:*
|
||||
|
||||
range("0", "9")
|
||||
|
||||
Will return: [0,1,2,3,4,5,6,7,8,9]
|
||||
|
||||
range("00", "09")
|
||||
|
||||
Will return: [0,1,2,3,4,5,6,7,8,9] (Zero padded strings are converted to
|
||||
integers automatically)
|
||||
|
||||
range("a", "c")
|
||||
|
||||
Will return: ["a","b","c"]
|
||||
|
||||
range("host01", "host10")
|
||||
|
||||
Will return: ["host01", "host02", ..., "host09", "host10"]
|
||||
EOS
|
||||
) do |arguments|
|
||||
|
||||
# We support more than one argument but at least one is mandatory ...
|
||||
raise(Puppet::ParseError, "range(): Wrong number of " +
|
||||
"arguments given (#{arguments.size} for 1)") if arguments.size < 1
|
||||
|
||||
if arguments.size > 1
|
||||
start = arguments[0]
|
||||
stop = arguments[1]
|
||||
|
||||
type = '..' # We select simplest type for Range available in Ruby ...
|
||||
|
||||
elsif arguments.size > 0
|
||||
value = arguments[0]
|
||||
|
||||
if m = value.match(/^(\w+)(\.\.\.?|\-)(\w+)$/)
|
||||
start = m[1]
|
||||
stop = m[3]
|
||||
|
||||
type = m[2]
|
||||
|
||||
elsif value.match(/^.+$/)
|
||||
raise(Puppet::ParseError, 'range(): Unable to compute range ' +
|
||||
'from the value given')
|
||||
else
|
||||
raise(Puppet::ParseError, 'range(): Unknown format of range given')
|
||||
end
|
||||
end
|
||||
|
||||
# Check whether we have integer value if so then make it so ...
|
||||
if start.match(/^\d+$/)
|
||||
start = start.to_i
|
||||
stop = stop.to_i
|
||||
else
|
||||
start = start.to_s
|
||||
stop = stop.to_s
|
||||
end
|
||||
|
||||
range = case type
|
||||
when /^(\.\.|\-)$/ then (start .. stop)
|
||||
when /^(\.\.\.)$/ then (start ... stop) # Exclusive of last element ...
|
||||
end
|
||||
|
||||
result = range.collect { |i| i } # Get them all ... Pokemon ...
|
||||
|
||||
return result
|
||||
end
|
||||
end
|
||||
|
||||
# vim: set ts=2 sw=2 et :
|
|
@ -0,0 +1,28 @@
|
|||
#
|
||||
# reverse.rb
|
||||
#
|
||||
|
||||
module Puppet::Parser::Functions
|
||||
newfunction(:reverse, :type => :rvalue, :doc => <<-EOS
|
||||
Reverses the order of a string or array.
|
||||
EOS
|
||||
) do |arguments|
|
||||
|
||||
raise(Puppet::ParseError, "reverse(): Wrong number of arguments " +
|
||||
"given (#{arguments.size} for 1)") if arguments.size < 1
|
||||
|
||||
value = arguments[0]
|
||||
klass = value.class
|
||||
|
||||
unless [Array, String].include?(klass)
|
||||
raise(Puppet::ParseError, 'reverse(): Requires either ' +
|
||||
'array or string to work with')
|
||||
end
|
||||
|
||||
result = value.reverse
|
||||
|
||||
return result
|
||||
end
|
||||
end
|
||||
|
||||
# vim: set ts=2 sw=2 et :
|
|
@ -0,0 +1,32 @@
|
|||
#
|
||||
# rstrip.rb
|
||||
#
|
||||
|
||||
module Puppet::Parser::Functions
|
||||
newfunction(:rstrip, :type => :rvalue, :doc => <<-EOS
|
||||
Strips leading spaces to the right of the string.
|
||||
EOS
|
||||
) do |arguments|
|
||||
|
||||
raise(Puppet::ParseError, "rstrip(): Wrong number of arguments " +
|
||||
"given (#{arguments.size} for 1)") if arguments.size < 1
|
||||
|
||||
value = arguments[0]
|
||||
klass = value.class
|
||||
|
||||
unless [Array, String].include?(klass)
|
||||
raise(Puppet::ParseError, 'rstrip(): Requires either ' +
|
||||
'array or string to work with')
|
||||
end
|
||||
|
||||
if value.is_a?(Array)
|
||||
result = value.collect { |i| i.is_a?(String) ? i.rstrip : i }
|
||||
else
|
||||
result = value.rstrip
|
||||
end
|
||||
|
||||
return result
|
||||
end
|
||||
end
|
||||
|
||||
# vim: set ts=2 sw=2 et :
|
|
@ -0,0 +1,46 @@
|
|||
#
|
||||
# shuffle.rb
|
||||
#
|
||||
|
||||
module Puppet::Parser::Functions
|
||||
newfunction(:shuffle, :type => :rvalue, :doc => <<-EOS
|
||||
Randomizes the order of a string or array elements.
|
||||
EOS
|
||||
) do |arguments|
|
||||
|
||||
raise(Puppet::ParseError, "shuffle(): Wrong number of arguments " +
|
||||
"given (#{arguments.size} for 1)") if arguments.size < 1
|
||||
|
||||
value = arguments[0]
|
||||
klass = value.class
|
||||
|
||||
unless [Array, String].include?(klass)
|
||||
raise(Puppet::ParseError, 'shuffle(): Requires either ' +
|
||||
'array or string to work with')
|
||||
end
|
||||
|
||||
result = value.clone
|
||||
|
||||
string = value.is_a?(String) ? true : false
|
||||
|
||||
# Check whether it makes sense to shuffle ...
|
||||
return result if result.size <= 1
|
||||
|
||||
# We turn any string value into an array to be able to shuffle ...
|
||||
result = string ? result.split('') : result
|
||||
|
||||
elements = result.size
|
||||
|
||||
# Simple implementation of Fisher–Yates in-place shuffle ...
|
||||
elements.times do |i|
|
||||
j = rand(elements - i) + i
|
||||
result[j], result[i] = result[i], result[j]
|
||||
end
|
||||
|
||||
result = string ? result.join : result
|
||||
|
||||
return result
|
||||
end
|
||||
end
|
||||
|
||||
# vim: set ts=2 sw=2 et :
|
|
@ -0,0 +1,48 @@
|
|||
#
|
||||
# size.rb
|
||||
#
|
||||
|
||||
# TODO(Krzysztof Wilczynski): Support for hashes would be nice too ...
|
||||
|
||||
module Puppet::Parser::Functions
|
||||
newfunction(:size, :type => :rvalue, :doc => <<-EOS
|
||||
Returns the number of elements in a string or array.
|
||||
EOS
|
||||
) do |arguments|
|
||||
|
||||
raise(Puppet::ParseError, "size(): Wrong number of arguments " +
|
||||
"given (#{arguments.size} for 1)") if arguments.size < 1
|
||||
|
||||
item = arguments[0]
|
||||
|
||||
if item.is_a?(String)
|
||||
|
||||
begin
|
||||
#
|
||||
# Check whether your item is a numeric value or not ...
|
||||
# This will take care about positive and/or negative numbers
|
||||
# for both integer and floating-point values ...
|
||||
#
|
||||
# Please note that Puppet has no notion of hexadecimal
|
||||
# nor octal numbers for its DSL at this point in time ...
|
||||
#
|
||||
Float(item)
|
||||
|
||||
raise(Puppet::ParseError, 'size(): Requires either ' +
|
||||
'string or array to work with')
|
||||
|
||||
rescue ArgumentError
|
||||
result = item.size
|
||||
end
|
||||
|
||||
elsif item.is_a?(Array)
|
||||
result = item.size
|
||||
else
|
||||
raise(Puppet::ParseError, 'size(): Unknown type given')
|
||||
end
|
||||
|
||||
return result
|
||||
end
|
||||
end
|
||||
|
||||
# vim: set ts=2 sw=2 et :
|
|
@ -0,0 +1,27 @@
|
|||
#
|
||||
# sort.rb
|
||||
#
|
||||
|
||||
module Puppet::Parser::Functions
|
||||
newfunction(:sort, :type => :rvalue, :doc => <<-EOS
|
||||
Sorts strings and arrays lexically.
|
||||
EOS
|
||||
) do |arguments|
|
||||
|
||||
if (arguments.size != 1) then
|
||||
raise(Puppet::ParseError, "sort(): Wrong number of arguments "+
|
||||
"given #{arguments.size} for 1")
|
||||
end
|
||||
|
||||
value = arguments[0]
|
||||
|
||||
if value.is_a?(Array) then
|
||||
value.sort
|
||||
elsif value.is_a?(String) then
|
||||
value.split("").sort.join("")
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
# vim: set ts=2 sw=2 et :
|
|
@ -0,0 +1,36 @@
|
|||
#
|
||||
# squeeze.rb
|
||||
#
|
||||
|
||||
module Puppet::Parser::Functions
|
||||
newfunction(:squeeze, :type => :rvalue, :doc => <<-EOS
|
||||
Returns a new string where runs of the same character that occur in this set are replaced by a single character.
|
||||
EOS
|
||||
) do |arguments|
|
||||
|
||||
if ((arguments.size != 2) and (arguments.size != 1)) then
|
||||
raise(Puppet::ParseError, "squeeze(): Wrong number of arguments "+
|
||||
"given #{arguments.size} for 2 or 1")
|
||||
end
|
||||
|
||||
item = arguments[0]
|
||||
squeezeval = arguments[1]
|
||||
|
||||
if item.is_a?(Array) then
|
||||
if squeezeval then
|
||||
item.collect { |i| i.squeeze(squeezeval) }
|
||||
else
|
||||
item.collect { |i| i.squeeze }
|
||||
end
|
||||
else
|
||||
if squeezeval then
|
||||
item.squeeze(squeezeval)
|
||||
else
|
||||
item.squeeze
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
# vim: set ts=2 sw=2 et :
|
|
@ -0,0 +1,41 @@
|
|||
#
|
||||
# str2bool.rb
|
||||
#
|
||||
|
||||
module Puppet::Parser::Functions
|
||||
newfunction(:str2bool, :type => :rvalue, :doc => <<-EOS
|
||||
This converts a string to a boolean. This attempt to convert strings that
|
||||
contain things like: y, 1, t, true to 'true' and strings that contain things
|
||||
like: 0, f, n, false, no to 'false'.
|
||||
EOS
|
||||
) do |arguments|
|
||||
|
||||
raise(Puppet::ParseError, "str2bool(): Wrong number of arguments " +
|
||||
"given (#{arguments.size} for 1)") if arguments.size < 1
|
||||
|
||||
string = arguments[0]
|
||||
|
||||
unless string.is_a?(String)
|
||||
raise(Puppet::ParseError, 'str2bool(): Requires either ' +
|
||||
'string to work with')
|
||||
end
|
||||
|
||||
# We consider all the yes, no, y, n and so on too ...
|
||||
result = case string
|
||||
#
|
||||
# This is how undef looks like in Puppet ...
|
||||
# We yield false in this case.
|
||||
#
|
||||
when /^$/, '' then false # Empty string will be false ...
|
||||
when /^(1|t|y|true|yes)$/ then true
|
||||
when /^(0|f|n|false|no)$/ then false
|
||||
when /^(undef|undefined)$/ then false # This is not likely to happen ...
|
||||
else
|
||||
raise(Puppet::ParseError, 'str2bool(): Unknown type of boolean given')
|
||||
end
|
||||
|
||||
return result
|
||||
end
|
||||
end
|
||||
|
||||
# vim: set ts=2 sw=2 et :
|
|
@ -0,0 +1,32 @@
|
|||
#
|
||||
# str2saltedsha512.rb
|
||||
#
|
||||
|
||||
module Puppet::Parser::Functions
|
||||
newfunction(:str2saltedsha512, :type => :rvalue, :doc => <<-EOS
|
||||
This converts a string to a salted-SHA512 password hash (which is used for
|
||||
OS X versions >= 10.7). Given any simple string, you will get a hex version
|
||||
of a salted-SHA512 password hash that can be inserted into your Puppet
|
||||
manifests as a valid password attribute.
|
||||
EOS
|
||||
) do |arguments|
|
||||
require 'digest/sha2'
|
||||
|
||||
raise(Puppet::ParseError, "str2saltedsha512(): Wrong number of arguments " +
|
||||
"passed (#{arguments.size} but we require 1)") if arguments.size != 1
|
||||
|
||||
password = arguments[0]
|
||||
|
||||
unless password.is_a?(String)
|
||||
raise(Puppet::ParseError, 'str2saltedsha512(): Requires a ' +
|
||||
"String argument, you passed: #{password.class}")
|
||||
end
|
||||
|
||||
seedint = rand(2**31 - 1)
|
||||
seedstring = Array(seedint).pack("L")
|
||||
saltedpass = Digest::SHA512.digest(seedstring + password)
|
||||
(seedstring + saltedpass).unpack('H*')[0]
|
||||
end
|
||||
end
|
||||
|
||||
# vim: set ts=2 sw=2 et :
|
|
@ -0,0 +1,107 @@
|
|||
#
|
||||
# strftime.rb
|
||||
#
|
||||
|
||||
module Puppet::Parser::Functions
|
||||
newfunction(:strftime, :type => :rvalue, :doc => <<-EOS
|
||||
This function returns formatted time.
|
||||
|
||||
*Examples:*
|
||||
|
||||
To return the time since epoch:
|
||||
|
||||
strftime("%s")
|
||||
|
||||
To return the date:
|
||||
|
||||
strftime("%Y-%m-%d")
|
||||
|
||||
*Format meaning:*
|
||||
|
||||
%a - The abbreviated weekday name (``Sun'')
|
||||
%A - The full weekday name (``Sunday'')
|
||||
%b - The abbreviated month name (``Jan'')
|
||||
%B - The full month name (``January'')
|
||||
%c - The preferred local date and time representation
|
||||
%C - Century (20 in 2009)
|
||||
%d - Day of the month (01..31)
|
||||
%D - Date (%m/%d/%y)
|
||||
%e - Day of the month, blank-padded ( 1..31)
|
||||
%F - Equivalent to %Y-%m-%d (the ISO 8601 date format)
|
||||
%h - Equivalent to %b
|
||||
%H - Hour of the day, 24-hour clock (00..23)
|
||||
%I - Hour of the day, 12-hour clock (01..12)
|
||||
%j - Day of the year (001..366)
|
||||
%k - hour, 24-hour clock, blank-padded ( 0..23)
|
||||
%l - hour, 12-hour clock, blank-padded ( 0..12)
|
||||
%L - Millisecond of the second (000..999)
|
||||
%m - Month of the year (01..12)
|
||||
%M - Minute of the hour (00..59)
|
||||
%n - Newline (\n)
|
||||
%N - Fractional seconds digits, default is 9 digits (nanosecond)
|
||||
%3N millisecond (3 digits)
|
||||
%6N microsecond (6 digits)
|
||||
%9N nanosecond (9 digits)
|
||||
%p - Meridian indicator (``AM'' or ``PM'')
|
||||
%P - Meridian indicator (``am'' or ``pm'')
|
||||
%r - time, 12-hour (same as %I:%M:%S %p)
|
||||
%R - time, 24-hour (%H:%M)
|
||||
%s - Number of seconds since 1970-01-01 00:00:00 UTC.
|
||||
%S - Second of the minute (00..60)
|
||||
%t - Tab character (\t)
|
||||
%T - time, 24-hour (%H:%M:%S)
|
||||
%u - Day of the week as a decimal, Monday being 1. (1..7)
|
||||
%U - Week number of the current year,
|
||||
starting with the first Sunday as the first
|
||||
day of the first week (00..53)
|
||||
%v - VMS date (%e-%b-%Y)
|
||||
%V - Week number of year according to ISO 8601 (01..53)
|
||||
%W - Week number of the current year,
|
||||
starting with the first Monday as the first
|
||||
day of the first week (00..53)
|
||||
%w - Day of the week (Sunday is 0, 0..6)
|
||||
%x - Preferred representation for the date alone, no time
|
||||
%X - Preferred representation for the time alone, no date
|
||||
%y - Year without a century (00..99)
|
||||
%Y - Year with century
|
||||
%z - Time zone as hour offset from UTC (e.g. +0900)
|
||||
%Z - Time zone name
|
||||
%% - Literal ``%'' character
|
||||
EOS
|
||||
) do |arguments|
|
||||
|
||||
# Technically we support two arguments but only first is mandatory ...
|
||||
raise(Puppet::ParseError, "strftime(): Wrong number of arguments " +
|
||||
"given (#{arguments.size} for 1)") if arguments.size < 1
|
||||
|
||||
format = arguments[0]
|
||||
|
||||
raise(Puppet::ParseError, 'strftime(): You must provide ' +
|
||||
'format for evaluation') if format.empty?
|
||||
|
||||
# The Time Zone argument is optional ...
|
||||
time_zone = arguments[1] if arguments[1]
|
||||
|
||||
time = Time.new
|
||||
|
||||
# There is probably a better way to handle Time Zone ...
|
||||
if time_zone and not time_zone.empty?
|
||||
original_zone = ENV['TZ']
|
||||
|
||||
local_time = time.clone
|
||||
local_time = local_time.utc
|
||||
|
||||
ENV['TZ'] = time_zone
|
||||
|
||||
time = local_time.localtime
|
||||
|
||||
ENV['TZ'] = original_zone
|
||||
end
|
||||
|
||||
result = time.strftime(format)
|
||||
|
||||
return result
|
||||
end
|
||||
end
|
||||
|
||||
# vim: set ts=2 sw=2 et :
|
|
@ -0,0 +1,39 @@
|
|||
#
|
||||
# strip.rb
|
||||
#
|
||||
|
||||
module Puppet::Parser::Functions
|
||||
newfunction(:strip, :type => :rvalue, :doc => <<-EOS
|
||||
This function removes leading and trailing whitespace from a string or from
|
||||
every string inside an array.
|
||||
|
||||
*Examples:*
|
||||
|
||||
strip(" aaa ")
|
||||
|
||||
Would result in: "aaa"
|
||||
EOS
|
||||
) do |arguments|
|
||||
|
||||
raise(Puppet::ParseError, "strip(): Wrong number of arguments " +
|
||||
"given (#{arguments.size} for 1)") if arguments.size < 1
|
||||
|
||||
value = arguments[0]
|
||||
klass = value.class
|
||||
|
||||
unless [Array, String].include?(klass)
|
||||
raise(Puppet::ParseError, 'strip(): Requires either ' +
|
||||
'array or string to work with')
|
||||
end
|
||||
|
||||
if value.is_a?(Array)
|
||||
result = value.collect { |i| i.is_a?(String) ? i.strip : i }
|
||||
else
|
||||
result = value.strip
|
||||
end
|
||||
|
||||
return result
|
||||
end
|
||||
end
|
||||
|
||||
# vim: set ts=2 sw=2 et :
|
|
@ -0,0 +1,39 @@
|
|||
#
|
||||
# swapcase.rb
|
||||
#
|
||||
|
||||
module Puppet::Parser::Functions
|
||||
newfunction(:swapcase, :type => :rvalue, :doc => <<-EOS
|
||||
This function will swap the existing case of a string.
|
||||
|
||||
*Examples:*
|
||||
|
||||
swapcase("aBcD")
|
||||
|
||||
Would result in: "AbCd"
|
||||
EOS
|
||||
) do |arguments|
|
||||
|
||||
raise(Puppet::ParseError, "swapcase(): Wrong number of arguments " +
|
||||
"given (#{arguments.size} for 1)") if arguments.size < 1
|
||||
|
||||
value = arguments[0]
|
||||
klass = value.class
|
||||
|
||||
unless [Array, String].include?(klass)
|
||||
raise(Puppet::ParseError, 'swapcase(): Requires either ' +
|
||||
'array or string to work with')
|
||||
end
|
||||
|
||||
if value.is_a?(Array)
|
||||
# Numbers in Puppet are often string-encoded which is troublesome ...
|
||||
result = value.collect { |i| i.is_a?(String) ? i.swapcase : i }
|
||||
else
|
||||
result = value.swapcase
|
||||
end
|
||||
|
||||
return result
|
||||
end
|
||||
end
|
||||
|
||||
# vim: set ts=2 sw=2 et :
|
|
@ -0,0 +1,49 @@
|
|||
#
|
||||
# time.rb
|
||||
#
|
||||
|
||||
module Puppet::Parser::Functions
|
||||
newfunction(:time, :type => :rvalue, :doc => <<-EOS
|
||||
This function will return the current time since epoch as an integer.
|
||||
|
||||
*Examples:*
|
||||
|
||||
time()
|
||||
|
||||
Will return something like: 1311972653
|
||||
EOS
|
||||
) do |arguments|
|
||||
|
||||
# The Time Zone argument is optional ...
|
||||
time_zone = arguments[0] if arguments[0]
|
||||
|
||||
if (arguments.size != 0) and (arguments.size != 1) then
|
||||
raise(Puppet::ParseError, "time(): Wrong number of arguments "+
|
||||
"given #{arguments.size} for 0 or 1")
|
||||
end
|
||||
|
||||
time = Time.new
|
||||
|
||||
# There is probably a better way to handle Time Zone ...
|
||||
if time_zone and not time_zone.empty?
|
||||
original_zone = ENV['TZ']
|
||||
|
||||
local_time = time.clone
|
||||
local_time = local_time.utc
|
||||
|
||||
ENV['TZ'] = time_zone
|
||||
|
||||
time = local_time.localtime
|
||||
|
||||
ENV['TZ'] = original_zone
|
||||
end
|
||||
|
||||
# Calling Time#to_i on a receiver changes it. Trust me I am the Doctor.
|
||||
result = time.strftime('%s')
|
||||
result = result.to_i
|
||||
|
||||
return result
|
||||
end
|
||||
end
|
||||
|
||||
# vim: set ts=2 sw=2 et :
|
|
@ -0,0 +1,50 @@
|
|||
#
|
||||
# type.rb
|
||||
#
|
||||
|
||||
module Puppet::Parser::Functions
|
||||
newfunction(:type, :type => :rvalue, :doc => <<-EOS
|
||||
Returns the type when passed a variable. Type can be one of:
|
||||
|
||||
* string
|
||||
* array
|
||||
* hash
|
||||
* float
|
||||
* integer
|
||||
* boolean
|
||||
EOS
|
||||
) do |arguments|
|
||||
|
||||
raise(Puppet::ParseError, "type(): Wrong number of arguments " +
|
||||
"given (#{arguments.size} for 1)") if arguments.size < 1
|
||||
|
||||
value = arguments[0]
|
||||
|
||||
klass = value.class
|
||||
|
||||
if not [TrueClass, FalseClass, Array, Bignum, Fixnum, Float, Hash, String].include?(klass)
|
||||
raise(Puppet::ParseError, 'type(): Unknown type')
|
||||
end
|
||||
|
||||
klass = klass.to_s # Ugly ...
|
||||
|
||||
# We note that Integer is the parent to Bignum and Fixnum ...
|
||||
result = case klass
|
||||
when /^(?:Big|Fix)num$/ then 'integer'
|
||||
when /^(?:True|False)Class$/ then 'boolean'
|
||||
else klass
|
||||
end
|
||||
|
||||
if result == "String" then
|
||||
if value == value.to_i.to_s then
|
||||
result = "Integer"
|
||||
elsif value == value.to_f.to_s then
|
||||
result = "Float"
|
||||
end
|
||||
end
|
||||
|
||||
return result.downcase
|
||||
end
|
||||
end
|
||||
|
||||
# vim: set ts=2 sw=2 et :
|
|
@ -0,0 +1,51 @@
|
|||
#
|
||||
# unique.rb
|
||||
#
|
||||
|
||||
module Puppet::Parser::Functions
|
||||
newfunction(:unique, :type => :rvalue, :doc => <<-EOS
|
||||
This function will remove duplicates from strings and arrays.
|
||||
|
||||
*Examples:*
|
||||
|
||||
unique("aabbcc")
|
||||
|
||||
Will return:
|
||||
|
||||
abc
|
||||
|
||||
You can also use this with arrays:
|
||||
|
||||
unique(["a","a","b","b","c","c"])
|
||||
|
||||
This returns:
|
||||
|
||||
["a","b","c"]
|
||||
EOS
|
||||
) do |arguments|
|
||||
|
||||
raise(Puppet::ParseError, "unique(): Wrong number of arguments " +
|
||||
"given (#{arguments.size} for 1)") if arguments.size < 1
|
||||
|
||||
value = arguments[0]
|
||||
klass = value.class
|
||||
|
||||
unless [Array, String].include?(klass)
|
||||
raise(Puppet::ParseError, 'unique(): Requires either ' +
|
||||
'array or string to work with')
|
||||
end
|
||||
|
||||
result = value.clone
|
||||
|
||||
string = value.is_a?(String) ? true : false
|
||||
|
||||
# We turn any string value into an array to be able to shuffle ...
|
||||
result = string ? result.split('') : result
|
||||
result = result.uniq # Remove duplicates ...
|
||||
result = string ? result.join : result
|
||||
|
||||
return result
|
||||
end
|
||||
end
|
||||
|
||||
# vim: set ts=2 sw=2 et :
|
|
@ -0,0 +1,41 @@
|
|||
#
|
||||
# upcase.rb
|
||||
#
|
||||
|
||||
module Puppet::Parser::Functions
|
||||
newfunction(:upcase, :type => :rvalue, :doc => <<-EOS
|
||||
Converts a string or an array of strings to uppercase.
|
||||
|
||||
*Examples:*
|
||||
|
||||
upcase("abcd")
|
||||
|
||||
Will return:
|
||||
|
||||
ASDF
|
||||
EOS
|
||||
) do |arguments|
|
||||
|
||||
raise(Puppet::ParseError, "upcase(): Wrong number of arguments " +
|
||||
"given (#{arguments.size} for 1)") if arguments.size < 1
|
||||
|
||||
value = arguments[0]
|
||||
klass = value.class
|
||||
|
||||
unless [Array, String].include?(klass)
|
||||
raise(Puppet::ParseError, 'upcase(): Requires either ' +
|
||||
'array or string to work with')
|
||||
end
|
||||
|
||||
if value.is_a?(Array)
|
||||
# Numbers in Puppet are often string-encoded which is troublesome ...
|
||||
result = value.collect { |i| i.is_a?(String) ? i.upcase : i }
|
||||
else
|
||||
result = value.upcase
|
||||
end
|
||||
|
||||
return result
|
||||
end
|
||||
end
|
||||
|
||||
# vim: set ts=2 sw=2 et :
|
|
@ -0,0 +1,56 @@
|
|||
module Puppet::Parser::Functions
|
||||
newfunction(:validate_absolute_path, :doc => <<-'ENDHEREDOC') do |args|
|
||||
Validate the string represents an absolute path in the filesystem. This function works
|
||||
for windows and unix style paths.
|
||||
|
||||
The following values will pass:
|
||||
|
||||
$my_path = "C:/Program Files (x86)/Puppet Labs/Puppet"
|
||||
validate_absolute_path($my_path)
|
||||
$my_path2 = "/var/lib/puppet"
|
||||
validate_absolute_path($my_path2)
|
||||
|
||||
|
||||
The following values will fail, causing compilation to abort:
|
||||
|
||||
validate_absolute_path(true)
|
||||
validate_absolute_path([ 'var/lib/puppet', '/var/foo' ])
|
||||
validate_absolute_path([ '/var/lib/puppet', 'var/foo' ])
|
||||
$undefined = undef
|
||||
validate_absolute_path($undefined)
|
||||
|
||||
ENDHEREDOC
|
||||
|
||||
require 'puppet/util'
|
||||
|
||||
unless args.length > 0 then
|
||||
raise Puppet::ParseError, ("validate_absolute_path(): wrong number of arguments (#{args.length}; must be > 0)")
|
||||
end
|
||||
|
||||
args.each do |arg|
|
||||
# This logic was borrowed from
|
||||
# [lib/puppet/file_serving/base.rb](https://github.com/puppetlabs/puppet/blob/master/lib/puppet/file_serving/base.rb)
|
||||
|
||||
# Puppet 2.7 and beyond will have Puppet::Util.absolute_path? Fall back to a back-ported implementation otherwise.
|
||||
if Puppet::Util.respond_to?(:absolute_path?) then
|
||||
unless Puppet::Util.absolute_path?(arg, :posix) or Puppet::Util.absolute_path?(arg, :windows)
|
||||
raise Puppet::ParseError, ("#{arg.inspect} is not an absolute path.")
|
||||
end
|
||||
else
|
||||
# This code back-ported from 2.7.x's lib/puppet/util.rb Puppet::Util.absolute_path?
|
||||
# Determine in a platform-specific way whether a path is absolute. This
|
||||
# defaults to the local platform if none is specified.
|
||||
# Escape once for the string literal, and once for the regex.
|
||||
slash = '[\\\\/]'
|
||||
name = '[^\\\\/]+'
|
||||
regexes = {
|
||||
:windows => %r!^(([A-Z]:#{slash})|(#{slash}#{slash}#{name}#{slash}#{name})|(#{slash}#{slash}\?#{slash}#{name}))!i,
|
||||
:posix => %r!^/!,
|
||||
}
|
||||
|
||||
rval = (!!(arg =~ regexes[:posix])) || (!!(arg =~ regexes[:windows]))
|
||||
rval or raise Puppet::ParseError, ("#{arg.inspect} is not an absolute path.")
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,33 @@
|
|||
module Puppet::Parser::Functions
|
||||
|
||||
newfunction(:validate_array, :doc => <<-'ENDHEREDOC') do |args|
|
||||
Validate that all passed values are array data structures. Abort catalog
|
||||
compilation if any value fails this check.
|
||||
|
||||
The following values will pass:
|
||||
|
||||
$my_array = [ 'one', 'two' ]
|
||||
validate_array($my_array)
|
||||
|
||||
The following values will fail, causing compilation to abort:
|
||||
|
||||
validate_array(true)
|
||||
validate_array('some_string')
|
||||
$undefined = undef
|
||||
validate_array($undefined)
|
||||
|
||||
ENDHEREDOC
|
||||
|
||||
unless args.length > 0 then
|
||||
raise Puppet::ParseError, ("validate_array(): wrong number of arguments (#{args.length}; must be > 0)")
|
||||
end
|
||||
|
||||
args.each do |arg|
|
||||
unless arg.is_a?(Array)
|
||||
raise Puppet::ParseError, ("#{arg.inspect} is not an Array. It looks to be a #{arg.class}")
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
|
@ -0,0 +1,34 @@
|
|||
module Puppet::Parser::Functions
|
||||
|
||||
newfunction(:validate_bool, :doc => <<-'ENDHEREDOC') do |args|
|
||||
Validate that all passed values are either true or false. Abort catalog
|
||||
compilation if any value fails this check.
|
||||
|
||||
The following values will pass:
|
||||
|
||||
$iamtrue = true
|
||||
validate_bool(true)
|
||||
validate_bool(true, true, false, $iamtrue)
|
||||
|
||||
The following values will fail, causing compilation to abort:
|
||||
|
||||
$some_array = [ true ]
|
||||
validate_bool("false")
|
||||
validate_bool("true")
|
||||
validate_bool($some_array)
|
||||
|
||||
ENDHEREDOC
|
||||
|
||||
unless args.length > 0 then
|
||||
raise Puppet::ParseError, ("validate_bool(): wrong number of arguments (#{args.length}; must be > 0)")
|
||||
end
|
||||
|
||||
args.each do |arg|
|
||||
unless (arg.is_a?(TrueClass) || arg.is_a?(FalseClass))
|
||||
raise Puppet::ParseError, ("#{arg.inspect} is not a boolean. It looks to be a #{arg.class}")
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
|
@ -0,0 +1,33 @@
|
|||
module Puppet::Parser::Functions
|
||||
|
||||
newfunction(:validate_hash, :doc => <<-'ENDHEREDOC') do |args|
|
||||
Validate that all passed values are hash data structures. Abort catalog
|
||||
compilation if any value fails this check.
|
||||
|
||||
The following values will pass:
|
||||
|
||||
$my_hash = { 'one' => 'two' }
|
||||
validate_hash($my_hash)
|
||||
|
||||
The following values will fail, causing compilation to abort:
|
||||
|
||||
validate_hash(true)
|
||||
validate_hash('some_string')
|
||||
$undefined = undef
|
||||
validate_hash($undefined)
|
||||
|
||||
ENDHEREDOC
|
||||
|
||||
unless args.length > 0 then
|
||||
raise Puppet::ParseError, ("validate_hash(): wrong number of arguments (#{args.length}; must be > 0)")
|
||||
end
|
||||
|
||||
args.each do |arg|
|
||||
unless arg.is_a?(Hash)
|
||||
raise Puppet::ParseError, ("#{arg.inspect} is not a Hash. It looks to be a #{arg.class}")
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
|
@ -0,0 +1,40 @@
|
|||
module Puppet::Parser::Functions
|
||||
newfunction(:validate_re, :doc => <<-'ENDHEREDOC') do |args|
|
||||
Perform simple validation of a string against one or more regular
|
||||
expressions. The first argument of this function should be a string to
|
||||
test, and the second argument should be a stringified regular expression
|
||||
(without the // delimiters) or an array of regular expressions. If none
|
||||
of the regular expressions match the string passed in, compilation will
|
||||
abort with a parse error.
|
||||
|
||||
If a third argument is specified, this will be the error message raised and
|
||||
seen by the user.
|
||||
|
||||
The following strings will validate against the regular expressions:
|
||||
|
||||
validate_re('one', '^one$')
|
||||
validate_re('one', [ '^one', '^two' ])
|
||||
|
||||
The following strings will fail to validate, causing compilation to abort:
|
||||
|
||||
validate_re('one', [ '^two', '^three' ])
|
||||
|
||||
A helpful error message can be returned like this:
|
||||
|
||||
validate_re($::puppetversion, '^2.7', 'The $puppetversion fact value does not match 2.7')
|
||||
|
||||
ENDHEREDOC
|
||||
if (args.length < 2) or (args.length > 3) then
|
||||
raise Puppet::ParseError, ("validate_re(): wrong number of arguments (#{args.length}; must be 2 or 3)")
|
||||
end
|
||||
|
||||
msg = args[2] || "validate_re(): #{args[0].inspect} does not match #{args[1].inspect}"
|
||||
|
||||
# We're using a flattened array here because we can't call String#any? in
|
||||
# Ruby 1.9 like we can in Ruby 1.8
|
||||
raise Puppet::ParseError, (msg) unless [args[1]].flatten.any? do |re_str|
|
||||
args[0] =~ Regexp.compile(re_str)
|
||||
end
|
||||
|
||||
end
|
||||
end
|
|
@ -0,0 +1,52 @@
|
|||
module Puppet::Parser::Functions
|
||||
|
||||
newfunction(:validate_slength, :doc => <<-'ENDHEREDOC') do |args|
|
||||
Validate that the first argument is a string (or an array of strings), and
|
||||
less/equal to than the length of the second argument. It fails if the first
|
||||
argument is not a string or array of strings, and if arg 2 is not convertable
|
||||
to a number.
|
||||
|
||||
The following values will pass:
|
||||
|
||||
validate_slength("discombobulate",17)
|
||||
validate_slength(["discombobulate","moo"],17)
|
||||
|
||||
The following valueis will not:
|
||||
|
||||
validate_slength("discombobulate",1)
|
||||
validate_slength(["discombobulate","thermometer"],5)
|
||||
|
||||
ENDHEREDOC
|
||||
|
||||
raise Puppet::ParseError, ("validate_slength(): Wrong number of arguments (#{args.length}; must be = 2)") unless args.length == 2
|
||||
|
||||
unless (args[0].is_a?(String) or args[0].is_a?(Array))
|
||||
raise Puppet::ParseError, ("validate_slength(): please pass a string, or an array of strings - what you passed didn't work for me at all - #{args[0].class}")
|
||||
end
|
||||
|
||||
begin
|
||||
max_length = args[1].to_i
|
||||
rescue NoMethodError => e
|
||||
raise Puppet::ParseError, ("validate_slength(): Couldn't convert whatever you passed as the length parameter to an integer - sorry: " + e.message )
|
||||
end
|
||||
|
||||
raise Puppet::ParseError, ("validate_slength(): please pass a positive number as max_length") unless max_length > 0
|
||||
|
||||
case args[0]
|
||||
when String
|
||||
raise Puppet::ParseError, ("validate_slength(): #{args[0].inspect} is #{args[0].length} characters. It should have been less than or equal to #{max_length} characters") unless args[0].length <= max_length
|
||||
when Array
|
||||
args[0].each do |arg|
|
||||
if arg.is_a?(String)
|
||||
unless ( arg.is_a?(String) and arg.length <= max_length )
|
||||
raise Puppet::ParseError, ("validate_slength(): #{arg.inspect} is #{arg.length} characters. It should have been less than or equal to #{max_length} characters")
|
||||
end
|
||||
else
|
||||
raise Puppet::ParseError, ("validate_slength(): #{arg.inspect} is not a string, it's a #{arg.class}")
|
||||
end
|
||||
end
|
||||
else
|
||||
raise Puppet::ParseError, ("validate_slength(): please pass a string, or an array of strings - what you passed didn't work for me at all - #{args[0].class}")
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,33 @@
|
|||
module Puppet::Parser::Functions
|
||||
|
||||
newfunction(:validate_string, :doc => <<-'ENDHEREDOC') do |args|
|
||||
Validate that all passed values are string data structures. Abort catalog
|
||||
compilation if any value fails this check.
|
||||
|
||||
The following values will pass:
|
||||
|
||||
$my_string = "one two"
|
||||
validate_string($my_string, 'three')
|
||||
|
||||
The following values will fail, causing compilation to abort:
|
||||
|
||||
validate_string(true)
|
||||
validate_string([ 'some', 'array' ])
|
||||
$undefined = undef
|
||||
validate_string($undefined)
|
||||
|
||||
ENDHEREDOC
|
||||
|
||||
unless args.length > 0 then
|
||||
raise Puppet::ParseError, ("validate_string(): wrong number of arguments (#{args.length}; must be > 0)")
|
||||
end
|
||||
|
||||
args.each do |arg|
|
||||
unless arg.is_a?(String)
|
||||
raise Puppet::ParseError, ("#{arg.inspect} is not a string. It looks to be a #{arg.class}")
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
|
@ -0,0 +1,39 @@
|
|||
#
|
||||
# values.rb
|
||||
#
|
||||
|
||||
module Puppet::Parser::Functions
|
||||
newfunction(:values, :type => :rvalue, :doc => <<-EOS
|
||||
When given a hash this function will return the values of that hash.
|
||||
|
||||
*Examples:*
|
||||
|
||||
$hash = {
|
||||
'a' => 1,
|
||||
'b' => 2,
|
||||
'c' => 3,
|
||||
}
|
||||
values($hash)
|
||||
|
||||
This example would return:
|
||||
|
||||
[1,2,3]
|
||||
EOS
|
||||
) do |arguments|
|
||||
|
||||
raise(Puppet::ParseError, "values(): Wrong number of arguments " +
|
||||
"given (#{arguments.size} for 1)") if arguments.size < 1
|
||||
|
||||
hash = arguments[0]
|
||||
|
||||
unless hash.is_a?(Hash)
|
||||
raise(Puppet::ParseError, 'values(): Requires hash to work with')
|
||||
end
|
||||
|
||||
result = hash.values
|
||||
|
||||
return result
|
||||
end
|
||||
end
|
||||
|
||||
# vim: set ts=2 sw=2 et :
|
|
@ -0,0 +1,98 @@
|
|||
#
|
||||
# values_at.rb
|
||||
#
|
||||
|
||||
module Puppet::Parser::Functions
|
||||
newfunction(:values_at, :type => :rvalue, :doc => <<-EOS
|
||||
Finds value inside an array based on location.
|
||||
|
||||
The first argument is the array you want to analyze, and the second element can
|
||||
be a combination of:
|
||||
|
||||
* A single numeric index
|
||||
* A range in the form of 'start-stop' (eg. 4-9)
|
||||
* An array combining the above
|
||||
|
||||
*Examples*:
|
||||
|
||||
values_at(['a','b','c'], 2)
|
||||
|
||||
Would return ['c'].
|
||||
|
||||
values_at(['a','b','c'], ["0-1"])
|
||||
|
||||
Would return ['a','b'].
|
||||
|
||||
values_at(['a','b','c','d','e'], [0, "2-3"])
|
||||
|
||||
Would return ['a','c','d'].
|
||||
EOS
|
||||
) do |arguments|
|
||||
|
||||
raise(Puppet::ParseError, "values_at(): Wrong number of " +
|
||||
"arguments given (#{arguments.size} for 2)") if arguments.size < 2
|
||||
|
||||
array = arguments.shift
|
||||
|
||||
unless array.is_a?(Array)
|
||||
raise(Puppet::ParseError, 'values_at(): Requires array to work with')
|
||||
end
|
||||
|
||||
indices = [arguments.shift].flatten() # Get them all ... Pokemon ...
|
||||
|
||||
if not indices or indices.empty?
|
||||
raise(Puppet::ParseError, 'values_at(): You must provide ' +
|
||||
'at least one positive index to collect')
|
||||
end
|
||||
|
||||
result = []
|
||||
indices_list = []
|
||||
|
||||
indices.each do |i|
|
||||
if m = i.match(/^(\d+)(\.\.\.?|\-)(\d+)$/)
|
||||
start = m[1].to_i
|
||||
stop = m[3].to_i
|
||||
|
||||
type = m[2]
|
||||
|
||||
if start > stop
|
||||
raise(Puppet::ParseError, 'values_at(): Stop index in ' +
|
||||
'given indices range is smaller than the start index')
|
||||
elsif stop > array.size - 1 # First element is at index 0 is it not?
|
||||
raise(Puppet::ParseError, 'values_at(): Stop index in ' +
|
||||
'given indices range exceeds array size')
|
||||
end
|
||||
|
||||
range = case type
|
||||
when /^(\.\.|\-)$/ then (start .. stop)
|
||||
when /^(\.\.\.)$/ then (start ... stop) # Exclusive of last element ...
|
||||
end
|
||||
|
||||
range.each { |i| indices_list << i.to_i }
|
||||
else
|
||||
# Only positive numbers allowed in this case ...
|
||||
if not i.match(/^\d+$/)
|
||||
raise(Puppet::ParseError, 'values_at(): Unknown format ' +
|
||||
'of given index')
|
||||
end
|
||||
|
||||
# In Puppet numbers are often string-encoded ...
|
||||
i = i.to_i
|
||||
|
||||
if i > array.size - 1 # Same story. First element is at index 0 ...
|
||||
raise(Puppet::ParseError, 'values_at(): Given index ' +
|
||||
'exceeds array size')
|
||||
end
|
||||
|
||||
indices_list << i
|
||||
end
|
||||
end
|
||||
|
||||
# We remove nil values as they make no sense in Puppet DSL ...
|
||||
result = indices_list.collect { |i| array[i] }.compact
|
||||
|
||||
return result
|
||||
end
|
||||
end
|
||||
|
||||
# vim: set ts=2 sw=2 et :
|
|
@ -0,0 +1,65 @@
|
|||
#
|
||||
# zip.rb
|
||||
#
|
||||
|
||||
module Puppet::Parser::Functions
|
||||
newfunction(:zip, :type => :rvalue, :doc => <<-EOS
|
||||
Takes one element from first array and merges corresponding elements from second array. This generates a sequence of n-element arrays, where n is one more than the count of arguments.
|
||||
|
||||
*Example:*
|
||||
|
||||
zip(['1','2','3'],['4','5','6'])
|
||||
|
||||
Would result in:
|
||||
|
||||
["1", "4"], ["2", "5"], ["3", "6"]
|
||||
EOS
|
||||
) do |arguments|
|
||||
|
||||
# Technically we support three arguments but only first is mandatory ...
|
||||
raise(Puppet::ParseError, "zip(): Wrong number of arguments " +
|
||||
"given (#{arguments.size} for 2)") if arguments.size < 2
|
||||
|
||||
a = arguments[0]
|
||||
b = arguments[1]
|
||||
|
||||
unless a.is_a?(Array) and b.is_a?(Array)
|
||||
raise(Puppet::ParseError, 'zip(): Requires array to work with')
|
||||
end
|
||||
|
||||
flatten = arguments[2] if arguments[2]
|
||||
|
||||
if flatten
|
||||
klass = flatten.class
|
||||
|
||||
# We can have either true or false, or string which resembles boolean ...
|
||||
unless [FalseClass, TrueClass, String].include?(klass)
|
||||
raise(Puppet::ParseError, 'zip(): Requires either ' +
|
||||
'boolean or string to work with')
|
||||
end
|
||||
|
||||
if flatten.is_a?(String)
|
||||
# We consider all the yes, no, y, n and so on too ...
|
||||
flatten = case flatten
|
||||
#
|
||||
# This is how undef looks like in Puppet ...
|
||||
# We yield false in this case.
|
||||
#
|
||||
when /^$/, '' then false # Empty string will be false ...
|
||||
when /^(1|t|y|true|yes)$/ then true
|
||||
when /^(0|f|n|false|no)$/ then false
|
||||
when /^(undef|undefined)$/ then false # This is not likely to happen ...
|
||||
else
|
||||
raise(Puppet::ParseError, 'zip(): Unknown type of boolean given')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
result = a.zip(b)
|
||||
result = flatten ? result.flatten : result
|
||||
|
||||
return result
|
||||
end
|
||||
end
|
||||
|
||||
# vim: set ts=2 sw=2 et :
|
|
@ -0,0 +1,59 @@
|
|||
|
||||
Puppet::Type.type(:file_line).provide(:ruby) do
|
||||
|
||||
def exists?
|
||||
lines.find do |line|
|
||||
line.chomp == resource[:line].chomp
|
||||
end
|
||||
end
|
||||
|
||||
def create
|
||||
if resource[:match]
|
||||
handle_create_with_match()
|
||||
else
|
||||
handle_create_without_match()
|
||||
end
|
||||
end
|
||||
|
||||
def destroy
|
||||
local_lines = lines
|
||||
File.open(resource[:path],'w') do |fh|
|
||||
fh.write(local_lines.reject{|l| l.chomp == resource[:line] }.join(''))
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
def lines
|
||||
# If this type is ever used with very large files, we should
|
||||
# write this in a different way, using a temp
|
||||
# file; for now assuming that this type is only used on
|
||||
# small-ish config files that can fit into memory without
|
||||
# too much trouble.
|
||||
@lines ||= File.readlines(resource[:path])
|
||||
end
|
||||
|
||||
def handle_create_with_match()
|
||||
regex = resource[:match] ? Regexp.new(resource[:match]) : nil
|
||||
match_count = lines.select { |l| regex.match(l) }.count
|
||||
if match_count > 1
|
||||
raise Puppet::Error, "More than one line in file '#{resource[:path]}' matches pattern '#{resource[:match]}'"
|
||||
end
|
||||
File.open(resource[:path], 'w') do |fh|
|
||||
lines.each do |l|
|
||||
fh.puts(regex.match(l) ? resource[:line] : l)
|
||||
end
|
||||
|
||||
if (match_count == 0)
|
||||
fh.puts(resource[:line])
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def handle_create_without_match
|
||||
File.open(resource[:path], 'a') do |fh|
|
||||
fh.puts resource[:line]
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
end
|
|
@ -0,0 +1,41 @@
|
|||
Puppet::Type.newtype(:anchor) do
|
||||
desc <<-'ENDOFDESC'
|
||||
A simple resource type intended to be used as an anchor in a composite class.
|
||||
|
||||
In Puppet 2.6, when a class declares another class, the resources in the
|
||||
interior class are not contained by the exterior class. This interacts badly
|
||||
with the pattern of composing complex modules from smaller classes, as it
|
||||
makes it impossible for end users to specify order relationships between the
|
||||
exterior class and other modules.
|
||||
|
||||
The anchor type lets you work around this. By sandwiching any interior
|
||||
classes between two no-op resources that _are_ contained by the exterior
|
||||
class, you can ensure that all resources in the module are contained.
|
||||
|
||||
class ntp {
|
||||
# These classes will have the correct order relationship with each
|
||||
# other. However, without anchors, they won't have any order
|
||||
# relationship to Class['ntp'].
|
||||
class { 'ntp::package': }
|
||||
-> class { 'ntp::config': }
|
||||
-> class { 'ntp::service': }
|
||||
|
||||
# These two resources "anchor" the composed classes within the ntp
|
||||
# class.
|
||||
anchor { 'ntp::begin': } -> Class['ntp::package']
|
||||
Class['ntp::service'] -> anchor { 'ntp::end': }
|
||||
}
|
||||
|
||||
This allows the end user of the ntp module to establish require and before
|
||||
relationships with Class['ntp']:
|
||||
|
||||
class { 'ntp': } -> class { 'mcollective': }
|
||||
class { 'mcollective': } -> class { 'ntp': }
|
||||
|
||||
ENDOFDESC
|
||||
|
||||
newparam :name do
|
||||
desc "The name of the anchor resource."
|
||||
end
|
||||
|
||||
end
|
|
@ -0,0 +1,65 @@
|
|||
Puppet::Type.newtype(:file_line) do
|
||||
|
||||
desc <<-EOT
|
||||
Ensures that a given line is contained within a file. The implementation
|
||||
matches the full line, including whitespace at the beginning and end. If
|
||||
the line is not contained in the given file, Puppet will add the line to
|
||||
ensure the desired state. Multiple resources may be declared to manage
|
||||
multiple lines in the same file.
|
||||
|
||||
Example:
|
||||
|
||||
file_line { 'sudo_rule':
|
||||
path => '/etc/sudoers',
|
||||
line => '%sudo ALL=(ALL) ALL',
|
||||
}
|
||||
file_line { 'sudo_rule_nopw':
|
||||
path => '/etc/sudoers',
|
||||
line => '%sudonopw ALL=(ALL) NOPASSWD: ALL',
|
||||
}
|
||||
|
||||
In this example, Puppet will ensure both of the specified lines are
|
||||
contained in the file /etc/sudoers.
|
||||
|
||||
EOT
|
||||
|
||||
ensurable do
|
||||
defaultvalues
|
||||
defaultto :present
|
||||
end
|
||||
|
||||
newparam(:name, :namevar => true) do
|
||||
desc 'An arbitrary name used as the identity of the resource.'
|
||||
end
|
||||
|
||||
newparam(:match) do
|
||||
desc 'An optional regular expression to run against existing lines in the file;\n' +
|
||||
'if a match is found, we replace that line rather than adding a new line.'
|
||||
end
|
||||
|
||||
newparam(:line) do
|
||||
desc 'The line to be appended to the file located by the path parameter.'
|
||||
end
|
||||
|
||||
newparam(:path) do
|
||||
desc 'The file Puppet will ensure contains the line specified by the line parameter.'
|
||||
validate do |value|
|
||||
unless (Puppet.features.posix? and value =~ /^\//) or (Puppet.features.microsoft_windows? and (value =~ /^.:\// or value =~ /^\/\/[^\/]+\/[^\/]+/))
|
||||
raise(Puppet::Error, "File paths must be fully qualified, not '#{value}'")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
validate do
|
||||
unless self[:line] and self[:path]
|
||||
raise(Puppet::Error, "Both line and path are required attributes")
|
||||
end
|
||||
|
||||
if (self[:match])
|
||||
unless Regexp.new(self[:match]).match(self[:line])
|
||||
raise(Puppet::Error, "When providing a 'match' parameter, the value must be a regex that matches against the value of your 'line' parameter")
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
|
@ -0,0 +1,20 @@
|
|||
# Class: stdlib
|
||||
#
|
||||
# This module manages stdlib. Most of stdlib's features are automatically
|
||||
# loaded by Puppet, but this class should be declared in order to use the
|
||||
# standardized run stages.
|
||||
#
|
||||
# Parameters: none
|
||||
#
|
||||
# Actions:
|
||||
#
|
||||
# Declares all other classes in the stdlib module. Currently, this consists
|
||||
# of stdlib::stages.
|
||||
#
|
||||
# Requires: nothing
|
||||
#
|
||||
class stdlib {
|
||||
|
||||
class { 'stdlib::stages': }
|
||||
|
||||
}
|
|
@ -0,0 +1,43 @@
|
|||
# Class: stdlib::stages
|
||||
#
|
||||
# This class manages a standard set of run stages for Puppet. It is managed by
|
||||
# the stdlib class, and should not be declared independently.
|
||||
#
|
||||
# The high level stages are (in order):
|
||||
#
|
||||
# * setup
|
||||
# * main
|
||||
# * runtime
|
||||
# * setup_infra
|
||||
# * deploy_infra
|
||||
# * setup_app
|
||||
# * deploy_app
|
||||
# * deploy
|
||||
#
|
||||
# Parameters: none
|
||||
#
|
||||
# Actions:
|
||||
#
|
||||
# Declares various run-stages for deploying infrastructure,
|
||||
# language runtimes, and application layers.
|
||||
#
|
||||
# Requires: nothing
|
||||
#
|
||||
# Sample Usage:
|
||||
#
|
||||
# node default {
|
||||
# include stdlib
|
||||
# class { java: stage => 'runtime' }
|
||||
# }
|
||||
#
|
||||
class stdlib::stages {
|
||||
|
||||
stage { 'setup': before => Stage['main'] }
|
||||
stage { 'runtime': require => Stage['main'] }
|
||||
-> stage { 'setup_infra': }
|
||||
-> stage { 'deploy_infra': }
|
||||
-> stage { 'setup_app': }
|
||||
-> stage { 'deploy_app': }
|
||||
-> stage { 'deploy': }
|
||||
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
require 'rspec'
|
||||
|
||||
class Object
|
||||
# This is necessary because the RAL has a 'should'
|
||||
# method.
|
||||
alias :must :should
|
||||
alias :must_not :should_not
|
||||
end
|
|
@ -0,0 +1,11 @@
|
|||
# Some monkey-patching to allow us to test private methods.
|
||||
class Class
|
||||
def publicize_methods(*methods)
|
||||
saved_private_instance_methods = methods.empty? ? self.private_instance_methods : methods
|
||||
|
||||
self.class_eval { public(*saved_private_instance_methods) }
|
||||
yield
|
||||
self.class_eval { private(*saved_private_instance_methods) }
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
--format
|
||||
s
|
||||
--colour
|
||||
--loadby
|
||||
mtime
|
||||
--backtrace
|
|
@ -0,0 +1,12 @@
|
|||
require 'puppetlabs_spec_helper/puppet_spec_helper'
|
||||
|
||||
RSpec.configure do |config|
|
||||
|
||||
config.before :each do
|
||||
GC.disable
|
||||
end
|
||||
|
||||
config.after :each do
|
||||
GC.enable
|
||||
end
|
||||
end
|
|
@ -0,0 +1,40 @@
|
|||
require 'spec_helper'
|
||||
require 'facter/root_home'
|
||||
|
||||
describe Facter::Util::RootHome do
|
||||
context "solaris" do
|
||||
let(:root_ent) { "root:x:0:0:Super-User:/:/sbin/sh" }
|
||||
let(:expected_root_home) { "/" }
|
||||
|
||||
it "should return /" do
|
||||
Facter::Util::Resolution.expects(:exec).with("getent passwd root").returns(root_ent)
|
||||
Facter::Util::RootHome.get_root_home.should == expected_root_home
|
||||
end
|
||||
end
|
||||
context "linux" do
|
||||
let(:root_ent) { "root:x:0:0:root:/root:/bin/bash" }
|
||||
let(:expected_root_home) { "/root" }
|
||||
|
||||
it "should return /root" do
|
||||
Facter::Util::Resolution.expects(:exec).with("getent passwd root").returns(root_ent)
|
||||
Facter::Util::RootHome.get_root_home.should == expected_root_home
|
||||
end
|
||||
end
|
||||
context "macosx" do
|
||||
let(:root_ent) { "root:*:0:0:System Administrator:/var/root:/bin/sh" }
|
||||
let(:expected_root_home) { "/var/root" }
|
||||
|
||||
it "should return /var/root" do
|
||||
Facter::Util::Resolution.expects(:exec).with("getent passwd root").returns(root_ent)
|
||||
Facter::Util::RootHome.get_root_home.should == expected_root_home
|
||||
end
|
||||
end
|
||||
context "windows" do
|
||||
before :each do
|
||||
Facter::Util::Resolution.expects(:exec).with("getent passwd root").returns(nil)
|
||||
end
|
||||
it "should be nil on windows" do
|
||||
Facter::Util::RootHome.get_root_home.should be_nil
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,35 @@
|
|||
require 'spec_helper'
|
||||
require 'facter/util/puppet_settings'
|
||||
|
||||
describe Facter::Util::PuppetSettings do
|
||||
|
||||
describe "#with_puppet" do
|
||||
context "Without Puppet loaded" do
|
||||
before(:each) do
|
||||
Module.expects(:const_get).with("Puppet").raises(NameError)
|
||||
end
|
||||
|
||||
it 'should be nil' do
|
||||
subject.with_puppet { Puppet[:vardir] }.should be_nil
|
||||
end
|
||||
it 'should not yield to the block' do
|
||||
Puppet.expects(:[]).never
|
||||
subject.with_puppet { Puppet[:vardir] }.should be_nil
|
||||
end
|
||||
end
|
||||
context "With Puppet loaded" do
|
||||
module Puppet; end
|
||||
let(:vardir) { "/var/lib/puppet" }
|
||||
|
||||
before :each do
|
||||
Puppet.expects(:[]).with(:vardir).returns vardir
|
||||
end
|
||||
it 'should yield to the block' do
|
||||
subject.with_puppet { Puppet[:vardir] }
|
||||
end
|
||||
it 'should return the nodes vardir' do
|
||||
subject.with_puppet { Puppet[:vardir] }.should eq vardir
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,31 @@
|
|||
#!/usr/bin/env rspec
|
||||
require 'spec_helper'
|
||||
|
||||
describe "the abs function" do
|
||||
before :all do
|
||||
Puppet::Parser::Functions.autoloader.loadall
|
||||
end
|
||||
|
||||
before :each do
|
||||
@scope = Puppet::Parser::Scope.new
|
||||
end
|
||||
|
||||
it "should exist" do
|
||||
Puppet::Parser::Functions.function("abs").should == "function_abs"
|
||||
end
|
||||
|
||||
it "should raise a ParseError if there is less than 1 arguments" do
|
||||
lambda { @scope.function_abs([]) }.should( raise_error(Puppet::ParseError))
|
||||
end
|
||||
|
||||
it "should convert a negative number into a positive" do
|
||||
result = @scope.function_abs(["-34"])
|
||||
result.should(eq(34))
|
||||
end
|
||||
|
||||
it "should do nothing with a positive number" do
|
||||
result = @scope.function_abs(["5678"])
|
||||
result.should(eq(5678))
|
||||
end
|
||||
|
||||
end
|
|
@ -0,0 +1,31 @@
|
|||
#!/usr/bin/env rspec
|
||||
require 'spec_helper'
|
||||
|
||||
describe "the bool2num function" do
|
||||
before :all do
|
||||
Puppet::Parser::Functions.autoloader.loadall
|
||||
end
|
||||
|
||||
before :each do
|
||||
@scope = Puppet::Parser::Scope.new
|
||||
end
|
||||
|
||||
it "should exist" do
|
||||
Puppet::Parser::Functions.function("bool2num").should == "function_bool2num"
|
||||
end
|
||||
|
||||
it "should raise a ParseError if there is less than 1 arguments" do
|
||||
lambda { @scope.function_bool2num([]) }.should( raise_error(Puppet::ParseError))
|
||||
end
|
||||
|
||||
it "should convert true to 1" do
|
||||
result = @scope.function_bool2num([true])
|
||||
result.should(eq(1))
|
||||
end
|
||||
|
||||
it "should convert false to 0" do
|
||||
result = @scope.function_bool2num([false])
|
||||
result.should(eq(0))
|
||||
end
|
||||
|
||||
end
|
|
@ -0,0 +1,26 @@
|
|||
#!/usr/bin/env rspec
|
||||
require 'spec_helper'
|
||||
|
||||
describe "the capitalize function" do
|
||||
before :all do
|
||||
Puppet::Parser::Functions.autoloader.loadall
|
||||
end
|
||||
|
||||
before :each do
|
||||
@scope = Puppet::Parser::Scope.new
|
||||
end
|
||||
|
||||
it "should exist" do
|
||||
Puppet::Parser::Functions.function("capitalize").should == "function_capitalize"
|
||||
end
|
||||
|
||||
it "should raise a ParseError if there is less than 1 arguments" do
|
||||
lambda { @scope.function_capitalize([]) }.should( raise_error(Puppet::ParseError))
|
||||
end
|
||||
|
||||
it "should capitalize the beginning of a string" do
|
||||
result = @scope.function_capitalize(["abc"])
|
||||
result.should(eq("Abc"))
|
||||
end
|
||||
|
||||
end
|
|
@ -0,0 +1,26 @@
|
|||
#!/usr/bin/env rspec
|
||||
require 'spec_helper'
|
||||
|
||||
describe "the chomp function" do
|
||||
before :all do
|
||||
Puppet::Parser::Functions.autoloader.loadall
|
||||
end
|
||||
|
||||
before :each do
|
||||
@scope = Puppet::Parser::Scope.new
|
||||
end
|
||||
|
||||
it "should exist" do
|
||||
Puppet::Parser::Functions.function("chomp").should == "function_chomp"
|
||||
end
|
||||
|
||||
it "should raise a ParseError if there is less than 1 arguments" do
|
||||
lambda { @scope.function_chomp([]) }.should( raise_error(Puppet::ParseError))
|
||||
end
|
||||
|
||||
it "should chomp the end of a string" do
|
||||
result = @scope.function_chomp(["abc\n"])
|
||||
result.should(eq("abc"))
|
||||
end
|
||||
|
||||
end
|
|
@ -0,0 +1,26 @@
|
|||
#!/usr/bin/env rspec
|
||||
require 'spec_helper'
|
||||
|
||||
describe "the chop function" do
|
||||
before :all do
|
||||
Puppet::Parser::Functions.autoloader.loadall
|
||||
end
|
||||
|
||||
before :each do
|
||||
@scope = Puppet::Parser::Scope.new
|
||||
end
|
||||
|
||||
it "should exist" do
|
||||
Puppet::Parser::Functions.function("chop").should == "function_chop"
|
||||
end
|
||||
|
||||
it "should raise a ParseError if there is less than 1 arguments" do
|
||||
lambda { @scope.function_chop([]) }.should( raise_error(Puppet::ParseError))
|
||||
end
|
||||
|
||||
it "should chop the end of a string" do
|
||||
result = @scope.function_chop(["asdf\n"])
|
||||
result.should(eq("asdf"))
|
||||
end
|
||||
|
||||
end
|
|
@ -0,0 +1,26 @@
|
|||
#!/usr/bin/env rspec
|
||||
require 'spec_helper'
|
||||
|
||||
describe "the delete_at function" do
|
||||
before :all do
|
||||
Puppet::Parser::Functions.autoloader.loadall
|
||||
end
|
||||
|
||||
before :each do
|
||||
@scope = Puppet::Parser::Scope.new
|
||||
end
|
||||
|
||||
it "should exist" do
|
||||
Puppet::Parser::Functions.function("delete_at").should == "function_delete_at"
|
||||
end
|
||||
|
||||
it "should raise a ParseError if there is less than 1 arguments" do
|
||||
lambda { @scope.function_delete_at([]) }.should( raise_error(Puppet::ParseError))
|
||||
end
|
||||
|
||||
it "should delete an item at specified location from an array" do
|
||||
result = @scope.function_delete_at([['a','b','c'],1])
|
||||
result.should(eq(['a','c']))
|
||||
end
|
||||
|
||||
end
|
|
@ -0,0 +1,26 @@
|
|||
#!/usr/bin/env rspec
|
||||
require 'spec_helper'
|
||||
|
||||
describe "the delete function" do
|
||||
before :all do
|
||||
Puppet::Parser::Functions.autoloader.loadall
|
||||
end
|
||||
|
||||
before :each do
|
||||
@scope = Puppet::Parser::Scope.new
|
||||
end
|
||||
|
||||
it "should exist" do
|
||||
Puppet::Parser::Functions.function("delete").should == "function_delete"
|
||||
end
|
||||
|
||||
it "should raise a ParseError if there is less than 1 arguments" do
|
||||
lambda { @scope.function_delete([]) }.should( raise_error(Puppet::ParseError))
|
||||
end
|
||||
|
||||
it "should delete an item from an array" do
|
||||
result = @scope.function_delete([['a','b','c'],'b'])
|
||||
result.should(eq(['a','c']))
|
||||
end
|
||||
|
||||
end
|
|
@ -0,0 +1,31 @@
|
|||
#!/usr/bin/env rspec
|
||||
require 'spec_helper'
|
||||
|
||||
describe "the downcase function" do
|
||||
before :all do
|
||||
Puppet::Parser::Functions.autoloader.loadall
|
||||
end
|
||||
|
||||
before :each do
|
||||
@scope = Puppet::Parser::Scope.new
|
||||
end
|
||||
|
||||
it "should exist" do
|
||||
Puppet::Parser::Functions.function("downcase").should == "function_downcase"
|
||||
end
|
||||
|
||||
it "should raise a ParseError if there is less than 1 arguments" do
|
||||
lambda { @scope.function_downcase([]) }.should( raise_error(Puppet::ParseError))
|
||||
end
|
||||
|
||||
it "should downcase a string" do
|
||||
result = @scope.function_downcase(["ASFD"])
|
||||
result.should(eq("asfd"))
|
||||
end
|
||||
|
||||
it "should do nothing to a string that is already downcase" do
|
||||
result = @scope.function_downcase(["asdf asdf"])
|
||||
result.should(eq("asdf asdf"))
|
||||
end
|
||||
|
||||
end
|
|
@ -0,0 +1,31 @@
|
|||
#!/usr/bin/env rspec
|
||||
require 'spec_helper'
|
||||
|
||||
describe "the empty function" do
|
||||
before :all do
|
||||
Puppet::Parser::Functions.autoloader.loadall
|
||||
end
|
||||
|
||||
before :each do
|
||||
@scope = Puppet::Parser::Scope.new
|
||||
end
|
||||
|
||||
it "should exist" do
|
||||
Puppet::Parser::Functions.function("empty").should == "function_empty"
|
||||
end
|
||||
|
||||
it "should raise a ParseError if there is less than 1 arguments" do
|
||||
lambda { @scope.function_empty([]) }.should( raise_error(Puppet::ParseError))
|
||||
end
|
||||
|
||||
it "should return a true for an empty string" do
|
||||
result = @scope.function_empty([''])
|
||||
result.should(eq(true))
|
||||
end
|
||||
|
||||
it "should return a false for a non-empty string" do
|
||||
result = @scope.function_empty(['asdf'])
|
||||
result.should(eq(false))
|
||||
end
|
||||
|
||||
end
|
|
@ -0,0 +1,31 @@
|
|||
#!/usr/bin/env rspec
|
||||
require 'spec_helper'
|
||||
|
||||
describe "the flatten function" do
|
||||
before :all do
|
||||
Puppet::Parser::Functions.autoloader.loadall
|
||||
end
|
||||
|
||||
before :each do
|
||||
@scope = Puppet::Parser::Scope.new
|
||||
end
|
||||
|
||||
it "should exist" do
|
||||
Puppet::Parser::Functions.function("flatten").should == "function_flatten"
|
||||
end
|
||||
|
||||
it "should raise a ParseError if there is less than 1 arguments" do
|
||||
lambda { @scope.function_flatten([]) }.should( raise_error(Puppet::ParseError))
|
||||
end
|
||||
|
||||
it "should flatten a complex data structure" do
|
||||
result = @scope.function_flatten([["a","b",["c",["d","e"],"f","g"]]])
|
||||
result.should(eq(["a","b","c","d","e","f","g"]))
|
||||
end
|
||||
|
||||
it "should do nothing to a structure that is already flat" do
|
||||
result = @scope.function_flatten([["a","b","c","d"]])
|
||||
result.should(eq(["a","b","c","d"]))
|
||||
end
|
||||
|
||||
end
|
|
@ -0,0 +1,40 @@
|
|||
#!/usr/bin/env rspec
|
||||
require 'spec_helper'
|
||||
|
||||
describe "the fqdn_rotate function" do
|
||||
before :all do
|
||||
Puppet::Parser::Functions.autoloader.loadall
|
||||
end
|
||||
|
||||
before :each do
|
||||
@scope = Puppet::Parser::Scope.new
|
||||
end
|
||||
|
||||
it "should exist" do
|
||||
Puppet::Parser::Functions.function("fqdn_rotate").should == "function_fqdn_rotate"
|
||||
end
|
||||
|
||||
it "should raise a ParseError if there is less than 1 arguments" do
|
||||
lambda { @scope.function_fqdn_rotate([]) }.should( raise_error(Puppet::ParseError))
|
||||
end
|
||||
|
||||
it "should rotate a string and the result should be the same size" do
|
||||
@scope.expects(:lookupvar).with("::fqdn").returns("127.0.0.1")
|
||||
result = @scope.function_fqdn_rotate(["asdf"])
|
||||
result.size.should(eq(4))
|
||||
end
|
||||
|
||||
it "should rotate a string to give the same results for one host" do
|
||||
@scope.expects(:lookupvar).with("::fqdn").returns("127.0.0.1").twice
|
||||
@scope.function_fqdn_rotate(["abcdefg"]).should eql(@scope.function_fqdn_rotate(["abcdefg"]))
|
||||
end
|
||||
|
||||
it "should rotate a string to give different values on different hosts" do
|
||||
@scope.expects(:lookupvar).with("::fqdn").returns("127.0.0.1")
|
||||
val1 = @scope.function_fqdn_rotate(["abcdefghijklmnopqrstuvwxyz01234567890987654321"])
|
||||
@scope.expects(:lookupvar).with("::fqdn").returns("127.0.0.2")
|
||||
val2 = @scope.function_fqdn_rotate(["abcdefghijklmnopqrstuvwxyz01234567890987654321"])
|
||||
val1.should_not eql(val2)
|
||||
end
|
||||
|
||||
end
|
|
@ -0,0 +1,42 @@
|
|||
#!/usr/bin/env rspec
|
||||
require 'puppet'
|
||||
require 'fileutils'
|
||||
require 'spec_helper'
|
||||
describe Puppet::Parser::Functions.function(:get_module_path) do
|
||||
include PuppetlabsSpec::Files
|
||||
|
||||
def get_scope(environment = 'production')
|
||||
scope = Puppet::Parser::Scope.new
|
||||
scope.compiler = Puppet::Parser::Compiler.new(Puppet::Node.new("floppy", :environment => environment))
|
||||
scope
|
||||
end
|
||||
it 'should only allow one argument' do
|
||||
expect { get_scope.function_get_module_path([]) }.should raise_error(Puppet::ParseError, /Wrong number of arguments, expects one/)
|
||||
expect { get_scope.function_get_module_path(['1','2','3']) }.should raise_error(Puppet::ParseError, /Wrong number of arguments, expects one/)
|
||||
end
|
||||
it 'should raise an exception when the module cannot be found' do
|
||||
expect { get_scope.function_get_module_path(['foo']) }.should raise_error(Puppet::ParseError, /Could not find module/)
|
||||
end
|
||||
describe 'when locating a module' do
|
||||
let(:modulepath) { tmpdir('modulepath') }
|
||||
let(:foo_path) { File.join(modulepath, 'foo') }
|
||||
before(:each) { FileUtils.mkdir(foo_path) }
|
||||
it 'should be able to find module paths from the modulepath setting' do
|
||||
Puppet[:modulepath] = modulepath
|
||||
get_scope.function_get_module_path(['foo']).should == foo_path
|
||||
end
|
||||
it 'should be able to find module paths when the modulepath is a list' do
|
||||
Puppet[:modulepath] = modulepath + ":/tmp"
|
||||
get_scope.function_get_module_path(['foo']).should == foo_path
|
||||
end
|
||||
it 'should be able to find module paths from the environment' do
|
||||
conf_file = tmpfilename('conffile')
|
||||
File.open(conf_file, 'w') do |fh|
|
||||
fh.write("[dansenvironment]\nmodulepath = #{modulepath}")
|
||||
end
|
||||
Puppet[:config] = conf_file
|
||||
Puppet.parse_config
|
||||
get_scope('dansenvironment').function_get_module_path(['foo']).should ==foo_path
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,53 @@
|
|||
require 'puppet'
|
||||
|
||||
# We don't need this for the basic tests we're doing
|
||||
# require 'spec_helper'
|
||||
|
||||
# Dan mentioned that Nick recommended the function method call
|
||||
# to return the string value for the test description.
|
||||
# this will not even try the test if the function cannot be
|
||||
# loaded.
|
||||
describe Puppet::Parser::Functions.function(:getvar) do
|
||||
|
||||
# Pulled from Dan's create_resources function
|
||||
def get_scope
|
||||
@topscope = Puppet::Parser::Scope.new
|
||||
# This is necessary so we don't try to use the compiler to discover our parent.
|
||||
@topscope.parent = nil
|
||||
@scope = Puppet::Parser::Scope.new
|
||||
@scope.compiler = Puppet::Parser::Compiler.new(Puppet::Node.new("floppy", :environment => 'production'))
|
||||
@scope.parent = @topscope
|
||||
@compiler = @scope.compiler
|
||||
end
|
||||
|
||||
describe 'when calling getvar from puppet' do
|
||||
|
||||
it "should not compile when no arguments are passed" do
|
||||
Puppet[:code] = 'getvar()'
|
||||
get_scope
|
||||
expect { @scope.compiler.compile }.should raise_error(Puppet::ParseError, /wrong number of arguments/)
|
||||
end
|
||||
it "should not compile when too many arguments are passed" do
|
||||
Puppet[:code] = 'getvar("foo::bar", "baz")'
|
||||
get_scope
|
||||
expect { @scope.compiler.compile }.should raise_error(Puppet::ParseError, /wrong number of arguments/)
|
||||
end
|
||||
|
||||
it "should lookup variables in other namespaces" do
|
||||
pending "Puppet doesn't appear to think getvar is an rvalue function... BUG?"
|
||||
Puppet[:code] = <<-'ENDofPUPPETcode'
|
||||
class site::data { $foo = 'baz' }
|
||||
include site::data
|
||||
$foo = getvar("site::data::foo")
|
||||
if $foo != 'baz' {
|
||||
fail('getvar did not return what we expect')
|
||||
}
|
||||
ENDofPUPPETcode
|
||||
get_scope
|
||||
@scope.compiler.compile
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
#!/usr/bin/env rspec
|
||||
require 'spec_helper'
|
||||
|
||||
describe "the grep function" do
|
||||
before :all do
|
||||
Puppet::Parser::Functions.autoloader.loadall
|
||||
end
|
||||
|
||||
before :each do
|
||||
@scope = Puppet::Parser::Scope.new
|
||||
end
|
||||
|
||||
it "should exist" do
|
||||
Puppet::Parser::Functions.function("grep").should == "function_grep"
|
||||
end
|
||||
|
||||
it "should raise a ParseError if there is less than 1 arguments" do
|
||||
lambda { @scope.function_grep([]) }.should( raise_error(Puppet::ParseError))
|
||||
end
|
||||
|
||||
it "should grep contents from an array" do
|
||||
result = @scope.function_grep([["aaabbb","bbbccc","dddeee"], "bbb"])
|
||||
result.should(eq(["aaabbb","bbbccc"]))
|
||||
end
|
||||
|
||||
end
|
|
@ -0,0 +1,46 @@
|
|||
require 'puppet'
|
||||
require 'mocha'
|
||||
describe Puppet::Parser::Functions.function(:has_key) do
|
||||
|
||||
# Pulled from Dan's create_resources function
|
||||
# TODO - this should be moved to spec_helper since the
|
||||
# logic is likely to be applied to multiple rspec files.
|
||||
let(:compiler) {
|
||||
topscope = Puppet::Parser::Scope.new
|
||||
# This is necessary so we don't try to use the compiler to discover our parent.
|
||||
topscope.parent = nil
|
||||
my_scope = Puppet::Parser::Scope.new
|
||||
my_scope.compiler = Puppet::Parser::Compiler.new(Puppet::Node.new("floppy", :environment => 'production'))
|
||||
my_scope.parent = topscope
|
||||
compiler = my_scope.compiler
|
||||
}
|
||||
let(:scope) {
|
||||
scope = Puppet::Parser::Scope.new
|
||||
scope.stubs(:environment).returns(Puppet::Node::Environment.new('production'))
|
||||
scope
|
||||
}
|
||||
|
||||
describe 'when calling has_key from puppet' do
|
||||
it "should not compile when no arguments are passed" do
|
||||
Puppet[:code] = 'has_key()'
|
||||
expect { compiler.compile }.should raise_error(Puppet::ParseError, /wrong number of arguments/)
|
||||
end
|
||||
it "should not compile when 1 argument is passed" do
|
||||
Puppet[:code] = "has_key('foo')"
|
||||
expect { compiler.compile }.should raise_error(Puppet::ParseError, /wrong number of arguments/)
|
||||
end
|
||||
it "should require the first value to be a Hash" do
|
||||
Puppet[:code] = "has_key('foo', 'bar')"
|
||||
expect { compiler.compile }.should raise_error(Puppet::ParseError, /expects the first argument to be a hash/)
|
||||
end
|
||||
end
|
||||
describe 'when calling the function has_key from a scope instance' do
|
||||
it 'should detect existing keys' do
|
||||
scope.function_has_key([{'one' => 1}, 'one']).should be_true
|
||||
end
|
||||
it 'should detect existing keys' do
|
||||
scope.function_has_key([{'one' => 1}, 'two']).should be_false
|
||||
end
|
||||
end
|
||||
|
||||
end
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue