Permalink
Browse files

Add new function singleton_resources

The singleton_resources function takes a list of resource specifications
and, provided defaults have been provided for the resource type, creates
them.

For example:

  singleton_resources(
    Package["vim"],
    Package["emacs"],
  )
  • Loading branch information...
1 parent 61217cc commit f7fd8971178b24a8b88b4b4133473299f517e904 @reidmv reidmv committed Apr 3, 2012
Showing with 129 additions and 27 deletions.
  1. +78 −5 README.md
  2. +32 −21 lib/puppet/parser/functions/singleton_resources.rb
  3. +19 −1 manifests/data.pp
View
83 README.md
@@ -3,9 +3,12 @@
The Singleton module provides functions that dynamically create resources
defined either by built-in defaults or by hiera-supplied parameters.
-For now, this module provides one function only: `singleton_packages`, which is
-intended to be used as a tool to address the problem of simple package
-inclusion in puppet manifests.
+## Functions
+
+### singleton_packages
+
+singleton_packages is intended to be used as a tool to address the problem of
+simple package inclusion in puppet manifests.
Because resources can only be declared once in a puppet manifest, including
"simple" packages in multiple places can become a complicated and verbose
@@ -23,8 +26,16 @@ to install. It does not matter how many times the function is called for a
given package name, the resource will only be defined once, and will be defined
within the scope of Class[singleton].
+### singleton_resources
+
+singleton_resources is a generalization from singleton_packages to arbitrary
+resource types. While singleton_packages expects string arguments,
+singleton_resources expects resource specifiers such as Package['vim'].
+
# Examples
+## singleton_packages
+
The following puppet code can be used to install three packages, "vim",
"emacs", and "nano".
@@ -41,7 +52,7 @@ Additional customization can be supplied by adding hiera data. You may supply
parameters, additional singleton_packages to chain-include, and additional
classes to include.
-## YAML Example for "vim" Package
+### YAML Example for "vim" Package
File: $confdir/data/common.yaml
(or other appropriate file, per hiera configuration)
@@ -57,7 +68,7 @@ File: $confdir/data/common.yaml
- stdlib
- obviouslyfakeclass
-## Puppet Example for "vim" Package
+### Puppet Example for "vim" Package
File: $modulepath/data/manifests/common.pp
(or other appropriate file/class, per hiera configuration)
@@ -77,3 +88,65 @@ File: $modulepath/data/manifests/common.pp
],
}
}
+
+## singleton_resources
+
+The following puppet code can be used to install three packages, "vim",
+"emacs", and "nano".
+
+ singleton_resources(
+ Package['vim'],
+ Package['emacs'],
+ Package['nano'],
+ )
+
+Default parameters must be supplied for every type used with
+singleton_resources. The singleton module comes with a set of defaults only for
+the Package resource type. Other defaults must be supplied by the user.
+
+For the Package['vim'] example and the module-supplied package resource
+defaults, Package['vim'] will be created as if it had been given the
+parameters:
+
+ package { "$title":
+ ensure => present,
+ name => $title,
+ }
+
+### Defaults for Package resource type (YAML)
+
+ ---
+ :singleton_resource_package:
+ :parameters:
+ :ensure: present
+
+### Package['vim'] Customization (YAML)
+
+ ---
+ :singleton_resource_package_vim:
+ :parameters:
+ :name: vim
+ :ensure: present
+ :include_singleton_resources:
+ - Package[vim-puppet]
+ :include_classes:
+ - stdlib
+ - obviouslyfakeclass
+
+### Package['vim'] Customization (Puppet)
+
+ class data::common {
+ $singleton_resource_package_vim = {
+ parameters => {
+ ensure => present,
+ name => 'vim',
+ },
+ include_singleton_resources => [
+ "Package[vim-puppet]",
+ ],
+ include_classes => [
+ "stdlib",
+ "obviouslyfakeclass",
+ ],
+ }
+ }
View
53 lib/puppet/parser/functions/singleton_resources.rb
@@ -47,46 +47,57 @@
Puppet::Parser::Functions.autoloader.loadall
- args.each do |resource|
- next if function_defined(resource)
+ blank_config = {
+ :parameters => {},
+ :include_singleton_resources => [],
+ :include_classes => []
+ }
+
+ singleton_loaded = self.catalog.classes.include?('singleton')
+ function_include('singleton') unless singleton_loaded
+ scope = self.class_scope('singleton')
+ args.flatten.each do |resource|
case resource
when String
# convert into resource
+ resource = Puppet::Resource.new(nil, resource)
when Puppet::Resource
- # yay
+ # yay!
else
raise ArgumentError, "Invalid argument of type '#{val.class}' to 'singleton_resources'"
end
- singleton_loaded = self.catalog.classes.include?('singleton')
- function_include('singleton') unless singleton_loaded
- scope = self.class_scope('singleton')
+ next if function_defined(resource)
- type = resource.type.to_s
- title = resource.title.to_s
+ type = resource.type.downcase
+ title = resource.title.downcase
defaults_key = "singleton_resource_#{type}"
resource_key = "singleton_resource_#{type}_#{title}"
defaults = scope.function_hiera(defaults_key)
- config = scope.function_hiera(resource_key, defaults_key)
- config[:parameters] ||= {}
- config[:include_singleton_packages] ||= []
- config[:include_classes] ||= []
- defaults[:parameters] ||= {}
- defaults[:include_singleton_packages] ||= []
- defaults[:include_classes] ||= []
+ config = scope.function_hiera(resource_key, defaults)
Puppet::Util.symbolizehash!(config)
Puppet::Util.symbolizehash!(defaults)
+ defaults = blank_config.merge(defaults)
+ config = blank_config.merge(config)
+
+ class_includes = defaults[:include_classes].concat(
+ config[:include_classes]
+ ).uniq
+
+ singleton_includes = defaults[:include_singleton_resources].concat(
+ config[:include_singleton_resources]
+ ).uniq
- params = defaults[:parameters].merge(config[:parameters])
- class_includes = defaults[:include_classes].merge(config[:include_classes])
- singleton_includes = defaults[:include_singleton_resources].merge(config[:include_singleton_resources])
- resource = { resource_key => params }
- scope.function_create_resources([type, resource])
+ params = { :name => title }.merge(
+ defaults[:parameters].merge(
+ config[:parameters]
+ ))
- scope.function_singleton_packages(singleton_includes)
+ scope.function_create_resources([type, {title => params}])
+ scope.function_singleton_resources(singleton_includes)
scope.function_include(class_includes)
end
View
20 manifests/data.pp
@@ -1,6 +1,24 @@
class singleton::data {
- # Example hiera data (puppet backend) for package "vim":
+ # Default parameters for Package resources (singleton)
+ $singleton_resource_package = {
+ parameters => {
+ ensure => present,
+ },
+ }
+
+ # # Example hiera data for singleton_resource Package["vim"]
+ #
+ # $singleton_resource_package_vim = {
+ # parameters => {
+ # ensure => present,
+ # },
+ # include_singleton_resources => [
+ # 'Package[vim-puppet]',
+ # ],
+ # }
+
+ # # Example hiera data for singleton_package "vim"
#
# $singleton_package_vim = {
# parameters => {

0 comments on commit f7fd897

Please sign in to comment.